Текст
                    ТЕОРИЯ И ПРАКТИКА
ПОСТРОЕНИЯ
БАЗ ДАННЫХ
9-Е ИЗДАНИЕ
Д. КРЁНКЕ
рн
PTR
гхпитгр

DATABASE PROCESSING NINTH EDITION David M. Kroenke Prentice Hall PTR Upper Saddle River, New Jersey 07458 www.phptr.com
HARCCHHR COmPUTER SCIENCE * Д.КРЁНКЕ ТЕОРИЯ И ПРАКТИКА ПОСТРОЕНИЯ БАЗ ДАННЫХ 9-Е ИЗДАНИЕ Е^ППТЕР* Москва • Санкт-Петербург • Нижний Новгород. Воронеж Новосибирск • Ростов-на-Дону • Екатеринбург • Самара Киев Харьков Минск 2005 _______ Ульяновские государегаоиные технические умиаерснто
ББК 32 973.233 УДК 6813.06 К79 Крёнке Д. К79 Теория и практика построения баз данных 9-е изд. — СПб. Питер 2005 — 859 с.: ил. — (Серия «Классика computer science»). ISBN 5-94723-583-8 В книге Д. Крёнке, выдержавшей уже 9 переизданий, вы найдете традиционно подробный, методически выверенный теоретический и практический материал, посвященный вопросам разработки и использования баз данных. В новом издании более глубоко обсуждаются моделирование данных и проектирование баз данных; расширены разделы no SQL и XML; добавлен раздел, знакомящий е ADO NET. Книгу отличает большое количество примеров, моделирующих типичные ситуации из практики делового мира. ББК 32.973.233 УДК 681 3 06 Права на издание получены по соглашению с Prentice Hall. Inc. Upper Sadie River New Jersey 07458. Все права защищены Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения алаг/ггьмее авторских прав. г-'Ы|^- .-.жж_.яяся в данной книге, получена из источников, рассматриваемых издательством как надежные Тем не тчнее. имев в виду возможные -ычгомж или технические ошибки, издательство не может гарантировать абсолютную ток есть и полноту приводимых сведений и не несет ответственности за возможные ошибки, связанные с использованием книги. IS8H 0131015141 (англ ) ООН 6-94723-583-8 ©2003 by Pearson Education, Inc. ©Перевод на русский язык. ЗАО Издательский дом «Питер», 2005 © Издание на русском языке, оформление, ЗАО Издательский дом «Питер». 2005
Краткое содержание Предисловие.................................................... Благодарности.................................................. Глава 1 Введение в базы данных.......................... 24 Часть I. Модель данных «сущность—связь» Глава 2. Модель «сущность—связь»: методы и средства моделирования ............................................ 60 Глава 3. Создание моделей данных «сущность—связь»: описание процесса и примеры........................116 Часть II. Проектирование баз данных Глава 4. Реляционная модель и нормализация.................172 Глава 5. Проектирование баз данных.........................215 Часть III. Структурированный язык запросов (SQL) Глава 6. Введение в язык SQL...............................266 Глава 7. Использование SQL в приложениях...................307 Глава 8. Перепроектирование баз данных.....................354 Часть IV. Обработка многопользовательских баз данных Глава 9. Многопользовательские базы данных.................394 Глава 10. Работа с базами данных в Oracle 9i...............435 Глава 11. Работа с базами данных в SQL Server 2000 ....... 494 Часть V. Стандарты доступа к базам данных Глава 12. ODBC, OLE DB, ADO и ASP..........................544 Глава 13. XML и ADO.NET....................................591 Глава 14. JDBC, Java Server Pages и MySQL..................651 Глава 15. Совместное использование данных предприятия......690 Часть VI. Работа с объектно-ориентированными базами данных Глава 16. Объектно-ориентированные базы данных.............738 Приложение А. Структуры данных.............................775 Приложение Б. Семантическая объектная модель...............802 Алфавитный указатель.......................................845
Содержание Предисловие....................................................... 17 Особенности настоящего издания......................................17 Более глубокое обсуждение моделирования дан! ix и проектирования баз данных.....................................17 Расширение изучения SQL..........................................18 XMLhADO.NET......................................................19 Соблюдение баланса в охвате Oracle 9i и SQL Server 2000 ........ 19 Структура книги.....................................................29 Благодарности..................................................... 22 От издательства.....................................................29 Глава 1. Введение в базы данных.....................................24 Почему используются базы данных?....................................24 Проблемы списков....................................................25 Проблемы совместно используемых данных..............................27 Базы данных как группы связанных таблиц.............................28 Связи............................................................29 Объединение таблиц...............................................31 Что такое система обработки базы данных?............................31 Функции прикладных программ......................................32 Функции СУБД.....................................................33 Определение и компоненты базы данных.............................34 Три примера систем баз данных....................................37 Как построить систему баз данных....................................44 Фаза формулирования требований..................................45 Фаза проектирования.............................................46 Фаза реализации.................................................48 Разработка приложения ..........................................48 Краткая история баз данных..........................................48 Ранние модели баз данных........................................49 Реляционная модель..............................................50 СУБД для персональных компьютеров...............................51 Объектно-ориентированные СУБД (ООСУБД)..........................51 Недавняя история................................................52 Резюме............................................................... Вопросы группы I..................................................53
Вопросы группы II...................,................. . . . . Вопросы к проекту FiredUp.................................... Вопросы к проекту Twigs Tree................................. se 56 57 Часть I. Модель данных «сущность—связь» Глава 2. Модель «сущность—связь»: методы и средства моделирования ...................................................... 60 Тройственная схематическая модель ANSI/SPARC.........................60 Внешняя, концептуальная и внутренняя схемы.........................61 Построение концептуальной схемы................................... 62 Сага о Брюсе и Зельде..............................................62 Модель «сущность—связь» и ее варианты.........................., , , . 65 Версии модели «сущность—связь»................................ . , 65 Выбор версии модели................................................66 Расширенная модель «сущность—связь»..................................67 Сущности....................................................., . . 67 Атрибуты.................................................... - 68 Идентификаторы.....................................................69 Связи............................................................ 69 Подтипы сущностей................................................ .76 Пример ER-диаграммы................................................78 Стандарт IDEF1X......................................................80 Сущности в IDEF1X..................................................80 Связи в IDEF1X................................................. . . 83 Домены..............................................................91 Стандарт IDEF1X и средства моделирования данных...........,.........94 Диаграммы «сущность—связь» в стиле UML................................94 Сущности и связи в UML..............................................94 Конструкции ООП, введенные языком UML...............................98 Роль UML в базах данных на сегодняшний день.........................99 Резюме................................................................100 Вопросы группы I.....................................................103 Вопросы группы II....................................................106 Вопросы к проекту FiredUp............................................113 Вопросы к проекту Twigs Tree.........................................114 Глава 3. Создание моделей данных «сущность—связь»: описание процесса и примеры.......................................116 Процесс моделирования данных.......................................116 Определение системных требований...............................117 Определение сущностей........................................ 120 Определение связей.............................................122 Определение идентификаторов....................................124 Определение атрибутов и доменов............................ . . 125 Проверка модели.......................>........................127 Методы проверки модели данных..................................129
В Содержание Построение моделей данных на базе анализа форм и отчетов...... 131 Одиночные сущности..........................................131 Идентифицирующие связи принадлежности.......................132 Неидентифицирующие связи принадлежности.....................134 Неспецифические (N:M) связи.................... ............137 Подтипы и категории.........................................141 Модель ЗАКАЗ................................................141 Рлрзбитка модели данных: пример................................144 Отчет о колледже............................................144 Отчет о кафедре и преподавателях............................145 Отчет о студентах кафедры...................................148 Домены......................................................152 Резюме.........................................................154 Вопросы группы I...............................................156 Вопросы группы II..............................................158 Задачи по моделированию........................................166 Вопросы к проекту FiredUp...................................... 169 Вопросы к проекту Twigs Tree...................................170 Часть II. Проектирование баз данных Глава 4. Реляционная модель и нормализация.........................172 Отношения..........................................................172 Пример отношения и две таблицы, не являющиеся отношениями.......173 Замечание по терминологии.......................................176 Типы ключей........................................................176 Композитные ключи...............................................177 Первичные ключи и ключи-кандидаты...............................177 Функциональные зависимости......................................178 Нормализация.......................................................180 Аномалии модификации...........................................180 Суть нормализации..............................................182 Классы отношений...............................................183 Нормальные формы от первой до пятой................................184 Вторая нормальная форма (2НФ)..................................184 Третья нормальная форма (ЗНФ)..................................185 Нормальная форма Бойса-Кодца (НФБК)............................186 Четвертая нормальная форма (4НФ)...............................188 Пятая нормальная форма (5НФ)...................................191 Доменно-ключевая нормальная форма (ДКНФ)................... , . 191 Определение....................................................192 Первый пример доменно-ключевой нормальной формы................193 Второй пример доменно-ключевой нормальной формы . . 194 Третий пример доменно ключевой нормальной формы............... . 196 Синтез отношений .............................................. 198 Атрибутивная связь «один к одному».............................198 Атрибутивная связь «многие к одному»...........................201
Атрибутивная связь «многие ко mhoi им» . , . ................. 201 Многозначные зависимости: часть вторая...................... • 203 Ненормализованные струю уры.................................... 204 Нормализованная схема неестественна.............. .... 204 Нормализация неудобна....................................... . 204 Нормализация может привести к низкой производительности........205 Резюме.............................................. ........... 206 Вопросы группы I............................................... 208 Вопросы группы II.............................................. 210 Вопросы к проекту FiredIIр.......................................212 Вопросы к проекту Twigs Tree.....................................214 Глава 5. Проектирование баз данных...............................215 Процесс проектирования базы данных...............................215 Преобразование сущностей и атрибутов в таблицы и столбцы.......216 Выбор первичного ключа.........................................217 Суррогатные ключи..............................................219 Представление связей.............................................221 Принципы представления связей..................................221 Представление идентификационно-зависимых связей................225 Представление связей принадлежности вида 1:1 и 1:N.............229 Представление связей вида N:M..................................236 Представление подтипов и категориальных связей.................241 Представление слабых, но не идентификационно-зависимых сущностей . . . 244 Примеры связей.................................................245 Особые ситуации..................................................249 Представление рекурсивных связей...............................249 Представление тернарных связей и связей высших порядков........251 Пустые значения................................................256 Резюме...........................................................257 Вопросы группы I.................................................260 Вопросы группы II................................................263 Вопросы к проекту FiredUp........................................264 Вопросы к проекту Twigs Тгее.....................................264 Насть III. Структурированный язык запросов (SQL) Глава 6. Введение в язык SQL.......................................266 База данных управления проектами на предприятии....................267 Средства определения данных языка SQL..............................269 Оператор CREATE TABLE.....................;.....................269 Определение первичных и альтернативных ключей с помощью оператора ALTER.................................................271 Предпочтение — использованию оператора CREATE...................274 Передача SQL-кода на исполнение СУБД............................275 Операторы DROP..................................................276 Средства запроса данных языка SQL..................................276 Чтение заданных столбцов из одиночной таблицы...................276 Чтение заданных строк из одиночной таблицы. ....................278
10 Содержание Чтение заданных строк и столбцов из одиночной таблицы............279 Диапазоны, специальные символы и пустые значения в предложениях WHERE............................................280 Сортировка результатов...........................................282 Встроенные функции SQL...........................................283 Встроенные функции и группировка.................................285 Чтение данных из нескольких таблиц с применением вложенных запросов 286 Чтение данных из нескольких таблиц с помощью операции соединения . . . 288 Сравнение вложенного запроса и соединения........................292 Внешние соединения...............................................293 Средства модификации данных языка SQL...............................295 Вставка данных................................... ..............295 Изменение данных.................................................296 Удаление данных.................................................. 297 Резюме..............................................................298 Обзорные вопросы................................................. . 300 Упражнения..........................................................303 Вопросы к проекту FiredUp...........................................304 Вопросы к проекту Twigs Tree........................................305 Глава 7. Использование SQL в приложениях ......... 307 Галерея View Ridge..................................................307 Требования к приложению..........................................308 Модель данных ...................................................308 Создание таблиц..................................................313 Данные для примера...............................................316 SQL-представления...................................................316 Использование представлений для скрытия столбцов и строк.........320 Использование представлений для отображения вычисляемых столбцов ... 321 Использование представлений для скрытия сложного синтаксиса......322 Другие варианты использования представлений......................325 Обновление представлений.........................................326 SQL-представления не являются внешними представлениями...........327 Встраивание SQL-операторов в прикладные программы...................328 Триггеры............................................................329 Использование триггеров для проверки допустимости вводимых данных . . . 330 Использование триггеров для присвоения значений по умолчанию.....331 Обновление представлений.........................................333 Процедуры обеспечения ссылочной целостности......................334 Хранимые процедуры..................................................338 Преимущества хранимых процедур...................................338 Хранимая процедура Add_WORK......................................339 Использование SQL в коде приложения.................................341 Резюме............................... .......................... Вопросы группы I................................................... д47 Вопросы группы II............................................... 249 Вопросы к проекту FiredUp............ Вопросы к проекту Twigs Tree.... . . i..............................qso
Глава 8. Перепроектирование баз данных..................... , , . 354 Зачем перепроектировать базы данных?............................. 354 другие SQL-операторы........................................... - 355 Коррелированные подзапросы..................................... 356 Условия EXISTS и NOT EXISTS.....................................359 Анализ существующей базы данных................................... 361 Реконструкция ................................................. 362 Графы зависимостей.............................................. 363 Резервное копирование и тестовые базы данных................... 366 Изменение имен таблиц и свойств столбцов..........................368 Изменение имен таблиц...........................................368 Добавление и удаление столбцов..................................369 Изменение типа данных столбца или ограничений...................371 Добавление и удаление ограничений...............................371 Изменение кардинальности и свойств связей.........................372 Изменение минимальной кардинальности............................372 Изменение максимальной кардинальности...........................373 Добавление и удаление связей......................................377 Добавление таблиц и связей с целью нормализации.................378 Автоматическое конструирование....................................384 Резюме............................................................384 Вопросы группы I................................................. 387 Вопросы группы II.................................................390 Вопросы к проекту FiredUp.........................................391 Вопросы к проекту Twigs Тгее......................................392 Часть IV. Обработка многопользовательских баз данных Глава 9. Многопользовательские базы данных...........................394 Администрирование баз данных.........................................395 Управление структурой базы данных..................................396 Управление параллельной обработкой...................................398 Необходимость в атомарных транзакциях..............................398 Блокировка ресурсов................................................403 Оптимистическая и пессимистическая блокировки......................406 Объявление характеристик блокировки................................408 Согласованность транзакций........................................409 Уровень изоляции транзакции.......................................410 Тип курсора.......................................................411 Безопасность базы данных............................................413 Права и обязанности по обработке..................................414 Обеспечение безопасности средствами СУБД..........................415 Принципы обеспечения безопасности СУБД............................416 Обеспечение безопасности средствами приложения....................418 Атака со вставкой SQL-кода........................................420 Восстановление баз данных...........................................420 Восстановление путем повторной обработки..........................421 Восстановление через откат-накат.................................... Управление СУБД.......................................................
12 Содержание Поддержание репозитория данных . ..................,............426 Резюме............................................... , . . . . 427 Вопросы группы I.................................................429 Вопросы группы II............................................... 432 Проект...................................................... . 432 Вопросы к проекту FiredUp............................... . . 433 Вопросы к проекту Twigs Tree................................ . 434 Глава 10. Работа с базами данных в Oracle 9i.....................435 Установка Oracle................................................ 436 Создание базы данных Oracle.................................. 436 Работа с SQL* Plus.............................................437 Создание таблиц.............................................. 442 Создание индексов........................................ 449 Изменение структуры таблицы....................................450 Создание представлений.........................................451 Работа с Oracle Enterprise Manager Console.......................452 Логика приложения............................................ 455 Хранимые процедуры . , .......................... 457 Словарь данных.................................................. 472 Управление параллельной обработкой........................ ... . 474 Уровень изоляции «завершенное чтение»..........................475 Уровень изоляции «сериализуемость».............................476 Уровень изоляции «только чтение»............................... 477 Дополнительные замечания о блокировках.........................477 Безопасность.....................................................477 Системные привилегии учетной записи.................. . . . . 478 Идентификация пользователей с помощью учетных записей..........481 Резервное копирование и восстановление в Oracle..................483 Средства восстановления Oracle.................................483 Типы сбоев.....................................................484 Вопросы, не затронутые в данной главе............................486 Резюме.......................................................... 486 Вопросы группы I.................................................488 Проект...........................................................490 Вопросы к проекту FiredUp........................................491 Вопросы к проекту Twigs Тгее.....................................493 Глава 11. Работа с базами данных в SQL Server 2000.............. 494 Установка SQL Server 2000 ........................................ 494 Создание базы данных SQL Server 2000 ............................. 495 Создание таблиц................................................497 Создание базы данных галереи View Ridge........................499 Индексы........................................................507 Логика приложения................................................508 Хранимые процедуры......................................... ... 509 Триггеры.......................................,...............515 Управление параллельной обработкой...............................524 Пс ведение курсора................................. . ...... 525 Блокировочные подсказки........................................526
Содержание 13 Безопасность .................................... ....... Настройки безопасности SQL Server.......................... • 527 Настройки безопасности учетной записи............................ 528 Настройки безопасности ролей..................................... 530 Резервное копирование и восстановление............................. 531 Типы резервных копий.............................................532 Модели восстановления SQL Server................................. 533 Восстановление базы данных.......................................534 План обслуживания базы данных....................................534 Вопросы, не затронутые в этой главе.................................535 Резюме..............................................................536 Вопросы группы I....................................................537 Проекты.............................................................539 Вопросы к проекту FiredUp...........................................540 Вопросы к проекту Twigs Tree........................................541 Часть V. Стандарты доступа к базам данных Глава 12. ODBC, OLE DB, ADO и ASP.................................. 544 Информационное окружение веб-сервера................................544 Стандарт ODBC.......................................................548 Архитектура ODBC.................................................548 Уровни соответствия..............................................550 Задание имени источника данных ODBC..............................552 OLEDB...............................................................554 Цели создания OLE DB.............................................556 Основные конструкции OLE DB......................................557 ADO.................................................................559 Вызов ADO из ASP-страниц.........................................559 Объектная модель ADO.............................................560 Примеры использования ADO...........................................565 Пример 1 — чтение конкретной таблицы.............................565 Пример 2 — чтение таблицы обобщенным способом....................568 Пример 3 — чтение любой таблицы..................................571 Пример 4 — обновление таблицы....................................576 Пример 5 — вызов хранимой процедуры..............................581 Резюме......................................,......................586 Вопросы группы I............................................... 587 Вопросы группы II..................................................589 Вопросы к проекту FiredUp..........................................590 Вопросы к проекту Twigs Tree.......................................590 Глава 13. XML и ADO.NET............................................591 Важность XML.......................................................591 XML как язык разметки..............................................593 XML-документ и DTD................................................ Материализация ХМ L-доку ментов с помощью XSLT..................595
14 Содержание XML Schema.........................................................600 Проверка допустимости по схеме................................ 601 Элементы и атрибуты........................................... 602 Плоские и структурированные схемы..................................603 Глобальные элементы.............................................606 Создание XML-документов на основе информации из базы данных........608 SELECT...FOR ХМL................................................609 SELECT...FOR XML для нескольких таблиц . .......................611 XML-схема, описывающая все покупки клиентов........................614 Схема с двумя многозначными маршрутами..........................616 Значение XML....................................................619 ADO.NET............................................................622 Набор данных ADO.NET............................................623 Обработка сведений о клиентах в базе данных View Ridge с помощью ADO.NET . 625 Назначение приложения...........................................626 Установка соединения и заполнение набора данных.................626 Добавление новых структур в набор данных........................629 Обработка набора данных.........................................632 Обновление информации в наборе данных и исходной базе данных .... 636 Обзор стандартов XML............................................642 Резюме.............................................................644 Вопросы группы I...................................................647 Вопросы группы II..................................................649 Вопросы к проекту FiredUp..........................................650 Вопросы к проекту Twigs Тгее.......................................650 Глава 14. JDBC, Java Server Pages и MySQL..........................651 JDBC...............................................................651 Типы драйверов..................................................652 Использование JDBC..............................................653 Примеры использования JDBC......................................656 Java Server Pages................................................ 663 JSP-страницы и сервлеты ........................................663 Apache Tomcat...................................................664 Настройка Tomcat для обработки JSP..............................664 Примеры JSP-страниц.............................................666 MySQL..............................................................678 Ограничения MySQL...............................................678 Работа c MySQL..................................................679 Настройка разрешений на доступ для JDBC.........................681 Управление параллельной обработкой данных.......................682 Резервное копирование и восстановление..........................683 Заключительное слово о MySQL....................................684 Резюме.............................................................684 Вопрос группы!.....................................................686 Вопросы группы II .................................................688 Проект ............................................................688 Вопрос к проекту FiredUp...........................................689 Вопросы к проекту Twigs Tree.......................................689
Глава 15. Совместное использование данных предприятие . • 999 Архитектуры корпоративных систем обработки данных .... Системы удаленной обработки. ....................... • > ’ ' Клиент-серверные системы........................ • • ‘ Системы совместного использования файлов ........ Системы обработки распределенных баз данных.......... • • < - • Загрузка данных......................................... Компания Universal Equipment..........................- - • • • 700 Процесс загрузки............................................. ... 702 Потенциальные проблемы при обработке загруженных баз данных . . . . 703 Оперативная аналитическая обработка данных (OLAP).... .... » 705 Информационные хранилища......................................... 714 Компоненты информационного хранилища........................... 714 Требования к информационному хранилищу............................ 716 Проблемы разработки и эксплуатации информационных хранилищ........717 Информационные лавки......................................... 722 Администрирование данных............................................723 Потребность в администрировании данных............................724 Проблемы администрирования данных............................... - 725 Задачи отдела администрирования данных............................726 Резюме............................................................ - 730 Вопросы группы I....................................................733 Вопросы группы II...................................................736 Часть VI, Работа с объектно-ориентированными базами данных Глава 16. Объектно-ориентированные базы данных.................738 Введение в объектно-ориентированное программирование.......^ . . . 739 Терминология ООП..............................................739 Пример ООП......................................................741 Постоянное хранение объектов....................................745 Постоянное хранение объектов в традиционной файловой системе. .... 746 Постоянное хранение объектов с использованием реляционной СУБД . . . 747 Постоянное хранение объектов с использованием ООСУБД.........749 Постоянное хранение объектов в Oracle .................................750 Типы объектов и коллекции....................................751 Объекты Oracle......................................... ..... 755 Стандарты ООСУБД............................................ ... 759 SQL3.........................................................760 ODMG-93................................................. 786 Резюме.................................................. .......770 Вопросы группы I................................................ 772 Вопросы группы II.................................... 774 Приложение А. Структуры данных................................... Плоские файлы............................................... , 775 Обработка плоских файлов в различном порядке ............ . Замечание по поводу адресации записей.............. . . . 777
1в Содержание Упорядочение с помощью связных списков.............................777 Упорядочение с помощью индексов.................................. 780 Бинарные деревья...................................................781 Резюме по структурам данных........................................783 Представление бинарных связей.........................................784 Обзор видов связей между записями..................................784 Представление деревьев.............................................786 Представление простых сетей...................................... 789 Представление сложных сетей........................................791 Представление вторичных ключей................................. ... 794 Представление вторичных ключей с помощью связных списков 795 Представление вторичных ключей с помощью индексов...............796 Резюме................................................................799 Вопросы группы I......................................................800 Вопросы группы II.....................................................801 Приложение Б. Семантическая объектная модель.......................802 Семантические объекты.................................................803 Определение семантических объектов.................................803 Атрибуты.......................................................... 804 Объектные идентификаторы......................................... 808 Домены атрибутов...................................................809 Представления семантических объектов............................. 809 Типы объектов.........................................................811 Простые объекты....................................................811 Композитные объекты................................................812 Составные объекты..................................................815 Представление составных объектов со связью 1:1.....................819 Представление связей «один ко многим» и «многие к одному»..........820 редставление связей «многие ко многим»............................822 Гибридные объекты..................................................823 Представление гибридных связей ....................................827 Ассоциативные объекты..............................................829 Объекты вида родитель-подтип................................... 832 Объекты вида архетип-версия............................... . . . 836 Сравнение семантической объектной модели и модели «сущность—связь». . 837 Вопросы группы I.................................................... 840 Вопросы к проекту FiredUp.............................................843 Алфавитный указатель...............................................845
Предисловие Базы данных — повсюду. Они обеспечивают основную функциональность прило- жений типа клиент—сервер, организационных приложений, а также приложений электронной коммерции типа бизнес—клиент и бизнес—бизнес. Кроме того, они используются на миллионах рабочих мест. Из-за такой популярности обработка баз данных стала самой важной темой при обучении информационным системам. Знание построения базы данных, разработки, администрирования и технологии доступа необходимо для успеха любого специалиста по информационным системам. К сожалению, рост популярности баз данных не означает роста компетентио- ч4 сти в них. Многих студентов (и даже профессионалов) вводит в заблуждение простота создания маленьких баз данных с помощью продуктов типа Microsoft Л\ Access. Им кажется, что они владеют технологией баз данных достаточно для создания баз данных с более замысловатой структурой, требующих сложной об- работки. Результат часто плачевен: такие базы данных сложно использовать, они не удовлетворяют системным требованиям. Кроме того, их трудно переделать. Ситуация похожа на ту, что имеет место при обучении программированию на компьютере. Выучив синтаксис языка, студенты думают, что они могут строить сложные приложения, не овладев предварительно навыками проектирования про- грамм. Важность умения проектировать программы становится очевидна только тогда, когда программы делаются больше и сложнее. Особенности настоящего издания Растущая важность технологии баз данных наряду с тревожной тенденцией уве- личения количества плохо спроектированных баз данных заставили меня серьез- но задуматься над организацией материала книги. В результате он был сильно пересмотрен. Более глубокое обсуждение моделирования данных и проектирования баз данных Для начала я решил, что книга нуждается в более глубоком рассмотрении и моде- лирования данных, и проектирования баз данных. После принятия такого реше- ния я осознал, что параллельный анализ двух методов моделирования данных — Ульяновский государственный технический университет Научней библиотека
18 Предисловие ие лучший способ изучения нового. Студентам нужно глубокое понимание одно- го метода и побольше практики по его применению. Исходя из этого, я убрал ак- цент с семантической объектной модели, переместив ее в приложение, и углубил рассмотрение модели сущность—связь. В этом издании вы найдете две главы, по- священные построению модели сущность—связь. Кроме того, чтобы облегчить студентам изучение моделирования данных, эти главы завершаются вопросами и заданиями (проектами) по моделированию данных. Для приобретения нужной ci оровки будет важно ответить на эти вопросы и выполнить задания. Одной из трудностей проникновения в глубь модели сущность—связь является то, что не существует ее общепринятой версии. Как обсуждается в главе 2, сущест- вуют классическая модель сущность—связь, версия обработки информации, версия национального стандарта IDEF1X, а также версия, включенная в язык UML. Чтобы подробнее представить модель сущность—связь, я должен был решить, какую из этих версий использовать. Процесс этого решения также описывается в главе 2, и суть его в следующем: я считаю, что UML-версия в конечном счете будет наиболее важной, но в настоящее время больше используется IDEFlX-вер- сия, поскольку она применяется в таких популярных средствах моделирования данных, как Visio и ERWin. Таким образом, в главах 2, 3 и 5 по большей части используется версия IDEF1X. UML-версия, однако, тоже представлена — в конце главы 2. Как и главы, посвященные моделированию данных, главы о проектировании баз данных стали глубже. В это издание вошли две главы по проектированию баз данных. Глава 5 описывает преобразование моделей данных в проекты баз дан- ных, а в главе 9 рассказывается о перепроектировании баз данных. Изложение в главе 5 теперь больше не сводится к тому, «куда поместить внешний ключ». В частности, подробно описывается целостность ссылочных данных. Кроме того, рассматриваются и более серьезные темы, такие как проектирование для рекур- сивных связей и проектирование для двоичных ограничений на тернарные связи. Главу 5 завершают более 80 вопросов и заданий, а также задачи для проектов FiredUp и Twigs. По окончании университета немногим студентам придется начинать проекти- рование базы данных с чистого листа. Скорее, большинство будет работать над проектами перепроектирования баз данных. Поэтому я добавил новую главу, по- священную этой важной теме. Эта новая глава появилась после главы об SQL, поскольку этот язык требуется для понимания и выполнения перепроектирова- ния базы данных Перепроектирование также требует корреллированных подза- просов и запросов EXISTS/NOT EXISTS, и глава снабжена реалистичными при- мерами их использования. Расширение изучения SQL Кроме углубления рассмотрения моделирования данных и проектирования баз данных, в настоящем издании я также расширил рамки применения SQL. В главе 4 излагаются основы SQL для определения данных и манипулирования данными
ОСОО- НП 1И HilLTUWUHW»' Вопрос определения данных для очень пажен, поскольку срщитва Цшфичесютф проектирования нельзя использован. программным образом, а повторно их ВКЛЮ- чатьпеинтереспо. Глава б излагает основы DML для стандарта SQL 92 и вклм.чм® два формата соединения, а также обсуждение внутреннего и внешнею соединения. В главе 7 представлен пример базы данных для галереи View Ridge; <ia бала данных широко используется и в последующих главах. После этою глава 7 как бы надстраивает SQL, описанный в главе б, и рассказывает об исполь ювании SQL в приложениях баз данных. Кроме того, в главу 7 включено обсуждение использования SQL в триггерах и хранимых процедурах. В главе 8 показано использование SQL для перепроектирования баз данных Как уже отмечалось, эта глава дает студентам реалистичное понимание необхо- димости в более сложных SQL-операторах. XML и ADO.NET Третье большое изменение этого издания было сделано в главе 13. В ней пол- ностью переписано все, что связано с языком XML, а также добавлено обсужде- ние ADO.NET. Что бы вы ни думали о Microsoft, а множества данных ADO.NET являются существенной новацией и весьма важны для веб-сервисов XML. С по- мощью ADO.NET программист может создать в памяти полную реляционную базу данных, которая будет отделена от любой внешней базы данных, управляемой Oracle, DB2, SQL Server или другой СУБД. Такая база данных может управлять- ся приложениями, написанными на любом из языков .NET, таких как С#, С++ или VB.NET. В главе 13 VB.NET используется для создания приложения ASP.NET, кото- рое создает множество данных и таблицу, XML, а также представление этого множества в виде XML-схемы. Чтобы облегчить присутствие Microsoft, прило- жение показывает использование ADO.NET совместно с Oracle. Соблюдение баланса в охвате Oracle 9i и SQL Server 2000 Oracle и SQL Server обсуждаются у меня в равной степени. В главе 7 показаны псевдотриггеры и псевдохранимыс процедуры, которые присущи и Oracle, и SQL Server. В главе 9 представлены многопользовательские СУБД с обсуждением возможностей Oracle и SQL Server. В главе 10 (посвященной Oracle) и в главе 11 (посвященной SQL Server) выдержана одна глубина изложения. В обеих главах показываются одни и те же хранимые процедуры и триггеры. В главе 12 пред- ставлены ASP-приложения, которые ведут базы данных как Oracle, так и SQL Server. Поскольку SQL Server не обеспечивает такой объектпо-орпептнровагиюй Функциональности, как Oracle, в главе 16 преобладает Oracle. Начинать изучение можно как с Oracle, так п с SQL Server. Книга построен* гак, что вы можете использовать любой из этих продуктов с один гковым успехом
20 Предисловие Структура книги главе 1 обработка баз данных изложена простейшим образом. Необходимость обработки баз данных иллюстрируется описанием проблем управления ненорма- лизованными (неупорядоченными) данными в таблице. После этого рассматри- ваются компоненты системы базы данных и дается краткое описание процесса разработки базы данных. Завершает первую главу краткая история баз данных. В главах 2 и 3 обсуждается моделирование данных с помощью модели сущ- ность- связь (E-R model). В главе 2 описываются разновидности этой модели, в том числе традиционная модель сущность—связь, IDEF1X и UML, а затем показываются приемы использования этих моделей. В главе 3 продолжается разговор о построении модели данных — объясняется процесс этого построения, приводятся примеры наглядных форм и отчетов, а также демонстрируется раз- работка модели данных для маленького университета. Главы 4 и 5 посвящены проектированию баз данных. В главе 4 рассматривают- ся реляционная модель и нормализация. Глава 5, в свою очередь, показывает, как преобразовать модель сущность—связь в реляционную модель. Как уже было от- мечено, эта глава стала глубже, чем простое описание того, куда поместить внеш- ние ключи. Помимо этого, подробно обсуждаются правила ссылочной целостности. Следующие три главы представляют язык SQL. В главе 6 даются основы SQL и иллюстрируется использование этого языка для определения данных и мани- пулирования данными. В главе 7 показано использование SQL в приложениях и обсуждаются представления, встроенный SQL, триггеры и хранимые процеду- ры. В главе 8 рассказывается о перепроектировании баз данных. Эта глава начи- нается с обсуждения коррелированных подзапросов и уелловий EXISTS/NOT EXISTS. После этого описывается процесс перепроектирования баз данных и при- водятся категории перепроектирования. Главы части IV имеют общую структуру. В главе 9 представлено администри- рование данных и администрирование баз данных, а также обсуждаются особен- ности управления большими многопользовательскими базами данных. Глава 10 продолжает главу 9 и представляет возможности и функции Oracle 9i, в том чис- ле использование хранимых процедур и триггеров. В главе 11 обсуждается то же, только для SQL Server 2000. Главы 12 13 и 14 посвящены обработке баз данных приложений. В главе 12 обсуждаются ODBC, OLE DB и ADO и показывается использование VBScript для вызова ADO из ASP-страниц. База данных и хранимые процедуры, разрабаты- ваемые в главах 10 и И, используются для иллюстрации обработки Oracle и SQL Server из ASP. В главе 13 представлены XML и XML Schema, и объясняется их важность для обработки баз данных. Вторая половина главы 13 иллюстрирует операторы SELECT...FOR XML, а также поясняет и демонстрирует использование ADO.NET для создания и обработки баз данных. Также показана способность множеств данных обеспечивать просмотр одних и тех же данных в виде таблиц, XML и XML Schema. В главе 14 показана обработка баз данных с помощью программного обеспе- чения с OI крытым кодом. Описывается роль JDBC и использование Java и Java
Структура книги 21 Server Pages, а также разрабатывается база данных для галереи View Ridge с по- мощью MySQL — тот же пример, который используется для Oracle и SQL Server в главах 10 и 11. Студенты должны уловить смысл этого, даже если они не про- граммируют на Java. Те же, кто знает Java, найдут эту главу легкой для себя. Завершают книгу главы 15 и 16. В главе 15 описывается разработка базы дан- ных предприятия и обсуждается OLAP. В главе 16 представлены понятия объект- но-ориентированных баз данных и приемы для работы с ними. Также обсуждает- ся использование возможностей Oracle для объектно-реляционных баз данных. В книгу входят два приложения. Приложение А описывает основные струк- туры данных. Приложение В представляет семантическую объектную модель и показывает, как такие модели можно преобразовать в реляционные проекты баз данных. В этом приложении весь концептуальный материал по таким моде- лям взят из восьмого издания, но из него удалены все примеры.
Благодарности В первую очередь я хочу поблагодарить рецензентов восьмого издания, которые обеспечили полезное и проницательное руководство процессом пересмотра мате- риала к ги: ♦ Карен Доулинг (Karen Dowling), Государственный университет Аризоны ♦ Ричард Хес (Richard Heath), Государственный университет Сант-Клода ♦ Вики Джонатан (Vicki Jonatan), Колледж Портлаида ♦ Брайан Маки (Brian Mackie), Университет Северного Иллинойса ♦ Мэтт Макгован (Matt McGowan), Университет Бредли ♦ Клер Мак-Инерли (Claire Mclnerley), Университет Рутжерса ♦ Чанг Мяо (Chang Miao), Северо-Западный Университет ♦ Marty Murray (Марти Муррей), Колледж Портлаида ♦ Дэ д Пальцер (Davi alzer), Технический Колледж Кловер-парка ♦ Дэвид Петри (David Petrie), Университет Редландса ♦ Линда Прис (Linda Preece), Университет Южного Иллинойса ♦ Кевин Робертс (Kevin Roberts), Университет Деври 4- Ашариф Шираки (Asharif Shirani), Государственный университет Сан-Хосе ♦ Эйлин Сиккема (Eileen Sikkema), Университет Вашингтона ♦ Боб Спир (Bob Spear), Университет Мэриленда 4 Шерон Туттл (Sharon Tuttle), Государственный Гумбольдт-университет 4- Диана Вальц (Diane Waltz), Университет Техаса в Сан-Антонио 4- Питер Волькотт (Peter Wolcott), Университет Небраски Кроме того, я благодарю Дональда Нильсена (Donald Nilsen) из корпорации Microsoft за всесторонние дискуссии со мной касательно цели и функциональности ADO.NET. Еще хотелось бы поблагодарить Гаррн А. Спаркса (Harry A. Sparks) из компании Sparks Consulting (который по совместительству является профес- сором Вебстеровского университета в Сан-Луисе) за советы по улучшению из- ложения вопросов безопасности в главе 9. Также я благодарен Марсии Вильямс (Marcia Williams) из колледжа Бельвю и всем, кто посещал мои лекции па обра- зовательной конференции в Белыяо, штат Вашингтон, летом 2002 года. Я верю, что нынешнее издание книги «Теория и практика построения баз Данных* лучшее В большой степени это произошло благодаря тому впима-
От издательства 23 нию, которое уделил книге Боб Хоран (Bob Horan), мой редактор в издательстве Prentice Hall. Я сердечно благодарю Боба за его энтузиазм и за мудрое руково- дство. Кроме того, я благодарен Килу Хеннону (Kyle Hannon), который, несмот- ря на крайнюю занятость, всегда успевает внести великое множество редактор- ских поправок. Спасибо также Ванессе Натри (Vanessa Nuttry) из Prentice Hall. Ванесса руководила выпуском трех моих книг, и я сердечно благодарен ей за ее преданность и профессионализм во всех этих проектах. Наконец, я благодарен Линде, моей жене, за ее любовь, терпение и понимание. Дэвид Кренке Сиэттл, штат Вашингтон От издательства Ваши замечания, предложения, вопросы отправляйте по адресу электронной по- чты comp@piter.com (издательство «Питер», компьютерная редакция). Мы будем рады узнать ваше мнение! Все исходные тексты, приведенные в книге, вы можете найти по адресу http://www.piter.com/download. На веб-сайте издательства http://www.piter.com вы найдете подробную инфор- мацию о наших книгах.
Глава 1 Введение в базы данных Базы данных всегда были важнейшей темой при изучении информационных сис- тем. Однако в последние годы всплеск популярности Интернета и бурное разви- тие новых технологий для Интернета сделали знание технологии баз данных для многих одним из актуальнейших путей карьеры. Технологии баз данных унели Интернет-приложения далеко от простых брошюрных публикаций, которые характеризовали ранние приложения. В то же время Интернет-технология обес- печивает пользователям стандартизированные и доступные средства публикации содержимого баз данных. Правда, ни одна из этих новых разработок не отменяет необходимости в классических приложениях баз данных, которые появились еще до развития Интернета для нужд бизнеса. Это только расширяет важность знания баз данных. Многие студенты считают этот предмет приятным и интересным, даже не- смотря на его сложность. Проектирование и разработка базы данных требуют и искусства, и умения. Понимание пользовательских требований и перевод их в эффективный проект базы данных можно назвать творческим процессом. Пре- образование этих проектов в физические базы данных с помощью функционально полных и высокопроизводительных приложений — инженерный процесс. Оба процесса полны сложностей и приятных интеллектуальных головоломок. Поскольку сейчас существует большая необходимость в развитии технологии баз данных, навыки, которые вы разовьете, и знания, которые вы получите в про- цессе изучения этого курса, будут востребованы. Цель книги — предоставить твердое обоснование фундаментальных положений технологии баз данных, что- бы вы могли начать успешную карьеру в этой области, если вам этого захочется. В этой главе мы обсудим, что, как и почему в базах данных. Мы поймем, по- чему используются базы данных, расскажем, какие существуют компоненты сис- темы базы данных и как разрабатывать такие системы. Глава завершится экскур- сом в историю баз данных. Почему используются базы данных? Цель базы данных — помочь людям и организациям вести учет определенных ве- щей. На первый взгляд, эта цель кажется скромной, и вы, возможно, удивитесь, зачем нам нужна такая сложная технология и целый курс, посвященный этому
Проблемы слисиов 25 предмету. Большинство из нас может вспомнить ситуации, в которых нам тр«<, ется отслеживать некоторые веши. Я, например, составляю список дел, которые нужно сделать на этой неделе, список покупок в магазине, список расходов для налоговой декларации и так далее. Почему не делатью же самое для информаци- онных систем? На самых ранних стадиях развития информационных технологий исполь- зовались списки — набитые на перфокарте и написанные на магнитной ленте. Со временем, однако, стало ясно, что только немногие проблемы можно решить с помощью таких списков. В следующем разделе мы обсудим такие проблемы а затем опишем, как построить базы данных для их решения, Проблемы списков Рассмотрим список в табл. 1.1, который используется фирмой Lakeview Equipment Rentals. Эта фирма занимается прокатом оборудования, такого как краны и экс- каваторы, строительным подрядчикам. В табл. 1.1 показан лишь небольшой кусок деятельности этой фирмы, но даже этот маленький пример иллюстрирует целый ряд важных проблем со списками. Таблица имеет 10 столбцов: Job (про- ект), Contractor (подрядчик), Phone (телефон), Equipment type (тип оборудования), Equipment number (номер оборудования), Daily rate (плата за день), Start date (дата начала), End date (дата окончания), Days (количество дней), Charge (стоимость). В первую очередь обратим внимание на следующее. Что случится, если у под- рядчика изменится номер телефона? Предположим, например, что у фирмы КН Services телефон станет 213-444-9988. Чтобы содержать список в порядке, нам нужно сделать изменения в четырех строках. Если мы не изменим все эти строки, мы получим противоречащие друг другу данные и не сможем установить, какой же из этих номеров верен. Далее предположим, что список отражает прокатную деятельность фирмы за весь квартал или год. В таком списке могут быть сотни или тысячи строк. Чтобы записать измененный телефонный номер, нам понадо- бится произвести поиск по списку и сделать исправления в каждой строке, кото- рая содержит фирму КН Services. Этот процесс очень долог и чреват ошибками. Еще одна проблема возникает, когда мы удаляем из такого списка данные. Скажем, фирма RB Partnership решила не брать в прокат экскаватор (backhoe), так что мы должны удалить последнюю строку. В процессе такого уда пения не только теряются данные о прокате, но также теряются номер телефона фирмы RB Partnership и тот факт, что эта фирма работает над проектом под названием Village Square и что она согласилась взять в прокат экскаватор за 750 долларе в день. А ведь мы, скорее всего, просто хотели удалить данные о дате проката. Такого же типа и следующая ситуация. Что делать, когда у нас есть только некоторые (но не все) данные? Допустим, мы знаем, что университет Swaging имеет телефон 206-555-8989 и что он работает над реконструкцией моста на Ц тральной улице. Мы хотим записать эти данные, но куда их поместить в списке’ Ведь эта компания еще ничего не брала у пас в прокат.
Тарима 1 Л. Список Lakeview Equipment Job Contractor Phone Equipment type Equipment number Daily rate Start date End date Daye Charge Sea view BM0 KH Serctces 213-222-1181 Backhoe 10400 $750 17.06.2002 19.06.2002 3 $2250 Highland Center Comstock, Inc 232-492-3383 Backhoe 10400 $750 24.06.2002 24.06.2002 1 $750 Vtaw OvTCB • iu w Bldg KH Sercices 213-222-1181 Middle crane 335 $350 17.06.2002 3.07.2002 17 $5950 Long Ptaza KH Sercices 213-222-1181 Backhoe 10020 $650 1.07.2002 3.07.2002 3 $1950 Sea View ВИд KH Se cices 213-222-1181 Scaffolding $135 15.06.2003 Highland Center Comstock, Inc 232-492-3383 Middle crane 335 $400 1.07.2002 8.07.2002 8 $3200 Village Square RB Partnership 508-555-3233 Backhoe 10020 $750 8.07.2002 11.07.2002 4 $3000
Проблемы совместно используемым данных 27 Другая проблема состоит в несовместимости данных. Мы можем сдедат! hjm> стую опечатку в имени подрядчика и случайно написать KJ Service# вместо КН Services. Пользователи этого списка нс поймут, то ли у нас появился новый кли- ент, то ли это ошибка. Такие ошибки не могут во шикнуть, если мы выберем под- рядчика из списка имеющихся. Есть и более тонкие несоответствия. Проверим, например, четвертую и пятую строки. Обе они — о прокате экскаватора с номером 10020. В четвертой строке ежедневная плата 650 долларов, а в последней — 750 долларов. Является ли это не- совпадение следствием опечатки, или арендная плата меняется в зависимости от дня? Пли, может быть, для разных клиентов существуют разные цены? В этом слу- чае КН Services платит за экскаватор 650 долларов в день, a RB Partnei>hip — 750 Если это правда, то мы должны убедиться, что каждый раз, когда мы вводим сочетание фирмы КН Services с экскаватором под номером 10020, мы должны вводить плату 650 долларов в день. Другая проблема касается отсутствующих данных. Например, в записи о про- кате строительных лесов нет конечной даты. Ошибка ли это, или это означает что-нибудь другое? Это может значить, что прокат еще не закончен или что ком- пания КН Services хочет держать леса неопределенно долго. Проблемы совместно используемых данных Другие проблемы использования списка всплывают, когда мы рассматриваем данные, которые совместно используются многими людьми в компании Lakeview Equipment Rentals. Компания хочет дать каждому доступ к именам подрядчиков и к телефонным номерам из общего источника данных. Таким образом, если кто-нибудь изменит телефонный номер, то это изменение нужно сделать в общем источнике данных компании, В противном случае сотрудникам придется изме- нить эти данные на каждом компьютере компании. Однако если данные о подрядчике используются совместно, возникают дру- гие проблемы. Бухгалтерия ходет вести учет счетов подрядчиков и платежей. Сотрудники отдела проката хотят отслеживать координаты подрядчиков, встре- чи и заказы. Отдел по работе с клиентами хочет знать, какие проблемы возника- ли с определенными подрядчиками и как они решались. Все эти отделы не обяза- тельцо хотят использовать данные совместно с другими отделами. Бухгалтерия, например, не хочет, чтобы кто-то другой имел доступ к данным о счетах и плате- жах. Отдел по работе с клиентами не хочет, чтобы кто-то в компании знал, какие проблемы есть у клиентов. Таким образом, отделы готовы совместно использо- вать только некоторые данные, но не все. Существуют и другие проблемы использования списков, но идея уже понят- на: нужен более сильный способ хранения данных.
28 Глава 1. Введение в базы данных " ' 'v- «I —-- --------- Базы данных как группы связанных таблиц Одна серьезная проблема со списками, подобными изображенному в табл. 1.1, со- стоит в том, что они содержат данные на различные темы. Помните пашу учи- тельницу родного языка? Она наверняка говорила вам, что абзац должен быть посвящен только одной теме. Если у вас есть абзац, содержащий две темы или бо- лее, следует его разбить на несколько, каждый из которых говорит только об одной теме. Это суть процесса под названием нормализация, который мы глубоко иссле- дуем в главе 4. Проверим список в табл. 1.1. Сколько тем он содержит? Одна — строитель- ные проекты, другая — подрядчики, третья — оборудование и четвертая — про- кат. На рис. 1.1 показаны результаты разбиения списка на отдельные компонен- ты. Каждый из этих компонентов представляет собой таблицу данных, поэтому мы будем называть их таблицами. Таких таблиц получилось четыре — по коли- честву тем: CONTRACTOR (подрядчики), JOB (проекты), EQUIPMENT (оборудование) и RENTAL (прокат). ft «I •kh Straw 213/44 1131 CwrHxk.tac <32 432 3395 RE Partrfrtihip 503 555 3235 Рис. 1.1. Данные Lakeview Equipment в таблице -ji । > i>.« Когда список разбивается на четыре таблицы, многие проблемы, которые мы обсуждали, исчезают. Если компания КН Services меняет свой телефон на 213- 444-9988, мы делаем это изменение только однажды — в таблице CONTRACTOR. Если мы хотим удалить запись о прокате, мы всего лишь удаляем строку из таб- лицы RENTAL, не теряя при этом никаких данных о проектах, подрядчиках или оборудовании Если мы хотим добавить данные о новом клиенте, то просто до- бавляем эти данные в таблицу CONTRACTOR. Что касается противоречивости данных, то мы можем разработать наше при- ложение баз данных так, что когда кому-нибудь понадобится сделать новую за- пись о прокате, он просто выберет запись в таблице CONTRACTOR. Таким образом, ошибку сделать нельзя. Это также дает нам возможность контролировать появ- лея»«« новых клиентов Можно сделать так, что только определенные люди, на- прпыер. бухгалтеры, смогут добавлять новые строки в таблицу CONTRACTOR.
А как насчет протиноречиных данных о стоимости прокат в 1и0л II / М •«< кажется, тут и начинается веселье, Иа рис, 1.1 стоимость проката в мнь rate) помещена и таблицу EQUIPMENT. Это значит, что оборудовали» вл* но да- ваться в прокат за одну и ту же плату всем клиентам. Так отроекти|мзвана вся таблица. Является ли это правильным? Это зависит от бизнсс-правиЛ компании Lakeview. Есин, однако, плата зависит от каждого конкретного случая HpotaiiA, то столбец Daily rate нужно поместить в таблицу RENTAL Гели » жд подрядчик платит за прокат по собственным расценкам, нужно построить новую таблицу Главное здесь не в решении этой частной проблемы. Главное что проекти- рование таблицы должно отражать порядки организации, которая ее использует В этой книге мы потратим довольно много времени и усилий на подробный раз- бор каждой такой ситуации. Разбиение на таблицы также позволяет нам добавлять больше данных по каж- дой теме, чем появляется в списке в табл. 1.1. На рис. 1.2, например, показаны дополнительные данные для подрядчиков. При необходимости мы можем разра- ботать приложения нашей базы данных так, что только определенный персонал сможет знакомится с этими дополнительными данными. j Phone... j : [ sueetg • ♦ КН &ues 213.444.И81 • .Comstock, lac 232.492.3303 • RE Paint-ship 538 555.3233 U1 Piny 1200 Cc?nstcck' 1234 Sm Slw'*- Ne*/ Yom Ci’y NY Nw Yotx City NY .Highlands CA 1 .ШЬ1232 42345-1399 Siert Data : i ‘ - d Date 6/17/2002 6/19/2002-3 : 6/24/2002; 6/24/2002.1 . 6/17/2902 " ‘7/3^002; 17 “** • 7/1/2902:...... 7/3/2002:3 : 6/16Шй:................... lb.... 7/1 £2902; ' 7/6/29029 ’’ "Z zpi/yaa/;* ... ..1 1 j УГКПГб: И| t " A 1 Рис. 1.2. Таблица CONTRACTOR и дополнительные данные Связи Сейчас вас может испугать следующий вопрос. Данные на рис. 1.1 и 1.2 хороши, но где же связи между ними? Как можно узнать, какой подрядчик взял напрокат какое оборудование, для какого проекта и на какой срок? По данным на этих рисунках невозможно сказать, что к чему относится. Мы пришли к одному из фундаментальных вопросов теории баз данных. Этот вопрос мы будем обсуждать в главах 5 и 8 в теме о проектировании баз данных Сейчас рассмотрим рис. 1.3, на котором изображен один из способов построить связи между таблицами. Каждой строке в каждой таблице дается уникальный идентификатор 10 Этот идентификатор для пользователей фирмы Lakeview не имеет ншпогпг-q смысла;
30 Г два Г Введение в базы данных его цель — просто пронумеровать все строки таблицы. Значения идентификато- ра мы будем использовать для представления связи со строками таблицы RENTAL Рис.1.3. Таблицы Lakeview и связи между ними Рассмотрим четвертую строку таблицы RENTAL на рис. 1.3. Значение 3 в столб- це, обозначенном JoblD (идентификатор проекта) означает, что этот прокат отно- сится к проекту, который имеет в таблице JOB идентификатор, равный 3. Это строка, содержащая проект Long Plaza, который соотносится с данными в табл. 1.1. Подобным же образом располагаются в таблице прокат для подрядчика, имею- щий идентификатор 1 (КН Services), и для оборудования с ID, равным 3 (экска- ватор номер 10020). Список в табл. 1.1. содержит столбец, обозначенный Charge (стоимость), но такого столбца нет на рис. 1.3. Причина в том, что мы можем вычислить этот столбец, если он нам понадобится. Так и будет в базе данных. Стоимость будет вычисляться каждый раз, а не храниться. Хорошо это спроектировано или нет, опять же зависит от порядков в Lakeview. Следствие такого проектирования со- стоит в том, что если значение платы за день в таблице RENTAL меняется, то все долги при следующем вычислении будут основаны уже на новой цене. Таким образом, мы можем получить значение стоимости, отличное от того, что пользо- ватель платил в свое время. Подобные ситуации мы еще будем обсуждать в по- следующих главах. Подведем итог. Чтобы справиться с проблемами, которые возникают со спис- ками, подобными показанному в табл. 1.1, мы разбили список на четыре табли- пы, каждая из которых посвящена определенной теме. После этого мы связали таблицы с помощью уникального идентификатора. Как вы потом узнаете, этот уникальный идентификатор называется ключом. Ключ, который представляет связь, вроде JoblD в таблице RENTAL, называется внешним ключом. Эти термины мы будем использовать много раз в наших последующих обсуждениях.
Что такое система обработки базы данных? 31 Объединение таблиц «Но где же наш список?» — спросите вы. На рис. 1.3. все изображено красиво и пра впльно, но пользователи в фирме Lakeview, по крайней мерс некоторые из них, захотят увидеть список типа того, с которого мы начинали. Где он? В главах 6-8 будет изучаться язык, который является настоящим подъязыком данных. Называется он SQL (Structured Query Language, язык структурирован- ных запросов) и используется для манипуляций с таблицами типа изображен- ных на рис. 1.3. SQL — это промышленный стандарт, который поддерживается всеми основными системами управления базами данных (СУБД). Приведенный ниже оператор SQL используется в Access для объединения таблиц и отображе- ния их в том виде, как в табл. 1.1. SELECT JOB.Name. CONTRACTOR.Contractor. CONTRACTOR.Phone. EQUIPMENT.[Equipment Type], EQUIPMENT.[Equipment Number], EQUIPMENT.[Dally Rate], RENTAL.[Start Date], RENTAL.[End Date], RENTAL.Days.[Dallу Rate]*[Days] AS Charge FROM JOB. EQUIPMENT. CONTRACTOR, RENTAL WHERE CONTRACTOR.ID = RENTAL.ContractorID ANDEQUIPMENT.ID = RENTAL.ContractorID ANDJOB.ID = RENTAL.JoblD: Результат выполнения этого оператора показан на рис. 1.4. Там содержится список, с которого мы начинали, но с исправленными ошибками. . . j. . -jab _____________ _________________ S«sV:₽wBEg .KHSer-ccc 2*3444 1/61 Вас? Нэе H-gblas-d Canter ; CfimsUKk. ;.nc 232.4923363. ..Back Hee.......... Sss Yew Bfc'g 'KHSwtes 2'3.444.1 *81 Oar* .. XHSer»:ces *134^4 1 ;£1 'Back Чае KHSetv-cee 213.444 1181 Scaffc:riing , tr.r. 22? 432.3#3 Medii*v Crow H У Partr.crihp 403.516 3233 Вась Нее -'Efeow •;; IEfriymeCTy t л идШ L.i Qaljy Jfotr E»:LO*ts -foY* j 'Chary - ---- .... - - .........— • s/tz/axr блзчгооз 2 $з;2босс . €J24pX2: &О4ЖЙ2 1 $750 GC 10400 KU к 355 1CC29 $750.00 $750.90 $135.90 Lcr-g pj«a Highland Cen:e; VJIagc- Lquore •5350.00 . . 6;17Z3X< »£59 30 7/J/20& |Щ£ Рис. 1.4. Исходный список, построенный на основе таблиц 22002 17 Приведенный выше SQL-оператор можно использовать, чтобы определить об- щую структуру. Но понять все в подробностях он не поможет. Когда вы закончите чтение этой книгид вы легко сможете писать такие и более сложные операторы. Что такое система обработки базы данных? На рис. 1.5 показаны четыре основных элемента базы данных. Слева показано, как пользователи выполняют свои задачи с помощью базы данных. Они вводят новые данные, модифицируют существующие и удаляют ненужные. Кроме того. °ни разными способами читают данные: посредством форм, запросов и путем ге- нерации отчетов. Следующий компонент, приложение баз данных, представляет собой множество из одной или более компьютерных программ, которые служат
32 Глава 1. Давление в базы посредниками между пользователем и СУБД (программой, обрабатывающей ба- зу данных). Приложение создает формы, запросы и отчеты, посылает данные пользователю и получает их от него, а также преобразует действия пользователя в запросы для управления данными с помощью СУБД. Цель СУБД состоит в получении запросов от приложений и в преобразова- нии этих запросов в файлы ввода или вывода базы данных. В большинстве слу- чаев СУБД посылает SQL-операторы и переводит их в инструкции операцион- ной системы компьютера для чтения и записи данных в файлы базы данных. Теперь рассмотрим функции программы приложения и СУБД более подробно. ПольЛ •аатьль Рис. 1.5. Компоненты системы базы данных Функции прикладных программ На рис. 1.6 перечислены функции прикладных программ баз данных и СУБД. В первую очередь приложение создает и обрабатывает формы. Веб-приложение, например, генерирует HTML и другие конструкции веб-форм, которые заставля- ют форму отображаться на компьютере пользователя. Когда пользователь запол- няет форму и посылает данные обратно, приложение определяет, какие таблицы данных нуждаются в модификации, и посылает запросы к СУБД, чтобы вызвать необходимую модификацию. Если во время этого процесса возникают ошибки, приложение получает сообщение об ошибке и генерирует подходящее сообщение для пользователя или осуществляет какое-нибудь другое действие. Вторая функция прикладной программы, показанная на рис. 1.6, — создание и передача запросов. Сначала приложение генерирует запрос к СУБД. Такие за- просы почти всегда пишутся на языке SQL. После обработки запроса его резуль- таты форматируются и передаются пользователю. Третья функция похожа на вторую. Приложение запрашивает данные у СУБД (опять с помощью SQL) и форматирует результаты запроса в виде отчета. Кроме создания форм, запросов и отчетов, приложение также производит другие действия по изменению базы данных в соответствии с логикой, специ- фичной для этого приложения. Например, в некотором приложении пользова- тель запросил 10 единиц определенного товара. Теперь предположим, что когда прикладная программа произвела запрос базы данных (через СУБД), она нашла только 8 единиц в наличии Что следует сделать? Это зависит от логики данного конкретного приложения. Возможно, следует не брать ничего со склада и уведо- мить пользователя о возникшей ситуации, или же взять 8 единиц, а 2 оформить как Отложенный заказ. Могут быть и другие варианты. В любом случае, реализа- ция соответствующей логики — задача прикладной. программы. ле Во ви. ри дем да! aej все В n ко\ Про ЬВ Cyi < *ИД1 (
Что такое система обработки базы данных? 33 Приложение базы данных • Создание и обработка форм SQL Создание базы данных Система управления базой данных (СУБД) •Данные пользователя • Метаданные • Индексы и реляционные структуры •Хранимые процедуры •Триггеры •Метаданные приложения • Создание и передача запросов • Создание и обработка отчетов • Выполнение логики приложения •Управление приложением Создание таблиц Создание поддерживающих структур Чтение данных из базы Изменение данных базы Поддержка структур базы данных Установка правил • Управление параллельной обработкой • Обеспечение безопасности • Сохранение и извлечение резервных копий Рис. 1.6. Функции и содержимое компонентов обработки базы данных Последняя функция прикладной программы, указанная на рис. 1.6, — управ- ление приложением. Существует два способа осуществлять это управление. Во-первых, приложение должно быть написано так, чтобы пользователю были видны только определенные опции. Приложение может сгенерировать меню с ва- риантами для пользователя. При этом оно должно убедиться, что пользователю Доступны только нужные варианты. Во-вторых, приложение должно управлять данными с помощью СУБД. Оно может, например, указать СУБД сделать опре- деленный набор изменений в данных. СУБД может быть приказано произвести все эти изменения или не делать ни одного из них. Функции СУБД В противоположность прикладным программам которые часто пишутся самими компаниями, их использующими, почти все СУБД являются коммерческими продуктами. К коммерческим СУБД относятся Oracle от корпорации Oracle. °В2 от корпорации IBM, а также Access и SQL Server от корпорации Microsoft. Существуют десятки СУБД, но эти четыре захватили львиную долю рынка. Функции СУБД перечислены на рис. 1.6. СУБД используется для создания «мой базы данных, таблиц и других поддерживаемых структур - например, "следующие две функции СУБД - чтение и изменение данных в базе дан- ных Для этого СУБД получает запросы SQL (или какие-нибудь другие запросы)
34 Глава 1. Введение в базы данных и преобразует их в действия по отношению к базе данных. Другая функция СУБД — поддержка всех структур базы данных. Например, время от времени может понадобиться изменить формат таблицы пли другую поддерживаемую структуру. Для таких изменений программисты используют СУБД. При работе с большинством СУБД можно устанавливать правила, касающиеся значений данных. Например, рассмотрим рис. 1.3: что случится, если пользова- тель ошибочно введет значение 4 в столбец ContractorlD (идентификатор подряд- чика) в таблице RENTAL? Такого подрядчика нет, и это значение вызовет множе- ство ошибок. Чтобы предотвратить такую ситуацию, можно объявить СУБД, что любое значение ContractorlD в таблице RENTAL должно уже быть значением иден- тификатора в таблице CONTRACTOR. Если такого значения нет, вставка и запрос о модификации разрешаться не будут. Такие правила, которые называются огра- ничениями ссылочной целостности, устанавливаются СУБД. Последние три функции СУБД, указанные на рис. 1.6, относятся к управле- нию базой данных. СУБД контролирует работу, следя, чтобы изменения одного пользователя не пересекались с изменениями другого. Эта важная (и сложная) функция будет обсуждаться в главе 9. Кроме того, СУБД содержит систему безопасности, которая используется для проверки того, что голько авторизо- ванные пользователи выполняют определенные действия с базой данных. Поль- зователям могут не позволить знакомиться некоторыми данными, а также ограни- чить их действия только определенными изменениями в определенных данных. Наконец, база данных, как централизованное хранилище данных, является ценным имуществом организации. Рассмотрим, например, ценность базы данных книг в компании типа Amazon.com. Ввиду крайней важности этой базы данных нужно принимать меры по предотвращению потерь данных из-за случайных оши- бок, проблем аппаратного обеспечения пли природных катастроф СУБД обеспе- чивает возможность резервного копирования данных нз базы данных и восста- новления их в случае необходимости. Определение и компоненты базы данных На рис. 1.6 компонент системы базы данных, находящийся справа, — сама база данных. Перед тем как продолжать, мы должны определить термин.база данных и описать ее компоненты. В общем случае, можно сказать, что база данных — это самодокументирован- ное собрание интегрированных записей. Для всех реляционных баз данных (а это сегодня почти все базы данных, и только этот тип рассматривается в данной кни- ге) это определение можно модифицировать так: база данных — это самодоку- мгнтированное с обрание связанных таблиц. Ключевые слова в этом определении — самодокументированность и связан- ные таблицы. Вы уже примерно представляете, что мы подразумеваем под свя- занными таблицами. Примерами являются таблицы JOB, CONTRACTOR, EQUIPMENT и RENTAL Ваше понимание этого углубится в главах 5 и 8.
Что такое система обработки базы данных? 35 Под саиодокументировттостью мы подразумеваем, что описание структуры базы данных содержится в самой базе данных. Благодаря этому мы всегда можем vзнать содержимое базы данных, просто посмотрев на нее. Нам не нужно смот- реть куда-то еще. Эта ситуация похожа на ситуацию с библиотекой в вашем студгородке Можно сказать, что находится в библиотеке, просмотрев карточки каталога. Данные о структуре базы данных называются метаданными. Примерами ме- таданных служат имена таблиц, имена столбцов и таблицы, которым они при- надлежат, а также свойства таблиц и столбцов, и так далее. На рис. 1.7 показаны метаданные для базы данных Lakeview, которую мы рас- сматривали ранее. Таблица под названием SYSTABLES содержит данные о каждой из таблиц базы данных, а вторая таблица (SYSCOLUMNS) содержит данные о каждом из столбцов и о связях столбцов с таблицами. Этот рисунок — только пример метаданных. Таблицы, подобные этим, существуют внутри баз данных, обраба- тываемых продуктами типа Oracle, SQL Server или DB2, но они более сложные. Заметим, однако, что сами метаданные содержатся в таблицах. Это значит, что осведомленный персонал может использовать SQL для запросов к метаданным, так же, как и к пользовательским данным. ТзЬЫО jiapteName Л iNumberCbk . NurnbetRov¥s К 1 JOB 2 4 2 CONTRACTOR 8 3 3 EQUIPMENT 4 4 RENTAL 7 7 Column© ICdName " 1 DataType 1 ID mt 4 1 __2 Name char 50 J .ID int 4 2 4 Contractor char 50 2 5 Phone char 20 2 6 Street char 50 2 7 Streets char 50 2 _е City char 50 2 9 State char 2 10 Up char 10 2 11 ID mt 4 3 12 Equipment Type char 35 3 13 Dary Rate currency 4 3 — Н ID int 4 4 _1S ХЬЮ int 4 4 _ и GxrtractorlD nt 4 4 — И Equipment!!? int 4 4 18 Start Data date/bme 4 4 End Date date/tfna 4 4 20 Days int 4 4 ZJ21 Equnment Number nt 8 3 ® Рис. 1.7. Пример метаданных
36 Глава 1. Введение в базы данных Все поставщики СУБД предоставляют набор средств отображения структуры баз данных. Например, иа рис. 1.8 показано использование команды Describe в базе данных Oracle. Как видно, эта команда выдает список имен п свойств столбцов в таблице. Рис. 1.8. Использование команды Dercribe из Oracle Согласно рис. 1.5, база данных содержит пользовательские данные и мета- данные, как было только что описано. Кроме того, база данных имеет индексы и другие структуры, которые существуют для облегчения представления баз дан- ных. Впоследствии мы поговорим об этих структурах подробнее. Сейчас скажем только, что индекс похож на предметный указатель в конце книги и показывает, где искать определенные записи в таблице. Например, можно построить индекс EquipmentlD (идентификатор оборудования) в таблице RENTAL. Этот индекс можно использовать для быстрого нахождения всех строк в таблице RENTAL, имеющих определенное значение идентификатора. Хранимая процедура — это программа, которая хранится в базе данных. Неко- торые хранимые процедуры являются утилитами для базы данных. Например, Lakeview может иметь хранимую процедуру, которая удаляет все данные о про- кате более чем годовалой давности и все платежи, которые были сделаны за про- кат. Такой хранимой процедуре может потребоваться проверка множества таб- лиц в базе данных и реализация сложной логики. Другие хранимые процедуры реализуют логику приложения. Например, можно написать хранимую процеду- ру для генерации списка задолженностей.
Что такое система обработки базы данных? 37 Триггер — это процедура, которая выполняется при вопикновении опреде- ленных ситуаций в данных. База данных Lakeview может, скажем, иметь триггер CustomerCheck, который проверяет, имеет ли клиент хорошую репутацию, перед сохранением каких-либо новых данных о прокате для него. При попытке добавить строку в таблицу RENTAL (прокат) СУБД сначала загрузит и обработает триггер, а потом уже сделает изменение. В этом случае триггер не позволит вставку но- вой строки, если репутация клиента плохая. Подобно хранимым процедурам, триггеры содержатся в базе данных. Хранимые процедуры пишутся или на язы- ке, уникальном для конкретной СУБД, или на языках общего назначения типа Java. О хранимых процедурах и триггерах вы узнаете подробнее из глав 10 и И. Наконец, некоторые базы данных содержат метаданные приложений — про- стые данные, которые описывают элементы приложения, такие как формы и от- четы. Например, Microsoft Access содержит метаданные приложения как часть своих баз данных. Три примера систем баз данных Технология баз данных может использоваться в широком спектре приложений. На одном его конце исследователь может использовать технологию баз дан- ных для отслеживания результатов экспериментов, проводимых в лаборатории. В такой базе данных может быть всего несколько таблиц, и каждая из них может иметь максимум несколько сотен строк. Исследователь может быть единствен- ным пользователем такого приложения. На другом конце спектра — гигантские базы данных, которые поддерживают международные организации. Такие базы данных содержат сотни таблиц по мил- лиону строк данных каждая и используются одновременно тысячами пользова- телей. Эти базы данных работают круглосуточно и без выходных. Сделать даже обычную копию такой базы данных — трудная задача. В этом разделе показаны три разных приложения баз данных: одно — для единичного пользователя, второе — для малого бизнеса и третье — для большого правительственного агентства. Малярная фирма Мэри Ричардс Мэри Ричардс — профессиональный маляр, владеет и управляет небольшой ком- панией, состоящей из нее самой, еще одного профессионального маляра и, когда это необходимо, наемных работников. Мэри занимается этим бизнесом уже 10 лет и приобрела за это время репутацию высококвалифицированного маляра, рабо- тающего за умеренную плату. Большую часть заказов она получает от постоянных клиентов, нанимающих ее для покраски домов, а также от их знакомых. Кроме того, некоторое количество заказов Мэри получает от строительных подрядчиков и профессиональных дизайнеров интерьера. Клиенты помнят Мэри намного лучше, чем она их. Порою она бывает смуще- на, когда клиент звонит ей и говорит что-нибудь такое: «Здравствуйте, Мэри, это
38 Глава 1. Введение в базы данных Джон Мэплз. Вы красили мой дом три года назад». При этом звонящий подразу- мевает, что Мэри вспомнит его и работу, которую она для него сделала; но если учесть, что Мэри красит более 50 домов в год, для нее это будет затруднительно. Ситуация становится еще хуже, когда клиент заявляет: «Моей соседке понрави- лось, как вы покрасили наш дом, и она хочет, чтобы вы и у нее сделали что-ни- будь подобное». Чтобы несколько разгрузить свою память и лучше организовать учет деятель- ности фирмы, Мэри наняла консультанта для разработки базы данных, которую она могла бы хранить на своем персональном компьютере. В базе данных долж- ны храниться записи о клиентах, заказах и поставщиках клиентов, представлен- ные в форме таблиц (рис. 1.9). IFJ Mwrosoft Access : . < leob tfrdw tri «1ИД t Аг -нФ £« ;c jb ' : ‘ - гл- . < • ’'J- Рис. 1.9. Таблицы данных для малярной фирмы Мэри Ричардс Как мы уже говорили, СУБД хранит данные в таблицах и извлекает их отту- да. К сожалению, эти данные, будучи представлены в форме таблиц, не слишком полезны для Мэри. Ей, скорее, хотелось бы знать, как клиенты и заказы связаны друг с другом — например, какие работы были выполнены ею для конкретного клиента или какие клиенты были направлены к ней конкретным человеком. Чтобы предоставить Мэри такую возможность, консультант создал приклад- ttpto программа (application program), которая обрабатывает формы (forms) для
Что такое система обработки базы д анных? ввода данных и формирует отчеты (reports). Рассмотрим пример, предела*- леннып на рис. 1.10. В изображенную здесь форму Мэри вводит личные данные клиента — имя, телефон и адрес. Далее опа вводит сведения о работах, ыпо ценных для клиента, и указывает, кто направил этого клиента к ней Эти данн е могут быть затем отражены в отчете, пример которого показан на рис. 111 Дру- гие функции этой базы данных включают оценку стоимости заказа, учет постав- щиков клиентов и создание наклеек с адресом для рекламных буклетов, которые Мэри время от времени рассылает. Рис. 1,10. Пример формы ввода данных для малярной фирмы Мэри Ричардс Прикладная программа и СУБД обрабатывают заполненную форму и пере- писывают данные из нее в таблицы, подобные изображенным на рис. 1.9. Анало- гичным образом прикладная программа и СУБД извлекают данные из этих таб- лиц для создания отчетов, таких, как на рис. 1.11. Еще раз вернувшись к рис. 1.9, обратите внимание, что строки таблицы со- держат перекрестные ссылки и поэтому оказываются связанными друг с другом. Для каждой работы (ЗОВ) указан номер клиента (CUSTOMER_ID), заказавшего эту работу, и для каждого клиента (CUSTOMER) указан номер поставщика клиента (SOURCE_ID), то есть человека, направившего этого клиента к Мэри. Эти ссылки используются для объединения данных в формы и отчеты (рис. 1.10 и 1.11). Как вы можете догадаться, Мэри вряд ли имеет представление о том, как про- ектировать таблицы, создавать их с помощью СУБД и разрабатывать приклад- ную программу для создания форм и отчетов. Но ваших знаний о технологии баз Данных к моменту окончания этого курса должно хватить для того, чтобы суметь разработать такую базу данных и прикладную программу для работы с ней. Вы должны будете также уметь проектировать таблицы и манипулировать ими для создания довольно сложных форм и отчетов.
40 Глава 1. Введение в базы данных Customer Job History (зоз) sss-ctx *2,730 »,w fiT/MtX} Pert Hong K*sm «0 tktwi tv 78 V.77B ЗЛ5ЙЙ0* Prepbrxip»WU3lU*sbafn *M0 »И0 *4028 $>,073 Total МюлвМняЬвг AwounlBliied AmotmiPaid »’^S8 r;as $1299 Jl.m Total Jackx*\ C/rtf (54$) Щ.124 fltarw^ti^r AmotmifiHixl Atnoxnlfiaid tees JbftPw Ztocrffifow 300000 P*i<u»er>M*TSHW»*« ЩЩЩ30ргкЩ| * •>. lit »>* \v--4*. i«4f> ОвммыгМыпс #4 Awofl С Ьф CMtwnjrtJttm Maples, Man^rt (303) 777-евР JabDatf Dtvccriptian__________________ 40'2005 Point work* tfoercin 633 Rod JbbDaie 7ЯЛОК" Prepandpawirtwinr wxxitnm •I sees Put Itfl j fowpmerlnh Ний-. < \ 4 *» и« Рис. 1.11. Пример отчета для малярной фирмы Мэри Ричардс Ajn>uniSUM A/nsumirtod Бюро проката музыкальных инструментов Treble Clef Music База данных Мэри Ричардс называется однопользовательской (single-user), по- скольку в каждый конкретный момент времени к ней обращается только один пользователь. В некоторых случаях такое ограничение неприемлемо: иногда тре- буется, чтобы одновременно к базе данных могли обращаться несколько человек с различных компьютеров. Такие многопользовательские (multi-user) базы данных являются более сложными, поскольку СУБД и прикладные программы должны заботиться о том, чтобы действия одного пользователя не противоречили дей- ствиям другого. Бюро проката Treble Clef Music использует базу данных для учета сдаваемых в аренду музыкальных инструментов. Для этого требуется многопользователь- ская база данных, поскольку в периоды наплыва клиентов выдачей музыкаль- ных инструментов могут одновременно заниматься несколько служащих. Кроме того, менеджер также должен иметь доступ к базе данных, чтобы определить момент, когда необходимо будет заказать большее количество определенных ин- струментов. При эгом менеджер не должен мешать процессу выдачи инструментов. Б reble Сlef Music имеет локальную сеть, соединяющую несколько персо- нальных компьютеров с сервером, па котором находится база данных (рис. 1.12).
Что такое система обработки бмы д» >***"> 41 У каждого из служащих есть доступ к прикладной программе, позволяющей ра- ботать с тремя видами форм (рис. 1.13). Форма CUSTOMER содержит информацию о клиенте, форма RENTAL AGREEMENT представляет договор аренды и используется для учета выдачи и возврата инструментов, а форма INSTRUMENT содержит сведе- ния об инструменте и историю его аренды. Компьютеры служащих Компьютер управляющего Рис. 1.12. Локальная сеть бюро проката Treble Clef Music Чтобы уяснить проблемы, которые необходимо преодолеть в многопользова- тельской базе данных, представьте себе, что произойдет, если два клиента одно- временно попытаются взять напрокат один и тот же кларнет си-бемоль. СУБД и прикладная программа должны каким-то образом обнаружить эту ситуацию и сообщить служащим, что им следует выбрать другой инструмент. Бюро регистрации автомобилей и выдачи прав Рассмотрим теперь еще более обширное приложение технологии баз данных — государственное бюро регистрации автомобилей и выдачи водительских прав. В него входят 52 центра, где принимаются экзамены по вождению и осуществля- ется выдача и продление прав, а также 37 офисов, занимающихся регистрацией транспортных средств. Персонал этих офисов использует в своей работе базу данных. Прежде чем конкретному лицу будут выданы или продлены права, в базе данных просматри- ваются сведения об этом лице на предмет наличия нарушений правил дорожного Движения, ДТП или арестов. На основе этих данных принимается решение, могут ли права быть продлены, и если да, то будут ли в них какие-либо ограничения. Аналогичным образом, персонал в отделе регистрации автомобилей обращает- ся к базе данных, чтобы определить, был ли автомобиль зарегистрирован ранее, а если был, то на чье имя, и нет ли каких-либо из ряда вон выходящих причин, по которым в регистрации следует отказать.
42 Глава 1. Введение в базы данных а б в Рис. 1.13. Формы, используемые бюро проката Treble Clef Music: а — форма Customer, б форма Rental Agreement, а — форма Instrument Data
Что такое система обработки базы данных? 43 у этой базы данных сотни пользователей, включая не только персонал, за- нимающийся регистрацией и выдачей прав, но и служащих финансового управ ленпя, а также сотрудников правоохранительных органов. Не удивительно, что база является большой и сложной и имеет более 40 таблиц, причем некоторые из них содержат сотни тысяч строк данных. Компоненты этой системы пока- заны на рис. 1.14. Заметьте, что приложения написаны на разных языках и, вероятно, в раз- ные периоды времени. Oracle обрабатывает две разные базы данных по пору- чению этих приложений. Поскольку эти приложения очень важны, система должна быть доступна круглосуточно и без выходных. Такой уровень доступ- ности делает простые задачи, например резервное копирование, очень труд- ными. Большие организационные базы данных, подобные только что рассмотренной нами, были первыми приложениями технологии баз данных. Подобные системы находятся в эксплуатации уже в течение 20 или 30 лет и за этот период неод- нократно модифицировались в соответствии с менявшимися требованиями вре- мени. Существуют организационные базы данных, предназначенные для веде- ния счетов в банках и других финансовых институтах, учета готовой продукции и комплектующих па складах больших предприятий, обработки медицинской документации в госпиталях и страховых компаниях, а также для правитель- ственных нужд. Сегодня многие организации модифицируют прикладные программы сво- их баз данных, чтобы дать клиентам возможность обращаться к этим данным н даже вносить в них изменения через Интернет. Если вы работаете в большой организации, то вас вполне могут подключить к подобному проекту. Сравнение четырех типов баз данных Приведенные примеры демонстрируют возможные варианты использования тех- нологии баз данных. Есть согни тысяч баз данных, похожих на ту, что имеется в малярной фирме Мэри Ричардс, — однопользовательские базы данных с отно- сительно небольшим количеством данных, скажем, менее 10 Мбайт. Формы и от- четы для этих баз данных имеют обычно довольно простой вид. У других баз данных, подобных той, что используется в бюро проката Treble Elef Music, несколько пользователей, но общее их количество обычно не превы- шает 20-30 человек. Они содержат умеренное количество данных — например 50 или 100 Мбайт. Формы и отчеты должны быть достаточно сложными, чтобы поддерживать несколько различных деловых функций. Самые большие размеры у баз данных, подобных той, которую мы рассмат- ривали для случая бюро регистрации автомобилей, — у них сотни пользователей 11 триллионы байт данных. Для работы с этими базами данных используется множество различных приложений, у каждого из которых свои собственные Формы и отчеты. Характеристики этих типов данных сведены в табл. 1.2.
44 Глава 1 Введение в базы данных Код C# HTML и VBScript Приложение для регистрации автомобилей Приложение для обновления информации о водителях Приложение для истории водителей Код Java Oracle База данных по водителям Рис. 1.14. Организационная система баз данных База данных по автомобилям Прочтя книгу, вы сможете проектировать и реализовывать базы данных напо- добие тех, что используются в малярной фирме Мэри Ричардс и в бюро проката Treble Clef Music. Возможно, вы будете еще не в состоянии создавать такие боль- шие и сложные базы данных, как та, что используется в бюро регистрации транс- портных средств, но, тем не менее, сможете быть полезным членом команды по разработке и созданию такой базы данных. Вы также сможете создавать неболь- шие или средних размеров базы данных, использующие Интернет-технология. Таблица 1.2. Характеристики разных типов баз данных Тип Пример Число пользователей Размер базы данных Персональная Малярная фирма Мэри Ричардс 1 < 10 Мбайт Для рабочей группы Бюро проката музыкальных инструментов Treble Clef Music <25 <100 Мбайт Организационная Бюро регистрации автомобилей и выдачи прав сотни или тысячи >1 Тбайт, возможно, несколько баз данных Как построить систему баз данных Процесс построения базы данных по большей части совпадает с процессом по- строения любой другой информационной системы. Как показано в табл. 1.3, существуют три основных фазы: формулирование требований, проектирование и реализация. Большая часть этой книги посвящена второй фазе, хотя в некото-
Как построить систему баз данных 4S рых главах мы будем рассматривать также создание запросов и кода прилоа • iшя. Однако сначала мы познакомимся с разработкой базы данных. таблица 1.3. Обзор фаз построения базы данных фаза построения базы данных Базы данных Приложения Фаза формулирования требований Построение модели данных Определение требований Задание элементов данных приложения Определение ограничений и правил Фаза проектирования Таблицы Формы Отношения Отчеты Индексы Запросы Ограничения Код приложения Хранимые процедуры и триггеры Фаза реализации Создание таблиц Создание форм Создание отношений Создание отчетов Создание ограничений Создание запросов Написание хранимых процедур Написание кода приложения и триггеров Тестирование Заполнение базы данных Тестирование Фаза формулирования требований Во время этой фазы разрабатывается модель данных: типы элементов данных, их длина и другие свойства. Кроме того, на данные накладываются ограничения и правила. Модель данных — это логическое представление структуры базы данных. Моделирование данных очень важно, поскольку и база данных, и все ее структу- ры зависят от модели данных. Если модель данных некорректна, результат будет разочаровывающим. Учитывая важность модели данных, я посвятил ей следу- ющие две главы. На рис. 1.15 показан пример диаграммы модели данных для фирмы Lakeview Rentals. На рисунке представлен пример диаграммы сущность—связь — средства выражения моделей данных, которое стало промышленным стандартом. На этом Рисунке JOB, CONTRACTOR, RENTAL и EQUIPMENT являются сущностями. Линии представляют связи между этими сущностями. Остальными подробностями пока можно пренебречь. Нужно только знать, что такие диаграммы существуют для Документирования моделей данных. Как вы увидите позже, во время фазы формулирования требований необхо- димо определить свойства элементов данных, такие как тип данных, максимальная Длина, требуется ли значение и т. д. Кроме того, следует определить значения элементов данных и правила обработки данных. Приведем пример ограничения ДДИных: значение Equipment type (тип оборудования) должно быть из следующего
46 Глава 1. Введение в базы данных множества: ['Backhoe', 'Smallcrane', 'Medium crane, 'Large crane', 'Scaffolding'^ (экска- ватор, малый кран, средний кран, большой кран, строительные леса). Ограниче- ния и правила мы будем обсуждать в следующих двух главах. Рис. 1.15. Диаграмма сущность—связь для базы данных Lakeview Rentals Фаза проектирования Во время фазы проектирования модель данных преобразуется в таблицы и отно- шения. На рис. 1.16 показан пример диаграммы с труктуры данных — диаграммы, используемой для отображения таблиц и их отношений. На этой диа1рамме ли- ния между таблицами EQUIPMENT и RENTAL представляет связь. Вилка по направ- лению к таблице RENTAL означает, что данная строка в таблице EQUIPMENT можег относиться ко многим строкам таблицы RENTAL. Эту и подобные диаграммы мы будем использовать при обсуждении проектирования баз данных в главах 5 и 8. В этих главах вы узнаете значение и других элементов на этом рисунке. JOB Table CONTRACTOR Table Рис. 1.1 в. Пример диаграммы структуры данных для Lakeview Rentals
Как построить систему баз данных 47 Необходимость в индексах определяется во время фазы проектирования биы данных, и иногда также задаются характеристики индексов (я говорю « иногда» поскольку не все СУБД поддерживают эту спецификацию) Механизмы огра ничении, хранимые процедуры и триггеры также проектируются Об этом вы узнаете из глав 10-12. CREATE TABLE EQUIPMENT ID EquipmentType EquipmentNumber DailyRate Int Char (35) Char (25) Number (6,1 Primary Key, Not Null, Not Null, г»; CREATE TABLE RENTAL( ID Int Pnmary Key, Jobl D Int Not Null. ContractorlD Int Not Null, Equipment® Int Not Null, StartDate Char (12) Not Null, EndDate Char (12), Days Smalllnt, Charge Number (8,2)); ALTER TABLE RENTAL ADD CONSTRAINT EquipmentFK FOREIGN KEY (EqwpmentID) REFERENCES RENTAL; a 6 Рис. 1.17. Создание таблиц, a — с помощью текстовых команд, б — с помощью графических средств
48 Глава 1. Введение в базы данных Фаза реализации Как показано в табл. 1.3, в фазе реализации создаются таблицы и связи. Для соз- дания таблиц используются два способа: с помощью SQL и через средство графи- ческого проектирования. На рис. 1 17, а показаны SQL-операторы для созда- ния таблиц EQUIPMENT и RENTAL и для определения связей между ними. Такие SQL-операторы можно вводить в базу данных для определения таблиц и связен. На рис. 1.17, б показан другой прием — использование средства графического проектирования для определения таблицы CONTRACTOR в SQL Server. Большин- ство СУБД позволяют использовать оба способа. Аналогичным образом, в боль- шинстве СУБД можно задавать ограничения на данные как с помощью SQL, так п с помощью графических средств. О том, как писать SQL-операторы для этих целей, вы узнаете в главах 7 и 8. Во время реализации также пишутся и тестируются хранимые процедуры и триггеры. Как это делается в Oracle, вы узнаете в главе 10, а в SQL Server — в главе И. Наконец, база данных заполняется данными, и система тестируется. Некоторые информационные системы на этом уже готовы. Обычно же когда база данных и ее приложение завершены, необходимо еще модифицировать их в соответствии с новыми требованиями, которые разрабатываются во время фазы реализации. Такие модификации также проходят эти же гри фазы (форму- лирования требований, проектирования и реализации), но это происходит в кон- тексте существующих баз данных и приложений. Изменение существующих баз данных может быть очень трудным, и этот процесс, называемый перепроектиро- ванием базы данных, мы будем обсуждать в главе 8 Разработка приложения Разработка приложения осуществляется параллельно с разработкой базы дан- ных. Поскольку эта книга посвящена базам данных, мы не будем слишком по- дробно останавливаться на разработке приложения. В главе 7 будет обсуждаться использование SQL для приложений, а в главах 10 и 11 будет описываться напи- сание хранимых процедур и триггеров. Однако по большей части третий столбец табл. 1.3 мы оставим для ваших занятий по системному программированию. Перед тем как перейти к моделированию данных, мы завершим эту главу кратким экскурсом в историю баз данных. Краткая история баз данных бл 1.4 сведена история развития технологии баз данных. До середины 1960-х годов почти все компьютерные хранилища данных были на магнитных лентах, оскольку лента может обрабатываться только последовательно, данные должны ‘ >< и храниться в виде списков (или последовательных файлов, как они называ- лись) Однако, как вы узнали в начале этой главы, хранение даже простейших иных в таком формате чревато большими проблемами.
Краткая история баз данных 49 Таблица 1.4. Краткая история баз данных Период Технология д^1968 Обработка файлов Примечания Предшествовала обработке баз данных. Данные хранились в виде списков. Характер обработки определялся всеобщим использованием в качестве носителя магнитной ленты 1968-1980 Иерархические и сетевые модели Эра обработки нереляционных баз данных. Выдающейся иерархической моделью данных была DL/I фирмы IBM Первая СУБД называлась IMS. Выдающейся сетевой моделью данных была модель DBTG фирмы CODASYL. Самой популярной сетеаой СУБД была IDMS 1980 - наст. Реляционная время модель данных 1982 Первые СУБД для микрокомпьютеров 1985 Развитие интереса к объектно- ориентированным СУБД (ООСУБД) 1991 Компания Microsoft выпустила Access 1995 Первые приложения баз данных для Интернета 1997 Применение XML к обработке баз данных Реляционная модель данных впервые была опубликована в 1970 году. Реализовываться в коммерческих приложениях начала в 1980 году. IBM выпустила DB2, среди других продуктов выделяется Oracle. Реляционный язык SQL стал промышленным стандартом Фирма Ashton-Tate разработала dBase, Microrim — R:Base, a Borland — Paradox С развитием объектно-ориентированного программирования были предложены ООСУБД. Коммерческий успех их невелик, в первую очередь потому, что преимущества не оправдывают перевод миллиардов байтов данных организаций в новый формат. Продолжают развиваться и сейчас Персональная СУБД, созданная как элемент Windows. Постепенно вытеснила с рынка все другие персональные СУБД Базы данных стали ключевым компонентом Интернет- приложений. Популярность Интернета существенно повысила необходимость в базах данных и требования к ним Использование XML решило проблемы, которые долго стояли перед базами данных. Ведущие производители стали интегрировать XML в свои СУБД Ранние модели баз данных С коммерческим успехом хранилищ на дисках в середине 1960-х стало воз- можным получение непоследовательного, или прямого, доступа к записям. Базы Данных стали разрабатываться по-другому. Изначально стали успешными две конкурирующие архитектуры, или модели. Корпорация IBM разработала и вне- дрила DL/I (Data Language One, язык данных один), который моделировал дан- Ные в базах данных в форме иерархий, или деревьев (см. рис. 1.18, а). Эта модель, которая была разработана совместно с промышленными предприятиями, легко МоглД использоваться для поддержки данных, таких как сметы материалов и списки Деталей, но для общих целей мало подходила. Представление неиерархических Сегевых данных (рис. 1.18, б) было громоздким.
50 Глава 1. Введение в базы данных После этого CODASYL, группа, которая разрабатывала стандарты для языка COBOL, в 1970 году создала модель под названием DBTG (Data Base Task Group группа задач баз данных). Модель DBTG была готова к представлению как ие- рархических, так и сетевых данных. Один раз эта модель предлагалась в качестве национального стандарта, но не была принята в первую очередь из-за своей сложности. Однако это была основа для ряда коммерчески успешных СУБД в се- мидесятых и восьмидесятых годах прошлого века. Наиболее успешным был продукт корпорации Cullinane под названием IDMS. Замечание: каждый узел имеет не более одного родительского узла а Замечание: узлы могут иметь и по несколько родительских узлов б Рис. 1.18. а — пример иерархии: университетская организация, б — пример сети: классы и студенты Реляционная модель Реляционная модель, которая представляет данные в формате, показанном на рис 1.3, впервые была предложена Е. Ф, Коддом в 1970 году. Кода работал в IBM, и после десяти лет исследований, разработки и лоббирования на уровне корпо- рации он с коллегами убедил IBM разработать несколько СУБД, основанных на
Краткая история баз данных 61 реляционной модели Наиболее известным на этих продуктов является DB2 — СУБД, которая активно используется и поныне. Между тем другие корпорации (такие как Oracle, Ingres, Sybase и Informix) тоже разработали СУБД, основанные на реляционной модели SQL Server был разработан в Sybase и в конце восьмидесятых ходов продан Microsoft. Сегодня D 2 Oracle и SQL Server являются наиболее выдающимися коммерческими СУБД СУБД для персональных компьютеров С появлением большого числа микрокомпьютеров стало возможно иметь персо- нальные базы данных. В результате был разработан ряд СУБД для персональных компьютеров. Наиболее успешной из них была dBase — продукт корпорации Ashton-Tate. Еще среди ранних персональных СУБД можно назвать R:base корпо- рации Microrim и Paradox от Borland. Поскольку компьютеры обладали довольно большой вычислительной мощ- ностью, персональные СУБД предоставляли больше графических интерфейсов пользователя. Кроме того, со временем под влиянием этих продуктов изменились и интерфейсы больших организационных СУБД. На рис. 1.17 показан этот момент. Технология того, что показано на рис. 1.17, а, разрабатывалась для символьно- ориентированных интерфейсов, которые были распространены для СУБД, пред- шествовавших персональным компьютерам. На рис. 1.17, б показан пример графи- ческого интерфейса, который появился с возникновением персональных СУБД. Объектно-ориентированные СУБД (ООСУБД) Объектно-ориентированное программирование начало развиваться в середине восьмидесятых годов прошлого века и привело к созданию объектно-ориентиро- ванных СУБД. Целью этих продуктов была способность хранить объекты из объектно-ориентированного программирования (например, из языков C++ или Java) в базе данных, не преобразуя их в реляционный формат. В настоящее время ООСУБД не имеют коммерческого успеха. Их использо- вание требует от организаций преобразовывать свои базы данных из реляцион- ного в ООСУБД формат. Кроме того, большинство крупных организаций имеют более старые приложения, не основанные на объектно-ориентированном про- граммировании. Программы в таких приложениях потребовалось бы как-то сопровождать новыми ООСУБД. Таким образом, высокая стоимость перевода существующих баз данных и информационных систем из реляционных СУБД в ООСУБД задерживает их широкое распространение. Были разработаны объектно-ориентированные СУБД, такие как Oracle 81 и 9i, Что позволило создавать как реляционное, так и объектное представление дан- НЬ1Х одной и той же базы данных. Эти СУБД начинают получать коммерческий Успех, но не такой, как чисто реляционные СУБД. Объектно-ориентированные уБД мы рассмотрим в главе 16.
52 Глава 1 Введение в базы данных Недавняя история » .. л „ -w.nn Access который на несколько дет вытеснил С РЫН' б,.а,тому, что ка все остальные С> Д_ « Microsof( СМ()171а использовать свое влияние на 'n,TCn>"PZ^™?l°'с ХбоХя смс,11Я.»я других продукт»» П^«. Esoft нужно отдать епра»ед,.п.юсгь: Access - суиерпролукт. Он доминирует на рынке потому что это легкая в использовании и сильная СУБД Как все знают, использование Интернета распрост ранилось в середине девя- ностых годов Но немногие знают, что именно это сильно повысило значение и важность технологии баз данных. Как только ранние статические веб-страницы уступили дорогу динамическим, как только стали иметь успех компании типа Amazon com и как только большие организации начали использовать Интернет для публикации своих данных, все большее и большее количество сайтов стало зависеть от баз данных. Эта тенденция продолжается и по сей д Наконец, в последние годы появился и стал широко использоваться язык XML, который представляет собой технологию для поддержки веб-сайтов, но был расширен для проведения важных решений, связанных с базами данных Я ык XML мы будем обсуждать в главе 13. Пока же нам осталось осознать, что инте- грация технологии баз данных с XML является ведущим пунктом области баз данных сегодня и будет важна еще много лет в будущем. Резюме Хотя обработка баз данных всегда была важной темой, популярность Интернета сделала ее еще и одной из самых нужных специальностей. Навыки, которые вы разовьете, и знания, которые вы приобретете, будут чрезвычайно востребованы. Цель базы данных — помочь людям и организациям вести учет различных ве- щей. Хотя для этой цели можно использовать списки, они вызывают множество проблем. Их сложно изменять без возникновения несоответствий, удаления из списков могут иметь непредвиденные последствия, а неполные данные трудно записывал,. Кроме того, вводя данные, легко вызвать их противоречивость, аконец различные части организации хотят поддерживать некоторые данные местно, а некоторые — исключительным образом. Это трудно организовать при использовании списков. кйЖ7тяа1гаГННЫХ состоят из гР>'пп реляционных таблиц. В большинстве случаев таким обпйзт^п содержит данные по определенной теме. Поддержка данных лидах п!елставпГаеТ ВСе проблемы- перечисленные для списков. Связи в таб- путем присвоения1?^ рззнь1ми спосо^ами- в эт°й главе связи представлялись этого идентиЛикатог^Д0И С"Р0Ке уникального идентификатора и использования лицы. Для представления1 “язи„СТроки одной таблицы со строкой другой таб- можно создавать с помощью да?ка5ОЬЛЬЗ°ВаЛ”СЬ ” ВНешНие ключи- Та6лш‘ы дартом для обработки таблиц ’ КОТОрыи является промышленным стан-
__________________________________________Вопросы группы I 53 Система базы данных состоит из четырех основных элементов пользователи приложения базы данных, СУБД и сама база данных. Пользователи применяют базу данных для решения своих задач. Приложения производят формы, запросы и отчеты, выполняют логику приложения и управляют обработкой базы. СУБД создает, обрабатывает и администрирует базу данных. База данных — это самодо- кументпрованное собрание интегрированных записей. Она содержит пользователь- ские данные, метаданные, индексы, хранимые процедуры, триггеры и метадан- ные приложения. Хранимая процедура — это программа, которая обрабатывает участок базы данных и хранится в базе данных. Триггер — это процедура, кото- рая вызывается при наступлении определенного события. На рис. 1.6 показаны функции компонентов базы данных. Технология баз данных может использоваться в широком спектре приложе- ний. Некоторые базы данных используются одним человеком, другие — группой людей, а третьи — большими организациями. В табл. 1.2 показаны некоторые характеристики этих разных типов баз данных. Подобно всем информационным системам, системы баз данных разрабатыва- ются в течение трех фаз: формулирования требований, проектирования и реали- зации. Во время фазы формулирования требований разрабатывается модель данных, или логическое представление структуры базы данных. Модели данных важны, потому что от них зависит проектирование базы данных и приложения. Диаграмма сущность—связь — средство, используемое для представления моде- ли данных. Модель данных преобразуется в таблицы и связи на фазе проектирования. Также проектируются индексы, ограничения, хранимые процедуры и триггеры. Диаграммы структур данных иногда используются для таблиц документов и их связей. Во время фазы реализации создаются таблицы, связи и ограничения, пишутся хранимые процедуры и триггеры, база данных заполняется данными в тестируется. Сегодня таблицы и связанные с ними конструкции создаются с по- мощыо SQL пли графических средств, являющихся частью СУБД. Разработка приложения идет параллельно с разработкой базы данных. Боль- шая часть этой книги посвящена разработке базы данных, но проектирование 11 построение запросов и создание кода приложения также будут рассматриваться в последующих главах. Существенные события в истории обработки баз данных показаны в табл. 5. Вопросы группы I I Почему обработка баз данных сегодня важнее, чем раньше? 2- Сформулируйте цель базы данных. 3, Перечислите проблемы, которые могут возникать при использовании спис- ков для учета чего-либо. 4 Основываясь на вашем ответе на вопрос 3, скажите, когда, по вашему мне- Н1|ю, можно использовать списки для учета чего-либо.
54 Глава! Введение в базы данных При отнете и» «опросы 5-9 иепОЛИуП™ НаучРуховоди.оль Тол1^учу^_Д ^*0HC ,?о_44 44 Штайн инф технологии Мм> КееЙ\ 281-39-44 Джонсон бухучет Грим Розенблюм 281 39-44 Гонзалес бухучет Грин РОЗенблЮМ 201-ЛЭ чч Джонс 221-23-45 РИКИ бухучет Грим 5. Опишите проблемы, которые могут возникнуть, когда научный руководи- тель меняет свой номер телефона. 6. Предположим, студент Штайн бросил учебу, и вторая строка удаляется. Опишите побочные эффекты от этого удаления. 7. Как можно использовать этот список для записи того факта, что Смит - заведующий кафедрой компьютерных наук? 8. Предположим, что в последней строке значение последнего столбца изме- нилось с Грин на Абернати. Какие проблемы возникнут при интерпрета- ции этого списка? 9. Переделайте этот список в набор из трех взаимосвязанных таблиц. Для представления связей используйте прием, показанный на рис 1.3. 10. Объясните, почему ни одна из проблем, описанных в вопросах 5-8, не мо- жет возникнуть в таблицах, которые вы построили при ответе на вопрос 9. И. Используя в качестве примера оператор SQL, показанный в разделе «Объ- единение таблиц», составьте подобный оператор для объединения таблиц, которые вы построили при ответе на вопрос 9. Если в каком-нибудь из имен столбцов есть пробелы, поставьте имена столбцов в квадратные скоб- ки [ ]. Поскольку в вашем результате нет вычислений, вам не понадобится выражение типа [Daily Rate]*[Days] As Charge. 12. Назовите четыре компонента системы базы данных. 13. Перечислите функции приложения базы данных. 14. Для чего предназначена СУБД? Перечислите ее функции. 15. Определите термин база данных. 16. Перечислите содержимое базы данных. 17. Чю 1акое метаданные? Приведите пример. 18. В чем разница между хранимой процедурой и триггером? бочейСг1дщтТЗЛИЧИЯ Между слеДУющими базами данных: личной, для ра- оочеи группы и организационной. мы базывданных ^ормулирован11Я требований при разработке систе- 21. Что такое модель данных? п„чему такие модел„ ,!ажны? 22. Назовите задан»фдзь. проект,,ром,™ „р„ разработкебазы ........
Вопросы группы II 23 Назовите задачи фазы реализации при разработке системы базы данных. 24. Назовите две модели данных, которые предшествовали реляционной модели 25. Опишите недостатки двух моделей, о которых идет речь в предыдущем вопросе. 26. Кто первый предложил реляционную модель? 27. Как персональные СУБД повлияли на организационные СУБД? 28. Назовите три ранних персональных СУБД. 29. Какова цель ООСУБД? 30. Почему ООСУБД не имеют коммерческого успеха? 31. Что такое объектно-реляционная СУБД? 32. Какая технология сейчас на переднем крае в области баз данных? Вопросы группы II 33. Предположим, что Новоорлеанское товарищество деревянных лодок (фик- тивная организация) публикует ежемесячный бюллетень, на который оно тратит 35 долларов в год. Пусть для рассылки этих бюллетеней товарище- ство хранит следующие данные в виде списка: Имя, Улица, НомерДома, Город, Штат, Индекс, НачДата, КонДата, СуммСтоимость. Какие проблемы могут возникнуть при хранении данных в таком списке? 34. Предположим, что подписчик этого бюллетеня на три года изменил свой адрес. Нужно ли изменять адресные данные для всей подписки, или толь- ко для текущей? Почему? 35. Разбейте список из вопроса 33 на две таблицы — ПОДПИСЧИК и ПОДПИСКА. Постройте связи между таблицами, используя в качестве примера рис. 1.3. Как такое расположение может исправить проблемы, которые вы нашли, отвечая на вопрос 33? Как оно влияет на ваш ответ на вопрос 34? 3G. Предположим, что товарищество решило опубликовать два издания: еже- квартальный путеводитель (зима, весна, лето и осень) и ежемесячное новостное издание. Предположим, что стоимость путеводителя — 15 дат- ларов в год, а новостного издания — 35 долларов в год. Пусть для этой подписки общество хранит следующие данные: Имя, Улица, НомерДома, Город, Штат, Индекс, Издание, НачДата, КонДата, Сумм- Стоимость. Какие проблемы могут возникнуть при хранении этих данных в виде списка? 37> Разбейте список из вопроса 36 на две таблицы: ПОДПИСЧИК и ПОДПИСКА. Постройте свя ш между таблицами, используя в качестве примера рис. 1.3. Как такси* расположение может исправить проблемы, которые вы наш ти, отвечая на вопрос 36? Объясните, почему такое двухтабличное располо- жение лучше, чем одна таблица.
56 Глава 1. Введение в базы данных________ 3S Предположим, что стоимость путеводителя 15 долларов В ошхт- лого издания — 35 долларов в юд, no стоимость обоих издании сразу •” 40 долларов в год. Повлияет ли это обсоятельство на проекторов; не таблиц для вопроса 37? Почему? Как товарищество должно действовать в этой ситуации? 39 Практически любой член товарищества, имеющий компью ери е и ’ кп, может создавать и обрабатывать список. Однако разработка базы дан- ных п приложения базы данных уже требует специализиро и умений. Если бы товарищество попросило вас помочь определить, оку- пятся ли затраты на базу данных, как бы вы рассуждали? Какие вопросы вы бы задали? Какой анализ вы бы провели? Вопросы к проекту FiredUp FiredUp, Inc. — небольшая компания, владельцами которой являются Керт и Джу- ли Роубердс. Эта компания, находящаяся в Брисбейне, Австралия, производит и продает легкие походные горелки под названием FiredNow. Керт, работавший раньше аэрокосмическим инженером, изобрел и запатентовал сопло, которое не дает огню в горелке погаснуть даже при очень сильном ветре — до 90 миль в час. Джули, промышленный дизайнер по образованию, разработала элегантную склад- ную конструкцию, которая имеет небольшой вес и габариты, проста в установке и весьма устойчива. Семья Роубердс производит горелки в своем гараже и прода- ет клиентам напрямую, принимая заказы через Интернет, по факсу и по почте. Владельцы FiredUp хотели бы отслеживать проданные горелки на тот случай, если им понадобится войти в контакт с покупателями относительно дефектов в изделиях и по другим вопросам, связанным с качеством изделий. Соответ- ственно, они ввели форму регистрации продукта для каждой из горелок. Форма содержит следующие данные: ИняПокупателя, Улица. НомерДома, Город, Штат, Индекс, Страна, НомерТелефона, ДатаПокупки, СерийныйНомер ♦ Предположим, фирма FiredUp хранит свои данные в списке. Опишите пять потенциальных проблем, которые у нее могут возникнуть при этом. ♦ Предположим, что вместо списка они решили создать персональную базу данных со следующими таблицами: КЛИЕНТ (Имя, Улица, Дом, Квартира, Город Штат, ПочтовыйИндекс, Страна, ЭлектронныйАдрес, Телефон) и ПОКУПКА (Дата- Покупки, СерийныйНомер) 1. Создай ге таблицу с данными, структура которой будет соответствовать таб- лице КЛИЕНТ. В таблице должно быть по меньшей мере четыре строки. (Для отета на вопросы 1-7 достаточно ввести данные в текстовом редакторе.) 2. Какой из столбцов таблицы КЛИЕНТ можно использовать для однозначной идентификации строки в таблице? Такой столбец иногда называется пер- вичным ключом, как вы позже узнаете из этой книги. 3. Создайте iаблицу с данными, структура которой будет соответствовать та шице ПОКУПКА. В таблице должно быть по меньшей мерс четыре строки
Вопросы к проекту Twiqb Tree 57 4. Какой из столбцов таблицы ПОКУПКА можно использовать в качестве пер- вичного ключа для этой таблицы? 5. Имея определенные выше таблицы, невозможно связать конкретного по- купателя с его горелкой. Один из способов сделать это — добавить столбец СерийныйНомер из таблицы ПОКУПКА в таблицу КЛИЕНТ. После этого табли- ца КЛИЕНТ будет выглядеть следующим образом: КЛИЕНТ (Имя, Улица, Дом, Квартира, Город, Штат, ПочтовыйИндекс, Страна, ЭлектронныйАдрес, Телефон). Скопируйте данные из таблицы КЛИЕНТ и добавьте к ним столбец Серий- ныйНомер. Назовите получившуюся таблицу КЛИЕНТ1. 6. Связь двух таблиц можно представить и по-другому: поместить столбец ЭлектронныйАдрес из таблицы КЛИЕНТ в таблицу ПОКУПКА. После этого таб- лица ПОКУПКА будет выглядеть следующим образом: ПОКУПКА (ДатаПокупки, СерийныйНомер, ЭлектронныйАдрес). Скопируйте данные из таблицы ПОКУПКА и добавьте к ним столбец ЭлектронныйАдрес из таблицы КЛИЕНТ. Назовите получившуюся таблицу ПОКУПКА1. 7 Теперь у вас имеются три возможные структуры: КЛИЕНТ1+ПОКУПКА, КЛИЕНТ+ПОКУПКА1 и КЛИЕНТ1+ПОКУПКА1. При каких условиях вы могли бы рекомендовать первую структуру? Вторую структуру? Третью структуру? Вопросы к проекту Twigs Tree Саман га Грин владеет и управляет фирмой Twigs Tree. Она закончила лесоводче- ские курсы и работала в большой фирме по ландшафтному дизайну, которая за- нималась подрезкой деревьев. Чс рез несколько лет она купила грузовик, машину Для корчевания иней и другое оборудование и затем открыла в Сент-Луисе, штат Миссури, собственное дело. Хотя большинство выполняемых ею заказов представляют собой одноразовые операции по спиливанию дерева или корчеванию пня, есть и повторяющиеся — например, подрезка деревьев каждый год или раз в два года Когда дело идет медленно, она звонит старым клиентам, чтобы напомнить им о себе и о необхо- димости произвести очередное подрезание деревьев. Саманта хранит о своих заказах следующие данные: ИмяКлиента, Телефон, Ули- ца, Город, Штат, Индекс, ДатаОбслуживания, Описание, Затраты, Плата, ДатаПлатежа. ♦ Предположим, Саманта хранит свои данные в виде списка. Опишите пять потенциальных проблем, с которыми она может при этом столкнуться. ♦ Допустим, Саманта решила вместо списка создать персональную базу дан ных со следующими таблицами. КЛИЕНТ (Имя, Телефон, Улица, Город, Штат, Индекс) и ЗАКАЗ (ДатаОбслуживания, Описание, Затраты, Плата, ДатаПлатежа). 1 Постройте таблицу, заполнив ее данными, соответствующими структуре таблицы КЛИЕНТ. В таблице должно быть по меныпей мере четыре ст|юки (Для ответа на первые вопросы достаточно ввести данные в текстовом ре- дакторе )
58 Глава 1 Введение в базы данных 2 Какой из столбцов таблицы КЛИЕНТ можно использовать для однозначной идентификации строки в таблице (то есп> в качестве ключа)? 3. Постройте таблицу данных, которая соответствует структуре ЗАКАЗ В ней должно быть по меньшей мере четыре строки. 4. Объясните, почему ни один из столбцов таблицы ЗАКАЗ нельзя использо- вать в качестве ключа. 5. Добавьте в таблицу КЛИЕНТ столбец идентификатора, как к таблицам на рис. 1.3. Дополните соответствующим образом ваши данные. 6. Имея определенные выше таблицы, невозможно связать конкретного кли- ента с его заказом. Один из способов сделать это — добавить столбец иден- тификатора из таблицы ЗАКАЗ в таблицу КЛИЕНТ. Таблица КЛИЕНТ при этом будет содержать следующее: КЛИЕНТ (Имя, Телефон, Улица, Город, Штат, Индекс, ИдентЗаказа). Скопируйте ваши данные из таблицы КЛИЕНТ и добавьте к ним ИдентЗака- за. Назовите новую таблицу КЛИЕНТ1. 7. Еще один способ создать связь между таблицами — поместить столбец Те- лефон из таблицы КЛИЕНТ в таблицу ЗАКАЗ. При этом таблица ЗАКАЗ будет выглядеть так: ЗАКАЗ (ДатаОбслуживания, Описание, Затраты, Плата, ДатаПлате- жа, Телефон). Скопируйте ваши данные из таблицы ЗАКАЗ и добавьте к ним Телефон. На- зовите новую таблицу 3AKA31. 8. Теперь у вас есть три возможных структуры базы данных: КЛИЕНТ1+ЗАКАЗ, КЛИЕНТ+ЗАКА31 и КЛИЕНТ1+ЗАКА31. При каких условиях вы могли бы реко- мендовать первую структуру? Вторую структуру? Третью структуру?
Часть I Модель данных «сущность—связь» В двух главах, составляющих первую часть книги, описываются и иллюстриру- ются на примерах методы, средства и процессы моделирования данных. В главе 2 происходит первое знакомство с моделью данных «сущность—связь» и рассматри- ваются несколько вариантов этой модели, с которыми читатель вероятнее всего может столкнуться в ходе практической деятельности. Здесь же описываются ком- поненты, входящие в состав средств моделирования данных. В главе 3 излагаются в общих чертах и демонстрируются на многочисленных примерах процессы моде- лирования данных с использованием инструментария, представленного в главе 2. Лучший способ научиться моделированию данных — это практика, и мы на- стоятельно рекомендуем вам не обходить вниманием задачи и примеры, приве- денные в конце каждой главы. Еще больше полезных знаний и навыков вы смо- жете приобрести, если обзаведетесь каким-нибудь программным продуктом для моделщювания данных и будете использовать его для создания собственных мо- делей. О том, как это сделать, можно прочесть в главе 2.
Глава 2 Модель «сущность—связь»: методы и средства моделирования В настоящей главе рассматриваются методы и средства моделирования данных. Вначале дается описание тройственной схематической модели AN. I PARC С помощью этой модели разъясняются роль и место моделирования данных в про- цессе проектирования баз данных. Далее описывается модель «сущность-связь» в том виде, как она изначально была предложена. Как вы далее увидите, есть существенные соображения в пользу того, чтобы изучать эту модель именно в такой форме. Затем рассматривается более новая версия модели «сущность—связь» — модель IDEFX1, получившая наибольшее распространение в современной про- мышленности. В завершение главы вы узнаете, как модель «сущность—связь» была встроена в UML — технологию объектно-ориентированного программиро- вания. Усвоив описанные здесь модели и средства, в следующей главе вы сможете приступить к их практическому применению. Тройственная схематическая модель ANSI/SPARC Тройственная схематическая модель базы данных ANSI/SPARC, предложенная Комитетом по планированию и разработке требовании к стандартам (Standards Planning and Requirements Committee, SPARC) Американского национального института стандартов (American National Standards Institute, ANSI), была пер- вые опубликована в 1975 году. Несмотря на то, что эта модель уже довольно шара, с ее помощью исключительно удобно описывать роль и цели моделирова- ния данных. ачнем с определения схемы. Схема (schema) — это представление чего-либо, римерами схем могут служить чертежи здания, блок-схема алгоритма или объектная диаграмма. Три схемы, составляющие рассматриваемую нами модель, определяют три различных представления базы данных.
Тройственная схематическвя модель ANSI/SPARC 61 Внешняя, концептуальная и внутренняя схемы Модель ANSI/SPARC включает в себя три схемы — внешнюю, концептуальнуюи внутреннюю (рис. 2.1). Внешняя схема (external schema), называемая также поль- зовательским представлением (user view), описывает то, как пользователи пред- ставляют себе базу данных. Для всех баз данных, кроме простейших, внешняя схема отображает лишь часть реальной базы данных. Например, если вернуться к примеру с фирмой Lakeview, приведенному в главе 1, то с точки зрения торго- вых агентов внешняя схема базы данных содержала бы данные только из таблиц CONTRACTOR и RENTAL. Пользователи Рис. 2.1. Тройственная схематическая модель Концептуальная схема (conceptual schema) — это полное логическое представ- ление базы данных, включающее описание всех данных и связей между ними. С' юва «лшическос представление» имеют тот смысл, что концептуальная схема не aamiiui от конкретною способа хранения данных. Хранить концептуальную ' хему можно в базе данных, в файловом архиве, в виде набора связанных между собой э юкцюпных таблиц и другими способами. Одной концептуальной схеме обычно соответствует множество различных ’’Певших схем У фирмы Lakeview может быть одна внешняя схема для торговых агентов, ip\iая — для отдела маркетинга, третья — для бухгалтерии, и т. д. Внутренняя схема (internal schema) — это представление, описывающее фи- зическую реализацию концептуальной схемы с использованием конкретного ’’Ротукга и или технологии Описание набора таблиц, ключей, внешних ключей, ”н тексов и других физических структур представляет собой внутреннюю схему. °1и.т н та же концептуальная схема может быть представлена различными впут- Рснними схемами например, одна из них может быть тля Oracle, другая — для Эти две внутренние схемы могут быть очень похожими или совершенно Различными Для нас эти различия несущественны, лишь бы обе они алекват Мо отражали соответствующую концептуальную схеме (Ра имеется, если вести об эффективности обработки, одна внутренняя схема может иметь огром- преимущество ис|>ед другой )
62 гппвя 2. Модель «сущность-связы^мотодыи сре;щгвамоДОлирований Построение концептуальной схемы Почему все это так важно? Наша задача при создании модели данных состоит построить концептуальную схему. Однако пользователи не будут го- ворить с нами на языке этой схемы. Пользователи . оворят о данных с точки эре ния своей работы, то есть своего собственного представления (внешней схемы) дшХ Нашей же целью будет, взяв за отправную точку все эти внешние схемы, построить единую концептуальную схему, которая бы поддерживала каждое из заданных нам на входе пользовательских представлении. Не менее важно при создании концептуальной схемы четко отличать ее от внутренней схемы. Не следует смешивать физическое представление данных с. их логическим представлением. В противном случае мы придем к тому, что ха- рактеристики СУБД будут ограничивать и искажать наше видение концептуаль- ной модели. Из-за этого мы можем упустить из виду какой-то важный аспект в мире пользователей или, что еще хуже, позволить СУБД ограничивать свободу действий пользователей. Такого рода ограничения подобны хвосту, который ви- ляет собакой. Не хотелось бы, чтобы характеристики индексов СУБД определя- ли то, как торговые агенты должны осуществлять продажи! Разумеется, разработав концептуальную схему, мы вскоре можем обнару- жить, что нам придется так или иначе от нее отступить, дабы обеспечить ее эффективную реализацию во внутренней схеме. Но прежде чем мы приступим к модификации схемы, у нас, по крайней мере, будут зафиксированные в доку- ментальной форме требования пользователей, и мы будем идти на компромисс сознательно. Может статься, что потом, в результате более тщательного обдумы- вания или из накопленного опыта, нам все-таки удастся найти способ реализо- вать ту концептуальную схему, которая нужна пользователям. А может быть, это станет возможным благодаря новому продукту или новым возможностям уже существующего продукта. Поэтому, создавая концептуальные модели, старайтесь абстрагироваться от физических структур и элементов внутренней схемы. Вместо этого направьте своп усилия па то, чтобы предоставить пользователям нужные им внешние схе- мы, с помощью которых они могли бы успешно выполнять свою работу. За прошедшие годы было разработано огромное количество разнообразных методов, концепций и символьных систем для документирования концепту- । >ix моделей. Наиболее популярные из них базируются на модели «сущ- ность связь» — их л1ы и рассмотрим в этой и следующих главах. Альтернатпв- тпДНт10Д’ НОСЯ1ЦИИ пазвание семантической объектной модели (semantic object model), описывается в приложении Б. Сага о Брюсе и Зельде модшш^ассмо^ЯДН° проде“онстРиР°вать суть тройственной схематической изучением пек он'С РЮС0М ” Зельдой- Брюс — биолог, занимающийся хлорида бифенипа <РСтУСГ 3агряЗНенпе воды 11 берет пробы на наличие поли- I Да бифенила (РСВ) и других химических веществ. Несколько раз в году он
Тройственная схематическая модель ANSI/SPARC вВ объезжает реки и подсчитывает количество рыбы в них, так как эта статисти. счужит важным показателем благополучия речной среды. Результаты своя* исследований он заносит в специальную форму (рис 2.2), содержащую дайны* о реке и таблицу для записи количества рыбы. Рис. 2.2. Внешняя схема Брюса Зельда, зоолог, занимается изучением рыбы. Основываясь на полученных ею данных, агентства отдельных штатов и федерального уровня определяют квоты на ловлю рыбы, налагают запрет на вылов определенных пород и оценивают со- стояние здоровья различных видов рыбы. Для записи своих результатов Зельда также использует специальную форму (рис. 2.3). Она выбирает интересующий ее вид рыбы и заносит в таблицу данные по каждой реке, где встречает этот вид. Рис. 2.3. Внешняя схема Зельды
64 rn.Pa Z Модель «сущность-связь»: методы и <WWW Брюс и Зельда работают в одном унмверспгете, и однажды! пиверситет рч ет создать единую базу данных, в которой содержалась бы вся информации о р бе и реках Первым шагом в этом деле, как известно, является иш ервыоироьзиие пользователей, и вот некто назначает встречу с фюгом и Зельдои Встреча происходит приблизительно так. Начинает ра.ясвор Зельда. «Брюс, я посмотрела, как ты записываешь свои результаты (см. рис. 2.2) У тебя же все вывернуто наизнанку! Сперва нужно выбрать интересующую нас породу рыбы, а потом занести в таблицу данные о количестве экземпляров данной породы раз- личных реках». Брюс возражает: «Боюсь, Зельда, что формальдегид от твоих рыб ударилтебе в голову. Так никто не делает. Сначала надо выбрать определенную реку, а по- том для данной конкретной реки записать статистику по всем породам рыбы, ко- торые мы в ней обнаружим. Если бы я записывал свои данные так же, как это де- лаешь ты (см. рис. 2.3), это бы заняло у меня часы!» Однако Зельда не сдается: «Напротив, Брюс, это твои мыслительные способ- ности, похоже, пострадали от слишком большой дозы PC В. Если мы будем за- писывать результаты так, как предлагаешь ты...». Далее дебаты продолжаются в том же духе, и каждая из сторон доказывает, что именно ее способ записи явля- ется правильным. Хотите верьте, хотите нет, но на подобные споры были потра- чены тысячи, если не миллионы часов. Проблема, разумеется, состоит в том, что Брюс, и Зельда смотрят на одни и те же данные с совершенно разных позиций. При разговоре Брюса и Зельды присутствует концептуализатор Конрад. Взгля- нув на формы, представленные на рис. 2.2 и 2.3, он говорит себе: «Эти формы - не что иное, как взгляд на одни и те же данные с двух различных точек зрения, то есть две внешние схемы. Нельзя ли объединить их в одной концептуальной схеме?» Конрад приходит к выводу, что это сделать можно, и конструирует концепту- альную схему, показанную на рис. 2.4. Как вы помните, концептуальная схема — это полное логическое представление данных. Она будет содержать множество друшх элементов, помимо тех, что показаны здесь, но пока нам хватит и этого.
Модель «Сущность—связь» и ее варианты 65 Концептуальная схема Конрада (см. рис. 2.4) включает три различных труп- пы данных: РЫБА. РЕКА и НАБЛЮДЕНИЕ. Линии представляют связи между ними Обратите внимание, что с одной рекой потенциально может быть связано много наблюдений. То же самое справедливо и для рыбы. Теперь, если следовать подходу Брюса, мы сперва выбираем нужную нам ре- ку в группе РЕКА, затем в группе НАБЛЮДЕНИЕ находим записи обо всех наблюде- ниях, сделанных на данной реке, и из этих наблюдений получаем данные о коли- честве рыбы различных видов. Если потребуются какие-то дополнительные сведения о рыбе, помимо названия вида (столбцы Рыба и Название вида), мы возь- мем их из группы РЫБА. С точки же зрения Зельды, мы сначала выбираем интере- сующий нас вид рыбы в группе РЫБА, затем в группе НАБЛЮДЕНИЕ находим записи обо всех наблюдениях, где фигурирует данный вид, и из этих записей извлекаем название реки. Дополнительные сведения о реках, помимо их названий (столбцы Река и Название реки), можно взять из группы РЕКА. Концептуальная схема, изображенная на рис. 2.4, хороша для данного приме- ра, однако для построения реальной базы данных необходимо гораздо больше подробностей. Далее в этой главе мы рассмотрим методы и средства, которые ис- пользуются для представления таких концептуальных схем при проектировании реальных баз данных. Но прежде мы доведем до конца нашу историю. Конрад передаст свою кон- цептуальную схему Оливии — специалисту по Oracle. Оливия, исходя из схемы Конрада, создаст внутреннюю схему, или проект базы данных, для СУБД Oracle. Она спроектирует таблицы, определит ключи и внешние ключи, создаст индек- сы, выделит пространство под таблицы па физических носителях и примет ряд Других решений относительно структуры внутренней схемы. Затем она физически реализует созданную схему в виде базы данных и сопутствующих ей структур. Процесс проектирования и реализации описывается нами в главах 4, 5, 8,10 и И. Модель «сущность—связь» и ее варианты Модель «сущность—связь» (entity-relationship model, E-R model) представляет собой совокупность понятий и графических символов для пост роения концепту- альных схем. Модель «сущность—связь» была предложена Питером Ченом и опуб- ликована им в 1976 году. В своей статье Чен описал основные элементы модели. Позже к этой модели были добавлены подтипы (речь о которых пойдет далее). Результатом чего стала расширенная модель «сущность—связь» (extended E-R wodel). На сегодняшний день, как правило, когда говорят о модели «сущность— связь», имеют в виду именно расширенный ее вариант. Версии модели «сущность—связь» Идеи, лежащие в основе расширенной модели «сущность—связь», были взяты на ВооРУЖение широким кругом профессионалов в области моделировав ня данных и проектирования баз данных, и сегодня почти все проекты по моделированию
66 Глава 2 Модель «сущность-связь, методы и средства мц данных используют ту или ннх^^Хшдя назваХ (information гадш.-гШй. IE), была ра.рабоган. Дж^м™, Май™ “о“ п 1990 Опа ми.м1Ю «... рагпроггр»...-... » «шремяжой »|». мышленности. и мы не будем рассматривать се далее . В 993 году Национальный институт стандартен, и технологии (National Institute of Standards and Technology) анонсировал еще одну версию модели «сущность-связь» в качестве национального стандарта Ш иная я ,х Л получила название IDEF1X. что расшифровывается как «Integrated Def.n.twn 1, Extended» - «Единый стандарт, версия 1, расширенная». Этот стандарт включает в себя основные идеи модели «сущность-связь», но использует для их представ- ления другие графические символы. В стандарте IDEF1X предусмотрены сред- ства для разработки как концептуальных, так и внутренних схем, а также методы преобразования первых во вторые. На этом, однако, путаница не кончается. Новая объектно-ориентированная модель разработки под названием UML (Universal Modeling Language - универ- сальный язык моделирования) также взяла за основу модель «сущность—связь», но при этом ввела свои собственные символы и привнесла объектно-ориентиро- ванную специфику. В конечном счете мы имеем исходную модель «сущность—связь», расширен- ную модель «сущность—связь», информационную инженерию, национальный стандарт IDEF1X и UML. Эту ситуацию можно заклеймить как абсурдную (тако- вой она в действительности и является), однако тем самым мы не сможем в ней ничего изменить. Вопрос звучит так: что мы со всем этим будем делать? Выбор версии модели Проще всего было бы вскинуть руки и сказать: «Чем связываться со всеми этими версиями, давайте лучше сосредоточимся на расширенной модели „сущность- связь", а остальные версии рассмотрим потом, если понадобится». Проблема за- ключается в том, что когда модель IDEF1X стала национальным стандартом, компании, занимавшиеся разработкой средств для моделирования данных, были вынуждены обеспечить соответствие своих продуктов этому стандарту, чтобы иметь возможность продавать их правительственным учреждениям. Игнориро- вать такой большой рынок было бы непростительно, поэтому большинство попу- лярных в настоящее время программных продуктов для моделирования данных, иащ^мер, ERWin и Visio, используют IDEF1X. А это значит, что именно с верси- ей 1DEF1X вам, вероятнее всего, придется сталкиваться в вашей практике, и даже чаще, чем с расширенной моделью «сущность—связь», В то же время, растущая популярность объектно-ориентированной системной разра отки и объектно-ориентированного программирования дала толчок рас- пространению ML. Однако изначально UML предназначался в первую очередь для моделирования процессов и программ, и, по мнению многих, он пока не го- тов к использованию в качестве полноценного средства моделирования данных, олжно пройти еще какое-то время, прежде чем UML достигнет той стадии эре-
Расширенная модель «сущность—связь» 67 пости, па которой находятся модель 1DEF1X и информационная инженерия Кроме того, если вы не знакомы с концепциями обьекгно ориентированного программирования, UML может оставить у вас странное впечатление. По правде говоря, какое бы решение мы ни приняли в .ной ситуации, оно все равно будет неудовлетворительным. Тем нс менее, наш подход будет таков ша- ппе классической расширенной модели «сущность- связь» необходимо, потому что содержащиеся в пей идеи и символы лежат в основе всех без исключения версий, а также потому, что данная модель столь широко распространена в про- мышленности. К несчастью, без знания модели 1DEF1X также не обойтись, по- скольку вам наверняка придется работать со средствами моделирования данных, а они по большей части следуют именно этой версии. Ну и, наконец, следует по крайней мере ориентироваться в символах, используемых в UML. Исходя из вышесказанного, структура этой главы будет такова. Сначала будет описана расширенная модель «сущность—связь» в ее классическом варианте. Далее мы представим версию IDEF1X, которая не только использует другие сим- волы, но и по-другому классифицирует связи. В заключительном разделе главы будет вкратце рассмотрено использование модели «сущность—связь» в UML. В оставшейся части книга будет использоваться либо расширенная модель «сущность—связь», либо стандарт IDEF1X. Хотя временами это будет затруд- нять изложение, мы не видим другого способа хорошо подготовить вас к реше- нию задач, с которыми вы можете столкнуться в ходе вашей будущей карьеры. Расширенная модель «сущность—связь» Ключевыми элементами модели «сущность—связь» являются сущности, атрибу- ты, идентификаторы и связи. Рассмотрим каждый из них по очереди. Сущности Сущность (entity) — это некоторый объект, идентифицируемый в рабочей среде пользователя, нечто такое, за чем пользователь хотел бы наблюдать. Примера- ми сущностей могут служить СОТРУДНИК Мэри Доу, КЛИЕНТ 12345, ЗАКАЗ 1000, ПРОДАВЕЦ Джон Смит или ПРОДУКТ А4200. Сущности одного и того же типа группи- руются в классы сущностей (entity classes). Так, класс сущностей СОТРУДНИК явля- ется совокупностью всех сущностей СОТРУДНИК. В тексте книги классы сущно- стей обозначаются заглавными буквами. Важно уяснить разницу между классом сущностей и экземпляром сущности. 'асе сущностей — это совокупность однотипных сущностей, и описывается он структурой или форматом сущностей, его составляющих. Экземпляр сущности ()Cnt,ty “’Stance) представляет конкретную сущность, такую как КЛИЕНТ 12345; он ^исывается значениями атрибутов данной сущности. Обычно класс сущностей Держит множество экземпляров сущности. Например, класс КЛИЕНТ содержит
68 Глава 2 Модель «сущность—-связь» методу и йЭбд< im множество экземпляров — но одному ид каждого клиента, о запись в базе данных. Пример класса сущностей и двух »кземиляров < показан па рис. 2.5. Рис. 2.5. КЛИЕНТ; пример сущности Атрибуты У сущностей есть атрибуты (attributes), или, как их иногда называют, с< (properties), которые описывают характеристики сущности. Примерами атрибу- тов могут служить ИмяСотрудника, ДатаНайма и КодКвалификации. В тексте этой книги для записи имен атрибутов используются как прописные, так и строчные буквы. В модели «сущность—связь» предполагается, что все экземпляры данного класса сущностей имеют одинаковые атрибуты. Исходное определение модели «сущность—связь» включает в себя коэшо- зитные атрибуты (composite attributes) и многозначные атрибуты (multi-valued attributes). В качестве примера композитного атрибута можно привести атрибут Адрес, состоящий из группы атрибутов {Улица, Город, Штат. Индекс}. Примером многозначного атрибута может служить атрибут ДоверенноеЛицо сущности КЛИЕНТ, который может содержать имена нескольких доверенных лиц данного клиента Атрибут может быть одновременно и композитным, и многозначным — нап мер, композитный атрибут Телефон, состоящий из группы атрибутов {КодРе МестныйНомер}, будучи многозначным, позволяет иметь в базе данных нес ко телефонных номеров одного и того же лица. В большинстве версий м «сущность—связь» однозначные композитные атрибуты игнорируются, и '
Расширенная модель «сущность—связь» ется, чтобы многозначные атрибуты (будь они составные ИЛИ чет) иреобразовы вались в сущности, как будет показано ниже. Идентификаторы Экземпляры сущностей имеют идентификаторы (identifiers) — атрибуты, с по мощыо которых эти экземпляры именуются, или идентифицируются. Например, экземпляры сущностей класса СОТРУДНИК могут идентифицироваться по атри- бутам НомерСоциальнойСтраховки, ТабельныйНомерСотрудника или ИмяСотрудника. Такие атрибуты, как Зарплата или ДатаНайма, вряд ли могут служить идентифика- торами экземпляров сущностей класса СОТРУДНИК, поскольку обычно эти атри- буты не способны однозначно указать на конкретного сотрудника. Точно так же сущности класса КЛИЕНТ могут идентифицироваться по атрибутам НомерКлиента или ИмяКлиента, а сущности класса ЗАКАЗ могут идентифицироваться по атрибуту НомерЗаказа. Идентификатор экземпляра сущности состоит из одного или более атрибутов сущности. Идентификатор может быть уникальным (unique) либо неуиикальчым (nonunique). Если идентификатор является уникальным, его значение будет указы- вай. на один и только один экземпляр сущности. Если идентификатор является неуинкальным, его значение будет указывать па некоторое множество экземпляров. ТабельныйНомер является, скорее всего, уникальным идентификатором, а ИмяСо- грудника — неуинкальным (например, может быть несколько сотрудников по имени Джон Смит) Идентификаторы, состоящие из нескольких атрибутов, называются компо- зитными идентификаторами (composite identifiers). Примерами могут служить идентификаторы вида {КодРегиона, МестныйНомер}, {НазваниеПроекта, НазваниеЗа- дачи} и {Имя, Фамилия, ДобавочныйНомерТелефона}. Связи Взаимоотношения сущностей выражаются связями (relationships). Модель «сущ- ность-связь» включает в себя классы связей п экземпляры связей1. Классы свя- зей (relationship classes) выражают взаимоотношения между классами сущностей, а экземпляры связи (relationship instances) — взаимоотношения между экземпля- рамп сущностей. У связей могут быть атрибуты. Класс связей может соединять несколько классов сущностей. Число классов 'УЩностей, участвующих в связи, называется степенью связи (relationship degree). Изображенная на рис. 2.6. а связь ПРОДАВЕЦ—ЗАКАЗ имеет степень 2, поскольку в ней участвуют два класса сущностей — ПРОДАВЕЦ и ЗАКАЗ. Связь РОДИТЕЛЬ на OTFi 2 6’ ' имсет степень 3-так как в ней участвуют три класса сущностей — МАТЬ, Ч и РЕБЕНОК Связи степени 2 весьма распространены, их часто называют еще и,трными связями (binary relationships). 1 Дл1 очи!^”*”™ мы С>дем и,,огда «пускать слово экзелнияр в тех случаях, когда из контекста будет ндно, что подразумевается именно экземпляр сущности, а не класс сущностей
—- гя«чь. методы и средстве мо, 70 глава 2 Модель «сущность-свя ь------------------- . МАТЬ РЕБЕНОК j ОТЕЦ*) -^редлтЕль ПРОДАВЕЦ—ЗАКАЗ ЗАКАЗ б стопный связей а — связь степени 2,6 — связь степени 3 Рис. 2.6. Различные степени связей, а Три типа бинарных связей На рис. 2.7 °™„™“ap“ тХ На рис. 2.7, а связь СЛУЖЕБНЫЙ-АВТОИОБИЛЬ связывает конкретного сотрудника с конкретным автомобилем. Согласно этой диа. ...у» ни за одним сотрудником не закреплено более одного автомобиля, и ни один ав- томобиль не закреплен более чем за одним сотрудником. СЛУЖЕБНЫЙ_АВТОМОБИЛЬ а ОБЩЕЖИТИЕ—ЖИЛЕЦ б СТУДЕНТ—КЛУБ в Рис. 2.7. Три типа бинарных связей: а — 1:1; б — 1:N; в — N:M На рис. 2.7, б изображен второй тип связи, 1:N («один к N» или «один ко мно- гим»), В этой связи, которая называется ОБЩЕЖИТИЕ—ЖИЛЕЦ, единичный экзем- пляр сущности класса ОБЩЕЖИТИЕ связан со множеством экземпляров сущности класса СТУДЕНТ. В соответствии с этим рисунком, в общежитии проживает много студентов, но каждый студент живет только в одном общежитии. Важна позиция, в которой стоят 1 и N. Единица стоит на той стороне связи, где располагается ОБЩЕЖИТИЕ, a N стоит на той стороне связи, где располагается СТУДЕНТ. Если бы мы поменяли местами 1 и N и записали бы эту связь как N't, получилось бы, что в общежитии проживает всего один студент, причем студент может жить в нескольких общежитиях. Это, разумеется, не так. На рис. 2.7, в показан третий тип бинарной связи. N;M (читается «N к М» мл» «многие ко многим»). Эта связь называется СТУДЕНТ-КЛУБ, и она связывает эскл
Расширенная модель «сущность—связь» 71 пляры сущностей класса СТУДЕНТ с экземплярами сущностей класса КЛУБ. Один студент может быть членом нескольких клубов, а в одном клубе может состоять много студентов. Числа внутри ромба, символизирующего связь, обозначают максимальное ко- личество сущностей на каждой стороне связи. Эти ограничения называются мак- симальными кардинальными числами, а совокупность из двух таких ограничений для обеих сторон связи называется максимальной кардинальностью (maximum cardinality) связи. Например, о связи, изображенной на рис. 2.7, б, говорят, что она обладает максимальной кардинальностью 1:N. Кардинальные числа могут иметь и другие значения, а не только 1 и N. Например, связь между сущностями БАСКЕТБОЛЬНАЯ.КОМАНДА и ИГРОК может иметь кардинальность 1:5, что говорит нам о том, что в баскетбольной команде может быть не более пяти игроков. Связи трех типов, представленных на рис. 2.7, называются иногда связями типа «ИМЕЕТ», или связями принадлежности (HAS-A relationships). Например: сотрудник имеет автомобиль, студент имеет общежитие, клуб имеет студентов. Диаграммы «сущность—связь» Схемы, изображенные на рис. 2.7, называются диаграммами «сущность—связь» (entity-relationship diagrams, ER-diagrams). Как в оригинальной, так и в расширен- ной модели «сущность—связь» классы сущностей обозначаются прямоугольни- ками, связи обозначаются ромбами, а максимальное кардинальное число каждой связи указывается внутри ромба1. Имя сущности указывается внутри прямо- угольника, а имя связи указывается рядом с ромбом. В других версиях модели используются другие символы, как вы увидите позже. Как мы уже говорили, максимальная кардинальность показывает максималь- ное число сущностей, которые могут участвовать в связи. Каково же минималь- ное число таких сущностей, приведенные диаграммы не сообщают. Например, рис. 2.7, б показывает, что студент может проживать максимум в одном обще- житии, однако из него не ясно, обязан ли студент проживать в каком-либо об- щежитии. Для указания минимальной кардинальности (minimum cardinality) существует несколько способов. Одни из них, продемонстрированный на рис. 2.8, заключает- ся в следующем: чтобы показать, что сущность обязана участвовать в связи, на чинию связи помещают перпендикулярную черту, а чтобы показать, что сущность может (но не обязана) участвовать в связи, на линию связи помещают овал. Со- 1Ч " тленно, рис. 2.8 показывает, что сущность ОБЩЕЖИТИЕ должна быть связана как минимум с одной сущностью СТУДЕНТ, однако сущность СТУДЕНТ не обязана мет связь с сущностью ОБЩЕЖИТИЕ. Полный набор накладываемых на связь ограничений состоит в том, что ОБЩЕЖИТИЕ имеет минимальное кардинальное щт5Ываемые здесь графические символы, которые берут начало в этой модели, не являются луч- Мас По^°0°| отображения модели в системе с графическим интерфейсом пользователя, подобной ‘ntoeh или Microsoft Windows. Фактически модель «сущность-связь» была разработана задолго *» L'Mi КаК ка|<ая-либо система графического интерфейса приобрела популярность Символы язы- *- которые будут представлены позже в этой главе, легче использовать в графической среде
72 Глява2. Модель сущиосм.-сдзь.: методы и cp««eT»a модепиооции. павное единице, и максимальное кардинальное число. р« «многим. Хост» СТУДЕНТ. СТУДЕНТ имеет минимальное кардинальное число раним ну. Х и максимальное кардинальное число, рапное одному экземпляру сутаж, 3 ОБЩЕЖИТИЕ. [ ОБЩЕЖИТИЕ JO—<l:N>—Н СТУДЕНТ ПРОЖИВАНИЕ Рис. 2.8. Связь с указанной минимальной кардинальностью Может существовать связь между сущностями одного и того же класса. На- пример, для сущностей класса СТУДЕНТ может быть определена связь СОСЕД_ПО_ КОМНАТЕ. Такая связь показана на рис. 2.9, а, а на рис. 2.9, б изображены экземпля- ры сущностей, охваченных этой связью. Связи между сущностями одного и того же класса называются иногда рекурсивными связями (recursive relationships). Рис. 2.9. Рекурсивная связь Изображение атрибутов на диаграммах «сущность-связь» 1псам1°со^иТИЯХ ДИаГРаММ ^У^^ь-связь, атрибуты обозначаются эл- оис 2 10 иными с сущностью или связью, которой они принадлежат На 0Б“,ЕЖ,,™Е " ™ЯЕНТ ” 06ЩЕЖИГиТ-^ЕЦ с имеет атрибуты Название^ УТаМИ‘ Как вндно из Рисунка, сущность ОБЩЕЖИТИЕ СТУДЕНТ имеет атрибуты нХрТтудентГимяГ^6 “ Ko™4ecTBoKoMHaT’ а сущность ЖИЛЕЦ имеет атрибут ПпЯта J У J ’ ИмяСтудента и Курс. Связь ОБЩЕЖИТИЕ- проживание в конкретном общежитииП°КаЗЫВаеТ ВНесенНуЮ «удентом плату за
73 Расширенная модель «сущность—cnw Если сущность имеет много атрибутом, такое их перечисление на диаграмм» может сделать ее чересчур громоздкой и трудной для восприятия В других вер- сиях модели, как вы увидите далее, атрибуты отображаются по-другому Рис. 2.10. Изображение свойств на диаграммах «сущность—связь» Слабые сущности В модели «сущность—связь» определен особый тип сущности, называемый сла- бой сущностью (weak entity). К слабым сущностям относятся такие сущности, которые могут существовать в базе данных только в том случае, если в ней при- сутствует сущность некоторого другого типа. Сущность, не являющаяся слабой, называется сильной сущностью (strong entity). Чтобы разобраться в том, что такое слабые сущности, рассмотрим базу данных отдела кадров с классами сущностей СОТРУДНИК и ПОДЧИНЕННЫЙ. Предположим, существует правило, что экземпляр сущности СОТРУДНИК может существовать не будучи связанным ни с одной сущностью класса ПОДЧИНЕННЫЙ, но сущность ПОДЧИНЕННЫЙ не может существовать вне связи с какой-либо сущностью клас- са СОТРУДНИК. Тогда сущность ПОДЧИНЕННЫЙ является слабой. Это означает, что запись о сущности ПОДЧИНЕННЫЙ может появиться в базе данных только в том случае, если эта сущность имеет связь с какой-либо сущностью класса СОТРУДНИК. Как показано на рис. 2.11, а, слабые сущности обозначаются прямоугольника- ми со скругленными углами. Кроме того, связь, от которой зависит существова- ние сущности, обозначается ромбом со скругленными углами. В некоторых диа- граммах (здесь не показано) прямоугольники для слабых сущностей рисуются Двойной линией, а связи, от которых зависит существование этих сущностей, изображаются двойными ромбами. В модели «сущность—связь» имеется особый тип слабых сущностей, назы- ваемый идентификационно-зависимыми сущностями (ID-dependent entities). Это такие сущности, идентификаторы которых содержат идентификатор другой сущ- ности. Рассмотрим сущности ДОМ и КВАРТИРА. Пусть идентификатором сущно- сти ДОМ является атрибут НазваниеДома, а идентификатором сущности КВАРТИРА является композитный идентификатор {НазваниеДома, НомерКвартиры). Поскольку ‘’верификатор сущности КВАРТИРА содержит в себе идентификатор сущности й М НазваниеДома, то сущность КВАРТИРА является идентификационно-зависи- мой от сущности ДОМ Сравните рис. 2.11, б с рис. 2,11, а. По-другому можно
74 Глава 2. Модель «сущность связь». методы и средства модели представить это таким образом, что как леи ГХеу.№-™,ш,..еея.,,.осу1пое™уСТ очески, так и фи мчески ква|: соответствующее здание СОТРУДНИК Идентификатор: НомерСотрудника 1 N ПОДЧИНЕННЫЙ Идентификатор НомерСоциальнойСтраховки ДОМ 1N КВАРТИРА ] а Идентификатор: НазваниеДома Идентификатор- {НазваниеДома, НомерКвартиры} Рис. 2.11. Слабые сущности: а — идентификационно-независимая, б — идентификационно-зависимая Идентификационно-зависимые сущности встречаются часто. Еще одним приме- ром может служить сущность ВЕРСИЯ в связи с сущностью ПРОДУКТ, где ПРОДУКТ — это некоторый программный продукт, а ВЕРСИЯ номер его версии. Идентифи- катором продукта является атрибут НазваниеПродукта, а идентификатором вер- сии является совокупность {НазваниеПродукта, НомерВерсии}. Третий пример - это связь между сущностями ИЗДАНИЕ и УЧЕБНИК. Идентификатором сущности УЧЕБНИК является атрибут Заглавие, а идентификаторов! издания является сово- купность {Заглавие, ПорядковыйНомерИздания}. К сожалению, в определении термина слабая сущность есть скрытая неодно- значность, и она по-разному интерпретируется в различных версиях модели «сущность—связь» и программных продуктах для моделирования данных. Эта неоднозначность заключается в следующем: в строгом смысле слабая сущность определяется как любая сущность, чье присутствие в базе данных зависит от дру- гой сущности; тогда любая сущность, участвующая в связи минимальной карди- нальности 1 с другой сущностью, является слабой. Таким образом, рассматривая базу данных образовательного учреждения, можно заключить следующее: если у студента должен быть руководитель, то сущность СТУДЕНТ является слабой, поскольку она не может быть записана в базу данных без связи с какой-либо сущностью класса РУКОВОДИТЕЛЬ. Некоторые, однако, считают это толкование чересчур широким. Студент физически не зависит от руководителя (в отличие 01 случая с квартирой и домом), как не зависит от него и логически (что бы по этому поводу ни думали студент и руководитель!), поэтому сущность СТУДЕНТ должна считаться сильной сущностью. нмр^п ГЫ "зЕ)сжа1ь подобных ситуаций, некоторые интерпретируют определе- к па-иЛл011 Су'дности олее ограниченно. Чтобы сущность можно было отнести данномУл^ Х’ °На Д°ЛЖНа Логически зависеть от другой сущности Согласно ?лабьши я даЛеНИЮ;^Х°СТИ П°ДЧИНЕННЫЙ и КВАРТИРА должны считаться слабыми, а сущность СТУДЕНТ - нет. Подчиненный не был бы подчиненным.
Расширенная модель «сущность - еспи бы не находился в подчинении у кого-то, а квартира не может существам» без здания, в котором она могла бы располагаться. Студент же может логически существовать и без руководителя, даже если бизисс-нравила этого не допускают Чтобы проиллюстрировать эту интерпретацию, рассмотрим несколько при- меров. Пусть у нас имеется связь между сущностями ЗАКАЗ и АГЕНТ (рис 2 12, а) Хотя можно было бы потребовать, чтобы для каждого заказа указывался агеН1 его обрабатывающий, в действительности это не всегда необходимо (заказ может быть, к примеру, продажей за наличные, при которой имя агента не записывает- ся). Следовательно, минимальное кардинальное число, равное 1, проистекает из бпзнес-правил, а не из логической необходимости. Таким образом, сущность ЗАКАЗ, хотя и требует наличия сущности АГЕНТ, не зависит от существования последней, поэтому ЗАКАЗ следует рассматривать как сильную сущность. а б [ НАЗНАЧЕНИЕ —Н] ПРОЕКТ | Идентификатор: Идентификатор: {НазваниеПроекта, НазваниеПроакта НаэваниеЗадачи) Рис. 2.12. Примеры обязательных сущностей Теперь рассмотрим связь между сущностями ПАЦИЕНТ и РЕЦЕПТ, изображен- ную на рис. 2.12, 6. Здесь рецепт не может логически существовать без пациента. Следовательно, помимо того, что минимальное кардинальное число сущности РЕЦЕПТ равно 1, эта сущность также зависит от существования сущности ПАЦИЕНТ Отсюда следует, что РЕЦЕПТ — это слабая сущность. Наконец, рассмотрим сущ- ность НАЗНАЧЕНИЕ, изображенную на рис. 2.12, в. Идентификатор этой сущно- сти содержит идентификатор сущности ПРОЕКТ. Здесь, кроме того, что сущность НАЗНАЧЕНИЕ имеет минимальную кардинальность 1 и зависит от существования сущности ПРОЕКТ, она является еще и идентификационно-зависимой от послед- ней, поскольку ее ключ содержит ключ сущности ПРОЕКТ. Таким образом, сущность НАЗНАЧЕНИЕ является слабой. В этой книге мы определяем слабые сущности как логически зависящие от существования другой сущности. Следовательно, не все сущности, имеющие ми- ««мальную кардинальность 1 в связи с другой сущностью, являются слабыми ЗДько логически зависимые сущности квалифицируются нами как слабые. Это но1>еДеЛеПИе также подразумевает, что слабыми являются все идентификацион- зависимые сущности. Кроме того, любая слабая сущность имеет минимальное
76 Глава 2. Модель .сущнос.ь-связь» "Д— i rntnil С CVIlUIOCIblO, от коюрои 34ИИСИ1, ИО П|«и карднналыкх' число в У шпальным чис лом, равным 1, взятая сущностьс минимальным кирдпи.инным ' должна быть слабой. Представление многозначных атрибутов при помощи идентификационно-зависимых сущностей Многозначные атрибуты представляю™ я модели .гущоость-сняг». „уызозд. ™™,o»ii .и.втифика.и.ошю-эаи.,сомой сушина» » ПМЧИОИШ еввзн с М вХодов ко многом.. В качестве промера на рис. 2.13, о "I*" — пение многозначного атрибута ДоверенноеЛицо сущности КЛИЕНТ Создастся и», вая сущность под именем ДОВЕРЕННОЕЛИЦО с единственным атрибутом Довере» ноеЛицо Связь между сущностями ДОВЕРЕННОЕЛИЦО и КЛИЕНТ имеет вид -лил ко многими. Созданная таким образом сущность должна быть идентификацион- но-зависимой, поскольку она должна содержать идентификатор сущности, име- ющей многозначный атрибут. На рис. 2.13, б изображено представление многозначного композитного атри- бута Адрес. Новая слабая сущность АДРЕС содержит всю совокупность атрибутов, а именно атрибуты Улица, Город, Штат и ПочтовыйИндекс. КЛИЕНТ содержит. Номер Клиента прочие атрибуты... КЛИЕНТ ДОВЕРЕННОЕ_ЛИЦО ] ДОВЕРЕННОЕЛИЦО содержит ДоверенноеЛицо а КЛИЕНТ АДРЕС 1:N КЛИЕНТ содержит: НомерКлиента прочие атрибуты . АДРЕС содержит: Улица Город Штат Индекс Рис. 2.13. Представление б многозначных атрибутов с помощью слабых сущностей Подтипы сущностей Некоторые сущности имеют необязательные наборы атрибутов; эти сущности часто представляются с помощью подтипов (subtypes)1. Рассмотрим, например, сущность КЛИЕНТ с атрибутами НомерКлиента, ИмяКлиента и СуммаКОплате. Пред- положим, что клиент может быть физическим лицом, товариществом или корпо- рацией и что необходимо указывать некоторую дополнительную информаинкх зависящую от типа клиента. Пусть эта информация имеет следующее содержаний 1 Подтипы были добавлены в модель «сущность связь» после публикации 6рппша.чыюй статьи 4W*. и они являются частью того, что называется расширенной моделью «сущность-сжик* ’
Расширенная модель «сущность—связь» 77 фИЗИЧЕСКОЕ_ЛИЦО: Адрес, НомерСоциальнойСтраховки ТОВАРИЩЕСТВО: ИмяУправляющегоПартнера, Адрес, ИдентификационныйНалоговыйНомер КОРПОРАЦИЯ: КонтактноеЛицо, Телефон, ИдентификационныйНалоговыйНомер Одна из возможностей — отнести все эти атрибуты к сущности КЛИЕНТ, как показано на рис. 2.14, а. В этом случае, однако, некоторые атрибуты будут непри менимы. Например, такой атрибут, как имя управляющего партнера, не имеет смысла для индивидуального или корпоративно! о клиента, и, таким образом, он нс может иметь какое-либо значение. КЛИЕНТ содержит: НомерКлиента ИмяКлиента СуммаКОплате Адрес НомерСоциальнойСтраховки ИмяУправляющегоПартнера ИдентификационныйНалоговыйНомер ДоверенноеЛицо Телефон КЛИЕНТ содержит: НомерКлиента ИмяКлиента СуммаКОплате ФИЗИЧЕСКОЕ_ЛИЦО содержит: Адрес НомерСоциальнойСтраховки ТОВАРИЩЕСТВО содержит: ИмяУправляющегоПартнера Адрес ИдентификационныйНалоговыйНомер КОРПОРАЦИЯ содержит: ДоверенноеЛицо Телефон ИдентификационныйНалогоаыйНомер б ₽Мс- 2.14. Подтипы сущностей: а — КЛИЕНТ без подтипов; б — КЛИЕНТ с подтипами, в - невзаимоисключающие подтипы с необязательным надтипом
78 Глава 2. Модель «сущность—связь»: методы и средства модели. В модели, более близкой к реальной ситуации, вместо этою будут определены три сущности-подтипа, как показано на рис. 2 14, 6. Здесь сущности ФИЗИЧЕСКОЕ ЛИЦО, ТОВАРИЩЕСТВО и КОРПОРАЦИЯ изображены как подтипы сущности КЛИЕНТ Последняя, в свою очередь, является подтипом (supertype) для сущностей ФИЗИЧЕСКОЕ_ЛИЦО, ТОВАРИЩЕСТВО и КОРПОРАЦИЯ. Символ е рядом с линиями связи указывает, что сущности ФИЗИЧЕСКОЕ_ЛИЦО. ТОВАРИЩЕСТВО и КОРПОРАЦИЯ являются подтипами сущности КЛИЕНТ. Каждый подтип должен принадлежать надтипу КЛИЕНТ. Кривая линия с цифрой 1 рядом показывает, что сущность КЛИЕНТ должна принадлежать к одному и только одно- му подтипу. Это означает, что подтипы являются взаимоисключающими и что требуется только один из них. Сущности со связью типа «ЕСТЬ» должны иметь один и тот же идентифика- тор, поскольку они представляют различные аспекты одного и того же. В данном случае таким идентификатором является НомерКлиента. Сравните эту ситуацию со связью типа «ИМЕЕТ», показанной на рис. 2.7, где сущности представляют разные вещи и поэтому имеют разные идентификаторы. Иерархии обобщений имеют специальную характеристику, называемую на- следованием (inheritance), которая означает, что подтипы классов сущностей на- следуют атрибуты от надтипа. Сущность ТОВАРИЩЕСТВО, к примеру, наследует атрибуты ИмяКлиента и СуммаКОплате от сущности КЛИЕНТ. Причины, по которым подтипы используются в моделировании данных, от- личаются от причин, по которым они используются в объектно-ориентирован- ном программировании. Фактически в модели данных они применяются с един- ственной целью: избежать ситуаций, при которых некоторые атрибуты должны иметь нулевые значения. Например, если атрибуту НомерСоциальнойСтраховки на рис. 2.14, а присвоено значение, то остальные четыре атрибута должны быть равны нулю. Эта ситуация наиболее ярко проявляется в медицинских приложени- ях: представьте себе, например, что пациенту мужского пола задается вопрос о ко- личестве беременностей. Нулевые значения более детально обсуждаются в главе 5. Пример ER-диаграммы На рис. 2.15 показан пример диаграммы, содержащей все элементы модели «сущ- ность-связь», о которых шла речь до сих пор. Она изображает сущности и связи для инженерной консалтинговой компании, которая занимается анализом строи- тельства и состояния жилых домов, а также других зданий и сооружений. На диаграмме есть класс сущностей, представляющий сотрудников компа- нии. Поскольку некоторые сотрудники являются инженерами, сущность ИНЖЕНЕР связана с сущностью СОТРУДНИК как подтип. Каждый инженер должен быть со- трудником. Сущность ИНЖЕНЕР имеет связь 1:1с сущностью ГРУЗОВИК: каждый грузовик должен быть закреплен за каким-то инженером, но не у всех инжене- ров есть грузовики.
Расширенная модель «сущность—связь- 79 КЕМ_ПРИВЕДЕН Рис. 2.15. Пример диаграммы «сущность—связь» Инженеры выполняют работы (сущность РАБОТА) для клиентов (сущность КЛИЕНТ). Инженер может не выполнять никаких работ (иначе говоря, выполнять ноль работ) или выполнять много работ, но каждая отдельно взятая работа мо- жет выполняться только одним конкретным инженером. Для одного и того же клиента может выполняться много различных работ, и один и тот же вид работы может выполняться для множества клиентов. Клиент должен оплатить по меньшей мере одну работу, но различные виды работ существуют независимо от клиентов. Связь КЛИЕНТ—РАБОТА имеет атрибут Плата, который показывает сумму, упла- ченную конкретным клиентом за конкретную работу. (Прочие атрибуты сущно- стей и связей не показаны на этой диаграмме.) Иногда одни клиенты приводят других, что показывается с помощью рекур- сивной связи КЕМ_ПРИВЕДЕН. Клиент может привести одного или нескольких Других клиентов. Клиент не обязан быть приведен другим клиентом, но каждого клиента может привести только один клиент. Сущность СЕРТИФИКАЦИЯ_ИНЖЕНЕРА показывает, что данный инженер полу- чил образование и прошел тестирование, требуемое для получения конкретно- Го сертификата. Инженер может иметь сертификаты (сущность СЕРТИФИКАТ). Существование сущности СЕРТИФИКАЦИЯ_ИНЖЕНЕРА зависит от сущности ИНЖЕНЕР Через связь ИНЖЕНЕР—КВАЛИФИКАЦИЯ. СЕРТИФИКАТ - это сущность, описываю- Щая конкретный сертификат.
80 Глава 2 Модель «сущность—связь»: методы и средства моделирования Стандарт IDEF1X Как уже говорилось, модель IDEF1X, представляющая собой модификацию модели -сущность—связь», была объявлена национальным стандартом США в 1993 году Ее основу составляют работы, выполнявшиеся в середине 1980-х годов для нужд военного ведомства. Имея модель «сущность—связь» в качестве фундамента, стан дарт IDEF1X расширяет ее в ряде аспектов, благодаря чему сею помощью стано- вится возможным создавать как концептуальные, так и внут ренние схемы По пово- ду создаваемой базы данных стандарт предполагает, что она является реляционной Стандарт IDEF1X включает сущности, связи и атрибуты, но значения этих понятий в нем сужены, а для их определения применяется более точная термино- логия Кроме того, в IDEF1X введено понятие домена (domain), отсутствующее в расширенной модели «сущность—связь». Наконец, в стандарте IDEF1X претер- пел изменения набор графических символов: в частности, был изъят ромб, а для обозначения категорий (отвечающих иерархиям обобщений и подтипам в расши- ренной модели «сущность—связь») были добавлены новые символы. Различия меж- ду расширенной моделью «сущность—связь» и моделью IDEF1X описаны в табл. 2.1 Таблица 2.1. Соответствие понятий расширенной модели «сущность—связь» и стандарта 1DEF1X Термин расширенной модели «сущность- связь») Термин модели IDEF1X Примечания Сущность Сущность Одно и то же Атрибут Атрибут Одно и то же Связь Связь Одно и то же Связи 1:1 и 1:N Связь N М Идентификационно- зависимая связь Слабая, но не идентификационно- зависимая сущность Неидентифицирующие связи принадлежности Неспецифическая связь Идентифицирующая связь принадлежности Связь принадлежности — это то же, что и связь типа «ИМЕЕТ» Сущность надтипа Порождающая сущность Порождающая сущность имеет связь типа «ЕСТЬ» с категориальным кластером Сущность подтипа Сущность-категория Домен Сущности-категории, принадлежащие к одному категориальному кластеру, являются взаимрисклк)ч£1рщими Сущности В IDEF1X Под сущностью в IDEF1X понимается то же самое, что и в расширенной модели «сущность—связь». Это может быть любая вещь, данные о которой пользователи хотели бы отслеживать. Как и в расширенной модели «сущность—связь», сущно-
Стандарт IDEF1X 81 стн изображаются и виде прямоугольников с прямыми или закругленными угла- ми, хотя прямоугольники с закругленными углами имеют в IDEF1X несколько иное значение (об этом речь пойдет позже, при обсуждении идентифицирующих связей). Сущности могут изображаться без атрибутов (рис. 2.16, а), с указанием толь- ко тех атрибутов, которые составляют первичный ключ (рис 2.16, б), или с указа- нием всех имеющихся атрибутов (рис. 2.17). Различные типы ключей будут подробно рассматриваться в главе 4. Пока что о первичном ключе можно думать как о главном уникальном идентификаторе сущности. В случае, когда сущность изображается со всеми атрибутами, символизирующий ее прямоугольник делит- ся на две части: в верхней части указываются атрибуты, входящие в первичный ключ, а в нижней — все прочие атрибуты. а ПРЕДМЕТ МЕБЕЛИ ОФИС ОТДЕЛ ЗДАНИЕ б Рис. 2.16. Уровни детализации моделей стандарте IDEF1X' а — только сущности, б — сущности и первичные ключи
82 МЕНЕДЖЕР ПЕРСОНАЛ КсдУровня ПочасоваяСтавка Последняя- ДниОтпуска Премия ПРОГРАММИСТ ТЕСТЕР ТЕХНИЧЕСКИЙ ПИСАТЕЛЬ Название Язык Операционнвя- Систвма ОпытРаботы ОпытРаботы Язык Рис. 2.17. Уровни детализации моделей стандарта IDEF1X — сущности и атрибуты Как вы, должно быть, помните (см. рис. 1.3), связи в реляционной модели создаются путем помещения ключа одной таблицы в другую таблицу. По отно- шению ко второй таблице такой ключ называется внешним ключом (foreign key). Вопросы создания внешних ключей и правила, регулирующие их размещение, относятся к проектированию баз данных. Эти ключи являются частью внутрен- ней схемы. Поскольку средства моделирования данных, отвечающие стандарту IDEF1X, мыут использоваться для создания как концептуальных, так и внутренних схем, они позволяют изобразить на схеме размещение внешних ключей. Как правило, на стадии создания концептуальной модели внешние ключи только отвлекают, поэтому мы рекомендуем вам отключить их показ (программные продукты обыч- но предусматривают такую возможность). Исключением из этого правила явля- ется моделирование идентифицирующих связей. Как вы увидите далее, в таких связях внешний ключ одной сущности является частью первичного ключа дру- гой сущности. Для таких сущностей имеет смысл отображать внешние ключи В остальных случаях при создании концептуальной модели на внешние ключи не стоит обращать внимания. Более подробно о внешних ключах вы узнаете из главы 5, где описывается проектирование баз данных.
Стандарт l X Связи в IDEF1X На рис- 2.18 перечислены четыре типа связей, определенные в стандарте IDEF1X Псполыпсмая там терминология хотя и несколько неуклюжа, является при май очень точной — как и полагается для национального стандарта Рассмотрим по- следователъно псе четыре гнпа связей. • Неидентифицирующие (вязи принадлежности • Идентифицирующие связи принадлежности • Неспецифические саязи • Категориальные связи Рис. 2.18. Типы связей в стандарте 1DEF1X Неидентифицирующие связи принадлежности Неидентифицирующие связи принадлежности (non-identifying connection relation- ships) — это связи 1:1 или 1:N между двумя идентификационно-независимыми сущностями (отсюда характеристика «неидентифицирующие»). Связь принадлеж- ности (connection relationship) — это то же самое, что и связь типа «ИМЕЕТ» в рас- ширенной модели «сущность—связь». На рис. 2.19 приведены примеры неидентифицирующих связей принадлеж- ности. Согласно стандарту, неидентифицирующие связи изображаются пунктирной линией. Кроме того, связи принадлежности в IDEF1X всегда рисуются в направ- лении от родителя к потомку. В случае связи 1:N родителем является сущность на той стороне связи, которая обозначена цифрой 1. В случае связи 1:1 любая из сущностей может считаться родителем, но стандарт IDEF1X предписывает вы- брать на эту роль какую-то одну из сущностей. Как видно из рис. 2.19, на конце линии связи рядом с сущностью-потомком на диаграмме «сущность—связь» стан- дарта IDEF1X помещается закрашенный кружок. ОТДЕЛ НазваниеОтдела БюджетныйКод НомерОфиса —ъ------- Р МЕБЕЛЬ СерийныйНомер Тип Размер Материал ДатаПриобре-еиия БЭЙДЖ НомерБэйДжа ДатаВыдачи КемВыдан _______СОТРУДНИК________ НомерСоциальнойСтраховки Имя Телефон КодДолжности КОМПЬЮТЕР Рис. 2.19. Неидентифицирующие связи принадлежности По умолчанию неидентифицирующне связи принадлежности имеют кацикма. ,ь- Ность «один ко многим» с обязательным родителем и необязательным потом- *°м- Такие связи изображаются пунктирной линией с закрашенным кружком
84 ft Моцель -сущность—связь-: Ц средсг.» модолиромим. стороне потомка без каких-либо яругах обозпаченн,,. Так, связь между сущие ™ МФВДРА .. МЕБЕЛЬ на рис. 2.19 имеет вил 1:№ н„ одна из кафедр „е обо., на иметь мебель, но любая мебель, если таковая имеется, должна обязательно чис питься за какой-либо кафедрой. Если кардинальность связи отличается от предполагаемой по умолчанию, ис- пользуются дополнительные обозначения. Если потомок является обязательным рядом с кружком на соответствующем конце линии связи помещается символ Р (от positive - положительный; имеется в виду положительное число). Если ро- дитель является необязательным, то на родительском конце линии связи рисует- ся ромб. На рис. 2.19 связь между сущностями КАФЕДРА и СОТРУДНИК имеет вид 1:N, причем любая кафедра должна иметь по крайней мере одного сотрудника, но отдельно взятый сотрудник не обязан числиться на какои-либо кафедре. Связи 1:1 обозначаются при помощи индексов рядом с кружком на соответ- ствующей стороне связи. Число 1 показывает, что требуется ровно один пото- мок, не больше и не меньше, а буква Z означает, что потомок может быть один, либо его может не быть вовсе. Так, на рис. 2.19 сущность СОТРУДНИК имеет связь с одной и только одной сущностью БЭЙДЖ, а также с одной или нулевым коли- чеством сущностей КОМПЬЮТЕР. Ромб показывает, что компьютер не обязатель- но должен быть связан с каким-либо сотрудником. Поскольку на линии связи БЭЙДЖ-СОТРУДНИК со стороны сущности СОТРУДНИК ромба нет, каждый значок должен принадлежать какому-то сотруднику. Идентифицирующие связи принадлежности Идентифицирующие связи принадлежности (identifying connection relationships) — это то же самое, что и идентификационно-зависимые связи в расширенной моде- ли «сущность-связь». Идентификатор родителя всегда является частью идентифи- катора потомка. На рис. 2.20 сущность ЗДАНИЕ является родителем в идентификаци- онно-зависимой связи с сущностью ОФИС. Обратите внимание, что идентифика- тор сущности ЗДАНИЕ, атрибут НомерЗдания, является частью идентификатора иим'^Т" О начение (ВК) означает, что данный атрибут является внеш- ошн СущН0СТИ <п дан,10М ^е сущности ЗДАНИЕ). Идентифици- связях писуютгя Казываются сплошными линиями, а сущности-потомки в таких связях рисуются с закругленными углами. ЗДАНИЕ НомврЗдания ТелвфонСвкретаря КоличествоЭтажвй МвстоСтоянки ОФИС НомврЗдания (ВК) НомерОфисв НомерСетевогоПорта НомврТелвфонногоПорта МаксВместимость связи принадлежности Рис. 2.20. Идентифицирующие ним вджко "STa Р»лом с закрашен- ум«,ю. Таким образом, „
Стандарт IDEEIX В5 зкество офисов. Если бы рядом с кружком был укатан индекс 1, то в здании мог бы располагаться ровно один офис, в случае индекса Z возможное количество офисов равнялось бы 0 или 1, а индекс Р указывал бы на любое количество офи- сов, большее или равное 1. На родительской стороне идентифицирующей связи не может быть ромба, поскольку сущности-родители в таких связях всегда явля- ются обязательными. Есть важное различие между слабыми сущностями в расширенном модели «сущность—связь» и идентифицирующими связями в модели IDEF1X. Как уже говорилось ранее, слабая сущность — это такая сущность, которая логически зави- сит от другой сущности. Это может быть как идентификационно-зависимая сущ- ность, так и сущность, имеющая свой собственный идентификатор: главное, чтобы она логически зависела от какой-то другой сущности. Сущность ПОДЧИНЕННЫЙ на рис. 2.11 является слабой, и все же у нее есть свой собственный идентифика- тор, отличный от идентификатора сущности СОТРУДНИК. Хотя стандарт IDEF1X допускает слабые сущности, не являющиеся иденти- фицирующими, он не предусматривает для них никакого специального обозна- чения. Минимальное кардинальное число для родителя в таких связях равно 1, но никаких других способов зафиксировать факт логической зависимости от сущности-родителя не имеется. Иными словами, в расширенной модели «сущность—связь» проводилось раз- личие между сущностью, логически зависимой от другой сущности (например, ПОДЧИНЕННЫЙ и СОТРУДНИК), и независимой сущностью, которая просто-напро- сто имеет обязательного родителя. Сущность ПОДЧИНЕННЫЙ логически требует сущности СОТРУДНИК, поскольку подчиненный всегда подчинен кому-то. С дру- гой стороны, в связи СТУДЕНТ—РУКОВОДИТЕЛЬ сущность РУКОВОДИТЕЛЬ может быть обязательной, однако это не делает сущность СТУДЕНТ логически зависимой от нее. В IDEF1X признается такое различие, но отсутствуют символы для его обо- значения. Подытожить это обсуждение можно следующим образом: в расширенной мо- дели «сущность—связь» закругленные углы обозначают слабую сущность, кото- рая может быть как идентификационно-зависимой, так и логически зависимой. В стандарте IDEF1X закругленными углами обозначаются только идентифика- ционно-зависимые сущности, а какого-либо способа изобразить на диаграмме сла- бую сущность, не являющуюся идентификационно-зависимой, не существует. Неспецифические связи Под неспецифической связью (non-specific relationship) в IDEF1X понимается не Чт° иное, как связь «многие ко многим». Неспецифичсские связи обозначаются закрашенными кружками на обоих концах сплошной линии связи (рис. 2.21, а). В 1OEF1X не предусмотрено задание минимальной кардинальности для неспе- Цифической связи. Стандарт IDEF1X обращается со связями «многие ко многим», как с бедными (Родственниками неидентифицирующих связей принадлежности. Причиной явля- <1Ся то» что такие связи не могут быть напрямую выражены в терминах реляци- онной модели. Как вы узнаете из главы 5, связь «многие ко многим» необходимо
86 глава 2. модель-сущность-сдзь. оредетва „одвзиро.аки. сначала преобразовать в две связи 1Н преж» «« ««—> ~»в.гь в реляционной базе данных. Примечание: идентификатором сущности КВАЛИФИКАЦИЯ является сочетание (НомерСоциальнойСтраховки, НазваниеНавыка) б Рис. 2.21. Неспецифические связи а — модели со связью N:M; б — модели с пропущенной сущностью Некоторые воспринимают это как вопиющий дефект модели IDEF1X, по- скольку тем самым идеи концептуальной схемы смешиваются с идеями схемы внутренней. С этой точки зрения, мы должны иметь возможность исчерпыва- ющим образом описать связь M:N, включая минимальные кардинальные числа, в рамках концептуальной модели. Что произойдет с этой связью позже, в про- цессе разработки внутренней схемы, не должно нас интересовать на стадии кон- цептуального проектирования. Другая точка зрения сводится к тому, что связи вида N:M не существуют в ре- альности Их кажущееся существование обусловлено тем, что при создании кон- цептуальной модели был упущен из виду некоторый объект, который, по идее, должен был бы в пен присутствовать. Рассмотрим связь N:M между сущностя- ми СОТРУДНИК и ПРОФЕССИЯ. В большинстве случаев организация хочет знать не только то, какими профессиями владеет сотрудник, но и то, в каком объеме он ими владеет. Выходит, какой-то сущности здесь не хватает. Если мы дополним нашу модель сущностью УРОВЕНЬ_КВАЛИФИКАЦИИ (рис. 2.21, б), связь N:M рас-
Стандарт IDEF1X 87 падегся на две связи 1:N. Первичный ключ сущности УРОВЕНЬ-КВАЛИФИКАЦИИ будет представлять собой комбинацию ключей сущностей СОТРУДНИК и ПРОФЕССИЯ, то есть (ТабельныйНомер, Профессия). Рассмотрим связь между сущностями СТУДЕНТ и ПРЕДМЕТ. Студент может изу- чать множество предметов, и один и тот же предмет может изучать множество студентов. Поэтому возникает впечатление, что эти сущности имеют связь N:M. Однако вспомним, что студенты получают оценки по изучаемым ими предметам Добавим в имеющуюся модель сущность ОЦЕНКА, и тогда то, что казалось связью N:M между сущностями СТУДЕНТ и ПРЕДМЕТ, превратится в две связи 1:N — одна ме- жду сущностями СТУДЕНТ и ОЦЕНКА, другая между сущностями ПРЕДМЕТ и ОЦЕНКА Для тех, кто мыслит в этом направлении, термин «неспецифичность» по отноше- нию к связям N:M попадает как раз в точку. Но тогда как мы поступим со связью N:M между сущностями СТУДЕНТ и РОК- ГРУППА, которая описывает интерес студентов к различным рок-группам? Сту- дент может интересоваться несколькими рок-группами, и одной и той же рок- группой может интересоваться множество студентов. Какой сущности здесь не хватает? Может быть, это альбом, который заинтересовал студента? Или первый посещенный студентом концерт? Эти дополнительные сущности кажутся притя- нутыми за уши и ненатуральными. Или, например, как насчет связи N:M между сущностями СОТРУДНИК и ОФИС? Что здесь можно охарактеризовать как недостающие данные? Дату, когда сотруд- ник занял данный офис? Физическое местоположение сотрудника в офисе? Эти сущности также не оставляют впечатления естественности. Вам следует сформировать собственное мнение по данной проблеме. Однако будьте осторожны в обсуждениях, поскольку для некоторых людей этот вопрос приобретает чуть ли не религиозный характер. Одним из таких людей может быть ваш преподаватель! Категориальные связи Категориальные связи (categorization relationships) представляют собой частный случай связей вида обобщенпе/подтпп в расширенной модели «сущность—связь». Л именно, категориальная связь — это связь между порождающей сущностью (generic entity) и другой сущностью, которая называется сущностью-категорией (category entity). Сущности-категории группируются в категориальные класте- ры (categorization clusters). Например, на рис. 2.22 сущность СОТРУДНИК явля- ется порождающей сущностью, сущности ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ^ ПИСАТЕЛЬ являются сущностями-категориями, а категориальный кластер, изобра- женный закрашенным кружком над двумя горизонтальными линиями, объединя- ет в себе сущности ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ_ПИСАТЕЛЬ. Категориальные связи — это связи типа «ЕСТЬ»: например, программист есть с°трудннк. Соответственно, как и полагается для связей этого типа, первич- нЫм ключом сущностей-категорий служит категориальный ключ порождающей сущности. В данном примере первичным ключом сущностей ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ_ПИСАТЕЛЬ является атрибут ТабельныйНомер. В связи с этим об- стоятельством сущности-категории показываются на схеме без первичных ключей.
88 r„«,a2. Модель.оущкооть-с.язь-: методы, иоредст. мушмедин. СОТРУДНИК НомерСоцивльнойСтраховки Имя Телефон КодДолжности |z ПРОГРАММИСТ Название Язык ОпврационнаяСистема КодДолжности ТЕСТЕР ”1 2 ТЕХНИЧЕСКИЙ ПИСАТЕЛЬ ОпытРаботы ОпытРаботы Язык Рис. 2.22. Категориальные связи В стандарте IDEF1X сущности, входящие в категориадьныи кластер, являют ся взаимоисключающими. На рис. 2.22 сотрудник может быть либо програ i стом, либо тестером, либо техническим писателем. Состоять на двух или более должностях одновременно сотрудник не может. Категориальные кластеры могут иметь дискриминатор (discriminator) — ат- рибут порождающей сущности, указывающий на тип сотрудника. На рис. 2.22 дискриминатором является атрибут КодДолжности. Таким образом, по значению данного атрибута можно определить, какую должность занимает сотрудник — программист, тестер или технический писатель. Способ, при помощи которого это делается, остается за рамками концептуальной модели — мы просто указыва- ем, что это сделать можно. Некоторые категориальные кластеры не имеют дис- криминатора, и конкретная сущность-категория остается в них неопределенной. Есть два типа категориальных кластеров: полные и неполные. В полном кате- гориальном кластере (complete category cluster) показана каждая из возможных для этого кластера категорий. Полные категориальные кластеры обозначаются двумя горизонтальными линиями с зазором между ними. Категориальный кла- стер, изображенный на рис. 2.22, является полным. Поскольку это так, на схеме изображены все без исключения категории сотрудников, входящие в данный кластер. Соответственно, каждый сотрудник может быть классифицирован как программист, тестер или технический писатель. (Вы можете спросить: «Постойте, есть же и другие типы сотрудников. Где, на- пример, бухгалтеры?» Суть в том, что согласно данной модели, других типов со- трудников не существует. Возможно, эта модель используется только в отделе разработки программного обеспечения, где не существует других должностей. может ыть, эта модель просто неверна. Но, как бы то ни было, в соответствии с данной моделью, не существует других типов сотрудников, помимо тех, которые в ней указаны.) Все сущности-категории являются жизненно зависимыми от порождающей сущности, поэтому минимальное кардинальное число связи со стороны порож-
Стандарт IDEF1X 89 дающей сущности равно 1. 1 ак как это справедливо но всех случаях, данное кар- динальное число не показывается па диаграмме. Согласно стандарту IDEF1X, кардинальное число категориальной свяж на стороне сущности-категории всегда равно 0 или 1. Индекс Z на линии, сое ди няюшей порождающую сущность с символом кластера, показывает, что поро- ждающая сущность не обязана (хотя и может) иметь категории Индекс Z на линии, соединяющей символ кластера с сущностью-категорией, показывает, что порождающая сущность может, но не обязана принадлежать к данному типу Многие считают эту запись с индексами Z сбивающей с толку, а то и попросту неправильной. Как уже отмечалось выше, категории в кластере являются вза- имоисключающими. Следовательно, как только устанавливается связь порожда- ющей сущности с одной из сущностей-категорий, кардинальность связей со всеми остальными сущностями данного кластера оказывается равной нулю. Кроме того, индекс Z на линии, соединяющей порождающую сущность с символом кластера, показывает, что эта сущность в принципе может и не иметь категорий. Однако в некоторых случаях для полных кластеров на месте Z следовало бы поставить 1, чтобы показать, что порождающая сущность обязана иметь связь с сущностью- категорией. К сожалению, в модели IDEF1X указание индекса 1 в подобных слу- чаях не предусмотрено. На рис. 2.23 показан еще один категориальный кластер, состоящий из сущно- стей-категорий МЕНЕДЖЕР и ПЕРСОНАЛ. Этот кластер является неполным, на что указывает его символ, состоящий из одной горизонтальной линии вместо двух. Это означает, что по меньшей мере одна категория отсутствует. Например, со- трудник может принадлежать к категории работающих на неполную ставку. Опять-таки все кардинальности на схеме обозначены как Z. СОТРУДНИК НомерСоциальнойСтраховки Имя Телефон КодДолжности ПЕРСОНАЛ nz ( ) КодДолжности менеджер I Z ПРОГРАММИСТ Подуровня Последняя- Дремия Почасовая- Стввка ДниОтпуска Название Язык Операционная Система ; | Z ТЕСТЕР ОпытРаботы I Z ТЕХНИЧЕСКИЙ- ПИСАТЕЛЬ ОпытРаботы Язык Рис. 2.23. Неполные и полные категориальные кластеры
90 Глава 2. Модель «сущность—связь»- методы и средства _моделиров.|ния Мы говорили, что сущности-категории, входящие в категориальный кластер, являются взаимоисключающими. Но это вовсе не означает, что сущность не мо- жет быть связана с двумя или более сущностями-категориями, принадлежащими к разным кластерам. Так, например, на рис. 2.23 сотрудник может быть менедже- ром и одновременно программистом. При этом сотрудник не может в одно и то же время принадлежать и к менеджерам, и к персоналу. Как вы можете видеть, модель IDEF1X дальнейшим образом структурирует связи вида обобщение/подтип, как они определены в расширенной модели «сущ- ность—связь» Давая этим идеям более четкое выражение, стандарт IDE 1 лает их более осмысленными, а следовательно, и более полезными. Имена связей В стандарте IDEF1X всем связям, кроме категориальных, могут присваиваться имена. Обычно имя связи состоит из трех элементов; глагол или глагольное сло- восочетание, описывающее предмет связи с точки зрения родителя, затем косая черта и аналогичный глагол или глагольное словосочетание, описывающее пред- мет связи с точки зрения потомка. (В связи N:M на роль родителя можно назна- чить любую из двух сущностей.) Так, на рис. 2.24 сотрудник использует компью- тер, но компьютер используется сотрудником; сотрудник занимает офис, а офис занят сотрудником. Как правило, глагольное словосочетание, описывающее предмет связи с точки зрения потомка, представляет собой страдательную форму глагольного словосочетания, описывающего предмет связи с точки зрения ро- дителя. В тех случаях, когда это приводит к неуклюжим речевым оборотам, ис- пользуется другой глагол. Например, бизнес-центр состоит из офисов, но офисы находятся в бизнес-центре. ЗДАНИЕ Рис. 2.24. Модель стандарта IDEF1X с именами связей Из-за этого сказуемыми и полезны, когда повторяющегося шаблона имена связей зачастую являются пред- поэтому не слишком информативными. Однако они могут быть характер связи между двумя сущностями неочевиден. На рис 2 25
Стандарт IDEF1X 91 1меется две связи между сущностями КЛИЕНТ и ПРОДАЖА Одна из связей указы* ваеТ на то, что клиент может что-то купить, а другая — на то, что клиент может что-то продать. КЛИЕНТ СДЕЛКА АГЕНТ НомерКлиента Покупает/Куплено Продает/Продано НомерДокумента Продает/Продано Имя Имя Улица Город Штат Индекс Телефон АдресЭпПочты Дата Описание ДоговорнаяЦена Налог Итого Комиссионные Телефон ИмяБрокера Рис. 2.25. Использование имен связей в случае нескольких связей между двумя сущностями Уникальность имен требуется только для связей между одними и теми же двумя сущностями. На рис. 2.25 связь между сущностями АГЕНТ и ПРОДАЖА име- ет то же имя, что и связь между сущностями КЛИЕНТ и ПРОДАЖА. Однако имена двух связей, соединяющих сущности КЛИЕНТ и ПРОДАЖА, должны быть раз- личными. Домены Стандарт IDEF1X дополнил расширенную модель «сущность—связь» понятием домена. Домен (domain) — это именованный набор значений, которые может при- нимать атрибут. Домен может представлять собой фиксированный список значе- ний, а может быть определен и более общим образом — например, как набор строк с максимальной длиной 50 символов. В качестве примера первого подхода можно привести домен НАЗВАНИЯ_КАФЕДР, включающий названия всех офици- альных кафедр в неком университете. Определение этого домена выглядит как простое перечисление названий кафедр: {'Бухгалтерский учет', 'Биология', 'Химия', Вычислительная техника', 'Информационные системы', 'Менеджмент', 'Физика'}. Приме- ром второго подхода может служить домен ИМЕНА_СТУДЕНТОВ, который можно определит!, как строку длиной до 75 символор. Д°мены устраняют неоднозначность Домены столь же важны, сколь и полезны. Например, обратите внимание, что на Рпс. 2.23 как у сущности ПРОГРАММИСТ, так и у сущности ТЕХНИЧЕСКИЙ_ПИСАТЕЛЬ имеется атрибут под названием Язык. Без использования доменов имена этих тРибутов могут толковаться неоднозначно. Описывают ли они одно и то же, _ нет? Возможно, для программиста Язык обозначает язык про!раммировання, а Аля технического писателя — естественный язык. А может быть, в обоих случа- Речь идет о языке программирования. Эту неоднозначность можно устранить, Указав домен, к которому должен принадлежать каждый из атрибутов.
92 Гпаиа 2. Модель сущн.югь-о.Мэь.: методы и оредса «деяиро^ П cnuik ПРОГРАММИРОВАНИЯ можно определить списком {С#, C++, Java, •VlsXe а Д»мИ. ЕСТЕСТВЕННЫМЗЫК - списком (Pyc«rf. 'Фпаннузский' 'Испанский', 'Британский английским', Американский английский} Те Французский, ис ,^п1.спгт Язык сущности ПРОГРАММИСТ принадлежит пень если постановить, что атрибут Язык сущности v тгуымиггимй г домену ЯЗЫК ПРОГРАММИРОВАНИЯ, а атрибут Язык сущности ТЕХНИЧЕСКИЙ_ ПИ«ТИЬ принадлежит к домену ЕСТЕСТВЕННЕЕ J3UK. эти два атрибута иовоз- Йта “..Хинные домены устраняют неоднозначность между атрн- бутами описывающими разные вещи, ио имеющими сходные значения Воз- вращаясь к рис. 2.23, предположим, что для сотрудников, входящих в число персонала, максимальная продолжительность отпуска составляет 30 дней. Пред- положим далее, что мы не ожидаем, что кто-либо из сотрудников проработа- ет более 30 лет. В этом случае каждый из атрибутов ПЕРСОНАЛ.ДлнтельностьОтпус- ка, ТЕСТЕР.ВыслугаЛет и ПРОГРАММИСТ.ВыслугаЛет будет иметь значения в диапазо- не от 0 до 30. (Здесь мы используем запись, в которой атрибуты идентифици- руются путем присоединения имени сущности к имени атрибута через точку.) Не указав домен, мы не сможем определить, описывают ли эти значения одно и то же. Теперь определим домен ДЛИТЕЛЬНОСТЬ_ОТПУСКА как целое число в интер- вале от 0 до 30 и домен ВЫСЛУГА как целое число в интервале от 0 до 30. Мы мо- жем указать, что атрибут ПЕРСОНАЛ.ДлительностьОтпуска принадлежит к домену ДЛИТЕЛЬНОСТЬ_ОТПУСКА, а атрибуты ТЕСТЕР.ВыслугаЛет и ПРОГРАММИСТ.ВыслугаЛет принадлежат к домену ВЫСЛУГА. Домены полезны на практике Домены хороши не только тем, что устраняют неоднозначность. Они полезны и в практическом отношении. Предположим, что в модели университетской ба- зы данных у пас есть атрибут под названием МестныйАдрес, используемый во множестве различных сущностей. Это могут быть, например, сущности СТУДЕНТ, ПРЕПОДАВАТЕЛЬ, КАФЕДРА, ЛАБОРАТОРИЯ и так далее. Предположим также, что все атрибуты МестныйАдрес отнесены к одному и тому же домену МЕСТНЫЙ_АДРЕС, который определен как множество всех возможных значений вида BBB-NNN, где ~мЭТ° СПУСОК кодов зданий, a NNN — список номеров комнат. Тогда все атри- буты МестныйАдрес унаследуют это определение. Теперь допустим, что, построив нашу модель, мы обнаружили, что некоторые комнаты имеют четырехзначные номера. Если бы у нас не был определен соот- етствующии домен, нам бы пришлось найти в модели все атрибуты, использу- местныи адрес, и поменять в них трехзначные номера на четырехзначные. . <С еСТЬ ДОмен’задача становится гораздо проще: стоит изменить определе- ичмрнп>ел1а'ч ВСе аТРМ У™’ пРннадлежащис к этому домену, унаследуют данное иие тпТл v Т° Не ТОЛЬК° сокращает тРУдозатраты, но и предотвращает появле- ие трудных для диагностики и исправления ошибок литьС?г Т. ОДН° ПОЛеЗНОе применение для доменов: они помогают опреде- лить, не описывают ли два атрибута с различными названиями одно и то же.
Стандарт IDEF1X »3 НаприМСР’ СУ,Ц,,ОС гь КАФЕДРА может иметь атрибут под названием БюджегиыиКод, а сущность ПРОЕКТ — атрибут под названием СтатьяРасходое. Используя домены, мы можем быстро определить, нс происходят ли эти атрибуты из одного и того же домена. Без доменов это было бы сделать нелегко. Даже если значения атри- бутов похожи, они могут обозначать совершенно разные вещи Базовые и типовые домены В стандарте IDEE 1X определены два типа доменов. Базовый домен (base domain) — это домен, которому присвоен тип данных и, возможно, перечень значений или определение диапазона. Стандартными типами данных являются Character (сим- вольный тип), Numeric (числовой тип) и Boolean (логический тип). В специфика- ции доменов можно использовать дополнительные типы данных, такие как Date (дата), Time (время), Currency (валюта) и так далее. Список значений — это список, подобный тому, что мы задавали для домена ЯЗЫ^ПРОГРАММИРОВАНИЯ, а приме- ром определения диапазона может служить определение домена ВЫСЛУГА. Типовой домен (type domain) представляет собой подмножество значений ба- зового домена или другого типового домена. На рис. 2.26 изображены типо- вые домены, основанные на базовом домене НАЗВАНИЯ_КАФЕДР. Типовые домены можно организовывать в иерархии, что позволяет достичь большей точности при определении атрибутов. Рис. 2.26. Пример иерархии доменов
94 Глава 2. Модель «сущность-связь»; методы и средства моделирования Стандарт IDEF1X и средства моделирования данных Существует целый ряд программных продуктов, предназначенных для моделиро ванн: данных. Все диаграммы модели IDEF1X в этой книге бы .и нарисованы с помощью программы под названием ERWin от компании Computer Associat В программе Microsoft Visio имеется шаблон для баз данных, позволяющий создавать диаграммы как расширенной модели «сущность-связь», так и модели IDEF1X. Программа ERWin специально предназначена для моделирования данных и вообще удобнее в использовании, чем Visio. Ознакомительную версию ERWin можно загрузить с сайта www.ca.com (зайдя на сайт, щелкните на ссыл- ке Download) На сайте www.microsoft.com можно получить 60-дневную ознако- мительную версию Visio. Еще один продукт для создания моделей «сущность- связь», Designer/2000, выпускается компанией Oracle. Если вы на практических занятиях используете Oracle, то, возможно, ваш преподаватель выдаст вам эту программу. Диаграммы «сущность—связь» в стиле UML UML (Unified Modeling Language — унифицированный язык моделирования) — это набор структур и методик для моделирования и проектирования объектно- ориентированных программ (ООП) и приложений. UML является одновременно и методологией разработки систем ООП, и набором инструментов для разработ- ки таких систем. UML получил известность стараниями группы OMG (Object Management Group) — организации, занимающейся разработкой ООП-моделей, технологии и стандартов с 1980-х годов. Этот язык стал также находить широ- кое применение в среде профессионалов ООП. На UML базируются инструмен- ты для объектно-ориентированного проектирования, разработанные компанией Rational Systems. Будучи методологией разработки приложений, UML является предметом курса системной разработки и поэтому представляет для нас лишь ограничен- ный интерес. Вам могут, однако, встретиться диаграммы «сущность—связь», вы- полненные в стиле UML, поэтому представление об этом стиле следует иметь. Сущности и связи в UML На рис. 2 27 приведено UML-представление структур, изображенных на рис. 2.7. аждая сущность представлена классом сущностей (entity class), который изо- ражен в виде прямоугольника с тремя сегментами. В верхнем сегменте находят- ся имя сущнос I и и другие данные, о которых мы будем говорить далее. Во втором сегменте перечислены имена атрибутов сущности, а в третьем описаны ограниче- ния и методы (программные процедуры), относящиеся к данной сущности.
Диаграммы «сущность—связь» в стиле UML 95 СОТРУДНИК ИдСотрудника Имя Должность Телефон КодКвалификации АВТОМОБИЛЬ—НАЗНАЧЕНИЕ . °-1 1..1 АВТОМОБИЛЬ НомерЛицензии VIN Производитель Медель ГодВыпуска Ограничения и методы перечисляются здесь Ограничения и методы перечисляются здесь а ОБЩЕЖИТИЕ Название МестныйАдрес Вместимость ТелефонКоменданта ОБЩЕЖИТИЕ—ЖИЛЕЦ 0-1 1..* СТУДЕНТ НомерСтудента ИмяСтудента Телефон Группа Комната Ограничения и методы перечисляются здесь Ограничения и методы перечисляются здесь б СТУДЕНТ СТУДЕНТ—КЛУБ 0..* 0..* КЛУБ НомерСтудента ИмяСтудента Телефон Группа Комната НомерКлуба БюджетныйКод Описание Председатель ТелефонПредседателя Ограничения и методы перечисляются здесь Ограничения и методы перечисляются здесь Рис. 2.27. Представления различных типов связей в UML: а — связь 1:1; б — связь 1 :N; в — связь N:M Связи показаны линиями, соединяющими две сущности. Кардинальность представлена в формате х.г/, где х — необходимый минимум, а у — допустимый Максимум. Так, 0..1 означает, что наличие данной сущности необязательно, а мак- с,»гально допустимое количество — одна. Звездочка представляет неограничен- н°е количество. Например, запись 1..* означает, что требуется одна сущность, Допускается неограниченное количество. Найдите на рис. 2.27, a-е примеры связец с максимальной кардинальностью 1:1, 1:N и N:M. представление слабых сущностей ₽еДставление слабых сущностей в UML иллюстрирует рис. 2.28. На линии свя- 1 РяД°м с родителем слабой сущности (то есть рядом с сущностью, от которой НоВИсит слабая сущность) помещается закрашенный ромб. На рис. 2.28, а сущ- С1Ь РЕЦЕПТ является слабой сущностью, а сущность ПАЦИЕНТ — ее родителем.
96 глава_2 Модель сущность связь- Рис. 2.28. Представление слабых сущностей в UML: а — слабая сущность, не являю—аяся идентификационно-зависимой; б — идентификационно-зависимая слабая сущность На рис. 2.28, а показана слабая сущность, не являющаяся идентификационно-за- висимой. Это обозначается выражением <non-identifying> (не идентифи ; ю.» на связи ПАЦИЕНТ-РЕЦЕПТ. На рис. 2.28, б изображена идентификационно-зависи- мая слабая сущность. На это указывает ярлык «identify! ng> (идентифицирующая). Представление подтипов Способ представления подтипов в UML показан на рис. 2.29. На этом рисунке допус- тимыми подтипами сущности КЛИЕНТ являются ФИЗИЧЕСКОЕ_ЛИЦО. ТОВАРИЩЕСТВО и КОРПОРАЦИЯ. В соответствии с рисунком, каждый клиент может иметь один, два или все три указанных подтипа. Для данной ситуации это не имеет смысла: кли- ент должен быть одного и только одного типа. В текущей версии UML отсутствуют средства для обозначения взаимоисключающих подтипов. Можно, однако, само- стоятельно добавить на диаграмму соответствующее обозначение. На рис. 2.30 представлена UML-версия диаграммы «сущность—связь», пока- занной ранее на рис. 2.15. Поскольку связь между сущностями РАБОТА и КЛИЕНТ имеет атрибут Плата, для несения этого атрибута выделена специальная сущ- ность ТА-^Я-К-ЛИЕНТА. Такова стандартная практика при использовании «К™ Обратите также внимание на представление рекурсивной связи ИВЕДЕН.
Диаграммы «сущность—связь» в стиле UML Рис. 2.29. Представление подтипов в UML
98 глава 2. Мп.п.япь «сущность-связь»., методы и средства модолиро^ Конструкции ООП, введенные языком UML Так как UML является объектно-ориентированной ихнологией, классы сущ ностеп UML были дополнены некоторыми конструкциями ООП Здесь мы толь- ко коснемся этих идей, а развитие им дадим в главе 16. Во-первых, классы всех сущнос ей, которые должны храниться в базе данных, номечаютс ключевым словом <persistent> (устойчивый). Это значит, что данные должны продолжать свое существование и после того, как будет разрушен объект, их обрабатыва- вший. Проще говоря, это означает, что класс сущности должен храниться в базе данных. „ Далее, UML допускает назначение атрибутов классам сущностей. Атрибуты класса (class attributes) отличаются от атрибутов сущностей тем, что они при- надлежат всему классу сущностей данного типа. Так, на рис. 2.31 атрибут Число- Пациентов сущности ПАЦИЕНТ является атрибутом всей совокупности сущно- стей этого типа, имеющихся в базе данных. Атрибут ИсточникПоступления описывает источник поступления всех пациентов, записи о которых имеются в базе данных. Рис. 2.31. Представление классов сущностей в UML с помощью конструкций ООП mn пп' ВЫ ПОЗЖе У3наете’ в рамках реляционной модели такие атрибуты клас- Паниентов^ба Хранить’ ®место того чтобы хранить такие атрибуты, как Число- В дпугих слх/ Зяе ДаННЫХ’ ИХ иногда в’«исляют на этапе выполнения программы, сущностей Для к ДЛЯ Х₽анения этих атРибутов выделяется специальный класс С з"а нов™ Z Г сущностей ПАЦИЕНТ’ изображенного на рис. 2.31, можно буть. ЧиХм ПОД Т™ ИбГОЧНИК-ПОСТУПЛЕНИЯ, имеющую атри- ПАЦИЕНТ будут связаны СТ°ЧНИК 0СТУпления. В таком случае все сущности класса Тоетьей^^ 7 Сущностью ИСТОЧНИК_ПОСТУПЛЕНИЯ. тинной Хи^1^10 UML ЯВ™ использование объектно-ориен- Р< нотации для обозначения видимости атрибутов и методов. Атрибу-
Диаграммы «сущность—связь» в стиле UML 99 ты. именам которых предшествует знак «+», являются открытыми, атрибуты со знаком «#» являются защищенными, а со знаком «-» — закрытыми. На рис. 2 31 атрибут Имя сущности ПАЦИЕНТ является защищенным. Эти термины имеют корни в объектно-ориентированном программировании. Открытым (public) называется такой атрибут, который может читаться и изме- няться любым методом любого объекта. Термин защищенный (protected) означает, что атрибут или метод доступен только методам данного класса и его подклас- сов, а термин закрытый (private) указывает на то, что соответствующий атрибут или метод доступен только методам данного класса. Наконец, в UML задаются ограничения и методы, для чего служит третий сегмент прямоугольника, изображающего класс сущностей. На рис. 2.31 на зна- чение атрибута НомерПациента налагается ограничение первичного ключа. Это означает просто, что НомерПациента является уникальным идентификатором. Кроме того, рис. 2.31 указывает, что должны быть созданы следующие методы: ПолучитьИмя() — для открытого доступа к атрибуту Имя (обратите внимание на знак «+» перед методом ПолучитьИмя()), ВвестиИмя() — для установки значения этого атрибута, и ПолучитьРецепт() — для перебора совокупности сущностей клас- са РЕЦЕПТ, связанных с данной сущностью ПАЦИЕНТ. Роль UML в базах данных на сегодняшний день Идеи, которые иллюстрирует рисунок 2.31, представляются довольно туманными в том, что касается применимости объектного мышления к построению и функ- ционированию баз данных. Такая объектно-ориентированная нотация не согла- суется с обычаями и процедурами, принятыми в коммерческих базах данных се- годняшнего дня. Понятие о том, что атрибут сущности может быть скрыт внутри объекта, не имеет смысла, если только база данных не обрабатывается исключи- тельно объектно-ориентированными программами; по даже если так, эти програм- мы должны обрабатывать данные в соответствии с этой политикой. За исключе- нием специализированных объектно-ориентированных СУБД (ООСУБД) и их приложений, так никогда не делается. Напротив, большинство коммерческих СУБД позволяют всем видам про- грамм обращаться к базе данных и обрабатывать любые данные, в отношении ко- торых у этих программ имеются соответствующие полномочия. Более того, с та- К|,ми средствами, как генератор запросов в Microsoft Access 2002 (см. рис. 2.6), Просто не существует способов ограничить доступ к значениям атрибутов отдель- Ного объекта. Итак, все сводится к тому, что вам необходимо уметь интерпретировать диа- гРа'1МЫ «сущность—связь», выполненные в стиле UML. Они точно гак же при- ,Т)Дны ДЛя проектирования баз данных, как и диаграммы расширенной модели УШность—связь». Тем не менее, на текущий момент объектно-ориентнрован- нотация, которая в них вводится, имеет весьма ограниченную практическую Юность Дальнейшую информацию по этой теме вы найдете в главе 16.
методы и средства моделирования 100 Глава 2. Модель «сущность свя—. _ --------- Резюме а хлппряг проясняет роль моделирования данных в про- Тройстоенвая сх™ат1«сская мм. „„Делены три типа схем внешня» ектировании баз данны . . П,п6„я схема является представлением чего-то, «шшешуальная .‘ |х.р»а,„,„. хранящейся в базе дав Внешняя схема является р д внешней схемой описывается только „ых. сто,и, - ’™ — -™Ч“- ZX",a3o данных, а внутренняя схема - представление физический ^“^„шпуальной схемы с использованием конкретного программного ZZ и/илп метода Одна концептуальная схема, как правило, служит осно- Z,, множества внешних схем. Одна и та же концептуальная схема может быть реализована в различных внутренних схемах, в зависимости от того, какие программные средства и методы применяются. Пользователи общаются с разработчиками базы данных в терминах внешних схем. Задача разработчиков состоит в том, чтобы по результатам опроса пользо- вателей построить такую концептуальную схему, которая поддерживала бы все заданные пользователями внешние схемы. Исключительно важно не смешивать концептуальную схему с внутренней схемой. Концептуальная схема должна быть чисто логическим представлением, не искаженным соображениями относитель- но природы и ограничений используемой СУБД. Модель «сущность—связь» была предложена Питером Ченом (Peter Chen) в 1975 году, и различные варианты этой модели могут использоваться для по- строения концептуальных схем. Тиори (Теогеу) и другие расширили исход- ную модель, введя в нее подтипы, и результирующая версия получила название расширенной модели «сущность—связь». На сегодняшний день, когда говорят о модели «сущность—связь», в большинстве случаев имеют в виду именно рас- ширенную модель «сущность—связь». В 1993 году Национальный институт стан- дартов и технологии объявил о стандарте моделирования данных под названием «Единый стандарт моделирования информации», или IDEF1X. Этот стандарт клю 1ает в себя модификацию расширенной модели «сущность—связь», но ис- блтгпУп! Друп1е Пифические символы и предусматривает средства для разра- ш lx поллепжНПИХ СХеМ РЯД прогРаммных продуктов для моделирования дан- X™ в молеЮТ ?ТРТ IDEF1X> НО П₽И ЭТОМ ОНИ вносят и собственные на мХХия поп С00бщССТВт°^ объектного моделирования была разработа- в которую также вошла^ПИСМ ML ^УниФииированный язык моделирования), которую также вошла одна из версий модели «сущность-связь» «Л и™," Cv“ ’ерсий?“ асУшность—связь,- являются суш- ект. за которым пользозатстш юте^бы ™кот“рый идентифицируемый обь- образуют классы сущностей г. ледить. Группы однотипных сущностей характеристики. ИдентнфитттовокГн1 ИМеют атР'Футы. которые описывают их осуществляется HMetZX ™ “^бут, с помощью которого именование, различение отдельных зисацияров класса сущ-
Резюме 101 ности. Уникальный идентификатор указывает на конкретный экземпляр класса сущности, неуникальный — на некоторое множество экземпляров класса. Связи отражают взаимоотношения между сущностями. Классы связей — по взаимоотношения между классами сущностей, а экземпляры связей — взаимоот- ношения между экземплярами сущностей. Класс связей, соединяющий только два класса сущностей, называется бинарной связью. На практике большинство связей являются бинарными. Есть три типа бинарных связей: 1:1, 1:N и N:M. Индексы показывают макси- мальное кардинальное число связи. На традиционных диаграммах «сущность- связь» сущности изображаются прямоугольниками с прямыми или закруглен- ными углами, а связи — ромбами. Для каждой связи определено также мини- мальное кардинальное число — наименьшее число экземпляров сущности, ко- торые должны существовать на каждой из сторон экземпляра связи. Типичные значения минимального кардинального числа — 0 или 1, но могут быть и дру- гие числа. В расширенной модели «сущность—связь» слабой сущностью называется та- кая сущность, которая не может существовать в базе данных без некоторой дру- гой сущности. Слабая сущность может быть идентификационно-зависимой либо логически зависимой от другой сущности. Идентификационно-зависимой явля- ется такая сущность, идентификатор которой включает в себя идентификатор некоторой другой сущности. Слабые сущности изображаются ромбами и пря- моугольниками с закругленными углами. Многозначные атрибуты и группы атрибутов могут быть представлены с помощью идентификационно-зависимых слабых сущностей. Сущность-подтип представляет собой разновидность некоторой другой сущ- ности, называемой надтипом. Связь между надтипом и подтипом является связью типа «ЕСТЬ», поскольку все экземпляры иадтниа и подтипа ссылаются на одно н ю же. Подтипы используются тогда, когда некоторые атрибуты сущности оказываются в определенных ситуациях неприменимыми. Стандарт IDEF1X включает в себя расширенную модель «сущность—связь», ”о придает некоторым терминам иное значение, а также вводит понятие домена. С помощью 1DEF1X можно проектировать как концептуальные, так и впутрен- нне схемы. В данной главе рассматривается только проектирование концепту- альных схем. Сущности в 1DEF1X изображаются прямоугольниками. Если на диаграмме показываются атрибуты, то первичные ключи перечисляются в верхнем сегмен- Те Прямоугольника, а все остальные атрибуты — в нижнем. На диаграммах моде- ли 1DI F1X могут отображаться и внешние ключи, однако это обычно не имеет СмЬ1сла при построении концептуальной схемы. Ь 1DEF1X определено четыре типа связей: неидентифицирующие связи при- надлежности, идентифицирующие связи принадлежности, неспецифическне свя- и категориальные связи. Под неидентифицирующими связями понимают- Л СВязи 1:1 и 1:N типа «ИМЕЕТ» в расширенной модели «сущность—связь». а Диаграмме модели IDEF1X такие связи изображаются пунктирной линией
102 Глвва 2 Модель «сущность—связь», методы и средства модвлирсв; ния с закрашенным кружком на том копне, где находится сущность потомок Необяза тельные родители отмечаются ромбом па соответствующем конце линии связи Есин никаких дополнительных обозначений па стороне потомка не имеется карди- нальное число на этой стороне связи может быть равным О, I или более Индекс Р обозначает кардинальное число' I пли более, Z обозначает 0 или 1, а 1 показывает что имеется ровно один обязательный потомок. Идентифицирующие связи принадлежности — эго то же самое, что и иде фикационно-зависимые связи в расширенной модели «сущность-связь». Такие связи изображаются сплошной линией с закрашенным кружком на стороне по- томка. Кардинальное число со стороны потомка может быть равным О, 1 или бо- лее (индекс отсутствует), 1 и более (индекс Р), 0 или 1 (индекс Z), либо просто 1 (индекс 1). Родитель всегда является обязательным. В IDEF1X отсутствуют сред- ства для обозначения слабых сущностей, не являющихся идентификационно-зави- симыми. Таким образом, в отличие от расширенной модели «сущность-связь», где прямоугольник со скругленными углами представляет любую слабую сущ- ность, в модели IDEF1X таким прямоугольником обозначаются только иденти- фикационно-зависимые сущности. Неспецифические связи в IDEF1X используются для представления связей NM По мнению некоторых, связи N:M не существуют в действительности, а их присутствие указывает на то, что какая-то сущность была пропущена при моде- лировании. Другие считают, что такие связи все же существуют, и следовало бы обеспечить более адекватное их представление в модели IDEF1X. Категориальные связи — это связи типа «ЕСТЬ». В них участвуют поро- ждающая сущность, одна или несколько категориальных сущностей и катего- риальный кластер. Категории, принадлежащие одному кластеру, являются вза- имоисключающими. Полным называется такой кластер, в котором показаны все возможные категории. В неполном кластере отсутствует по меньшей мере одна категория. Дискриминатор — это атрибут порождающей сущности, с помощью которого определяется ее принадлежность к определенной категории. Сущность может иметь более одного категориального кластера и может иметь связь более чем с одной сущностью-категорией, лишь бы все эти категории происходили из разных кластеров. В модели IDEF1X связям могут присваиваться имена. Обычно имя связи со- стоит из трех элементов: глагольное словосочетание, описывающее предмет свя- зи с точки зрения родителя, косая черта и аналогичное глагольное словосочета- ние, описывающее предмет связи с точки зрения потомка. Имена связей важны, котда две сущности имеют между собой более одной связи. Стандарт IDEF1X ввел в модель «сущность—связь» понятие домена. Домен представляет собой именованное множество значений, которое может прини- мать атрибут. Домены устраняют неоднозначность, возникающую при наличии двух атри утов с одинаковыми именами или одинаковым набором значений, о которых неизвестно, описывают ли они одно и то же. Домены полезны на прак- тике, так как позволяют атрибутам наследовать свои характеристики из единого
Воирдды группы I 103 источника Если некоторая характеристика меняется, достаточно и «««-нить оире деление домена, п все атрибуты, принадлежащие «тому домену, автоматичг ски унаследуют произведенное изменение Базовым доменом называется домен, имеющий тин данных и, возможно, список значений или определение диапазона. Типовой домен — зто подмножество базового домена или другого типового домена. Существует ряд коммерческих нршраммиых продуктов для построения диа- грамм модели IDEF1X. Примерами таких продуктов могут служить ERWin, Visio и Dcsigner/2000. Язык UML представляет собой набор структур и методик для моделирования и проектирования объектно-ориентированных программ. Будучи технологией разработки приложений, он в общем и целом является предметом курса систем- ного анализа. Мы рассматриваем UML потому, что он включает в себя одн из модификаций модели «сущность—связь» для моделирования баз данных Сущности, связи и атрибуты UML весьма схожи с теми, которые используют- ся в расширенной модели «сущность—связь». Основное различие состоит в за- писи, а также в том, что в UML сущности и атрибуты дополнены конструкция- ми объектно-ориентированного программирования. UML поддерживает слабые сущности. Вопросы группы I 1. Объясните своими словами значение термина схема. 2. Перечислите схемы, входящие в тройственную схематическую модель ANSI/SPARC, и укажите функцию каждой из них. 3. Приведите пример ситуации, в которой организация может иметь три раз- личные внешние схемы, реализующиеся в одной концептуальной схеме. 4. Опишите, как с помощью внешних схем можно разработать концептуаль- ную схему. 5. Почему так важно не смешивать концептуальную схему с внутренней схемой? 6. В чем суть конфликта между Брюсом и Зельдой? Как вы считаете, смогут ли они прийти к единому мнению относительно способа записи данных? 7- В чем разница между исходной и расширенной моделями «сущность- связь»? 8. В чем состоит важность IDE FIX? В чем состоит важность UML? Дайте определение сущности и приведите пример. Ч- Поясните разницу между классом сущностей и экземпляром сущности *2. Дайте определение атрибута и приведите примеры атрибутов для сущно- сти, описанной вами в ответе на вопрос 10.
104 2. Мшель .оцноеть-свиь-: методы и сродсте молелиромни. 13. Обмен.™, что такое композитный „лентпфикатор. и п|«.«и« ..рииер 14. Какой .га атрибутов, приведенных вами в ответе на „опрос 12, идеитифи цирует сущность? 15. Дайте определение связи и приведите пример. 16 Объясните, в чем разница между классом связей и экземпляром связи. 17’ Дайте определение степени связи. Приведите пример связи СО степенью больше 2, отличный от того, который дан в тексте. 18. Перечислите три типа бинарных связей и приведите примеры. Нарисуйте диаграмму «сущность—связь» для каждого типа. 19 Дайте определения терминов максимальное кардинальное число и мини- мальное кардинальное число, максимальная кардинальность и минималь- ная кардинальность. 20. Назовите и нарисуйте символы, используемые в диаграммах расширенной модели «сущность-связь» для обозначения: (а) сущности; (б) связи; (в) сла- бой сущности и ее связи; (г) рекурсивной связи; (д) сущности-подтипа. 21. Приведите пример диаграммы «сущность—связь» для сущностей ОТДЕЛ и СОТРУДНИК, имеющих связь 1:N. Предположите, что в отделе может и не быть сотрудников, но каждый сотрудник должен работать в каком-либо отделе. 22. Приведите пример рекурсивной связи и изобразите ее на диаграмме «сущ- ность-связь». 23. Дайте определение термина слабая сущность и приведите пример, отлич- ный от того, который дан в тексте. 24. Поясните, в чем состоит неоднозначность в определении термина слабая сущность. Как этот термин интерпретируется в расширенной модели «сущ- ность связь»? Приведите примеры каждого типа слабой сущности, отлич- ные от тех, которые даны в тексте. 25. Дайте определение термина идентификационно-зависимая сущность и при- ведите пример, отличный от того, который дан в тексте. 26. Продемонстрируйте использование идентификационно-зависимой сущ- гптрч ДЛЯ представления многозначного атрибута Профессия сущности ДНИК. Укажите минимальное и максимальное кардинальное число на о еих сторонах связи. Используйте символы расширенной модели «сущ- ность-связь». 27. Продемонстрируйте использование идентификационно-зависимой сущно- сти для представления многозначного композитного атрибута Телефон, со- стоящего из однозначных атрибутов КодРегиона и НомерТелефона. Пусть ри этом атрибут Телефон принадлежит сущности ПРОДАВЕЦ. Укажите ми- нимальное и максимальное кардинальное число на обеих сторонах связи. Используйте символы расширенной модели «сущность-связь»
Вопросы группы I 105 28. Дайте определение сущности-подтипа и прицедите пример, отличный от того, который дан в тексте. 29. Объясните, что значит утверждение «Подтипы используются тогда, когда некоторые атрибуты сущности оказываются в определенных ситуациях неприменимыми». Покажите, как его можно применить к вашему ответу на вопрос 28. 30. Поясните разницу между связью типа «ИМЕЕТ» и связью типа «ЕСТЬ- и приведите пример каждого из типов связи. 31. Дайте определение термина первичный ключ. 32. Что такое вторичный ключ, и почему такие ключи неуместны на концеп- туальной схеме? 33. Что такое неидентифицирующие связи принадлежности? 34. Приведите пример неидентифицирующей связи принадлежности. 35. Объясните значение закрашенного кружка, ромба и индексов Р, Z и 1 на диаграмме «сущность—связь» модели IDEF1X. 36. Чему равна по умолчанию кардинальность неидентифицирующей связи принадлежности? 37. Какому виду связей в расширенной модели «сущность—связь» соответ- ствуют идентифицирующие связи принадлежности? 38. Чем отличается слабая сущность в расширенной модели «сущность—связь» от идентифицирующей связи принадлежности в модели IDEF1X? 39. Как в модели IDEF1X представляются слабые сущности, не являющиеся идентификационно-зависимыми? 40. Как в модели IDEF1X представляются связи N:M? 41. Приведите аргументы в пользу того, что связи N:M не существуют в дей- ствительности. Подкрепите аргументацию примерами, отличными от тех, которые приведены в тексте. 42. Приведите аргументы в пользу того, что связи N:M все-таки существуют. Подкрепите аргументацию примерами, отличными от тех, которые приве- дены в тексте. 43. Какую из двух точек зрения, представленных в ваших ответах на вопро- сы 41 н 42, разделяете вы лично? Почему? 44. Объясните значение терминов порождающая сущность, сущность-катего- рия и категориальный кластер. Приведите примеры. 45. Какова роль дискриминатора в категориальной связи? 46. В чем состоит разница между полным и неполным категориальными кла- стерами? 47. Объясните, почему указание индекса Z рядом с полными категориальны- ми кластерами может сбивать с толку.
106 глава 2. Модель .сущность-связь»; методы и средства модели^ания 48. При каких условиях экземпляр сущности может иметь связь с двумя или более экземплярами категориальных сущностей? 49 Чем категориальные связи в молили 1DEF1X отличаются от подтипов/ налтпнов в расширенной модели «сущность-связь») 50. Опишите традиционный способ именования связей. 51. В каких случаях имена связей могут быть особенно полезными? 52. Что такое домен? 53 Опишите два типа ситуаций, в которых использование доменов устраняет неод! юзначность. 54. Объясните, в чем состоит практическая польза доменов. 55. Дайте определение термина базовый домен. 56. Дайте определение термина типовой домен. Вопросы группы II Для ответа на вопросы 57-64 используйте диаграмму модели IDEF1X «Спортив- ные секции», изображенную на рис. 2.32. Рис. 2.32. Диаграмма «Спортивные секции» 7. Рассмотрим связь между сущностями СТУДЕНТ и ОБОРУДОВАНИЕ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3 Чему равно минимальное кардинальное число с обеих сторон связи? } снуйте ™ Не°бХ0Д,,МЬ1е-на паш ВЗГЛВД> изменения кардинальное™. Обо- 5) Дайте этой связи подходящее имя. 58. Рассмотрим связь между сущностями ОБОРУДОВАНИЕ и КУРС. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи?
Вопросы группы И 107 3) Чему равно минимальное кардинальное число с обеих сторон связи ? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 59. На рис. 2.32 сущность КУРС описывает курс спортивной дисциплины опре- деленного уровня сложности — например, гребля на каноэ для начинающих или подводное плавание для продолжающих. Сущность ЗАНЯТИЯ описывает занятия по данному курсу в конкретной группе — например, занятия по гребле на каноэ для начинающих с началом 7 января 2003 года. Рассмотрим связь между сущностями КУРС и ЗАНЯТИЯ. 1) К какому типу принадлежит эта связь? Правильный ли тип связи вы- бран для данного случая? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности Обоснуйте их. 5) Дайте этой связи подходящее имя. 60. Рассмотрим связь между сущностями ПЛАТА и ЗАНЯТИЯ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 61. Рассмотрим связь между сущностями ПЛАТА и СТУДЕНТ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. Рассмотрим связь между сущностями СТУДЕНТ и КЛУБ. ОК какому типу принадлежит эта связь? 2) Опишите новую сущность, введя которую, можно было бы превратить данную связь в две неидентифицирующие связи принадлежности. Ука- жите кардинальность новых связей 3) Как вы считаете, является ли получившаяся структура более удачным решением, чем первоначальная?
108 г^ва 2. Модель «сущность-связь»: методы и средства модвлиромния 63. Добавьте новую жду сущностью сущность под названием ИНСТРУКТОР. Создайте связи ме- ИНСТРУКТОР и сущностями КУРС и ОБОРУДОВАНИЕ 1) Обоснуйте выбор типа связи в каждом случае 2) Укажите кардинальности новых связей. 3) Дайте имена созданным связям. 4) Перерисуйте диаграмму, изображенную па рис. 2.32, добавив в нее но- вые сущности и связи и указав значения кардинальности, выбранные вами в ответах на вопросы 57-62. 64 Измените ваш ответ на вопрос 63, введя новую сущность АДМИНИ1 ТАГОР и сделав сущности ИНСТРУКТОР и АДМИНИСТРАТОР категориями сущности СТУДЕНТ. 1) Какого вида категориальный кластер следует использовать — полный или неполный? Обоснуйте свой выбор. 2) Назовите и опишите атрибут, который мог бы использоваться в каче- стве дискриминатора для этого категориального кластера. 3) Перерисуйте диаграмму, изображенную на рис. 2.32, добавив в нее но- вые сущности и связи. Для ответа на вопросы 65-71 используйте диаграмму модели IDEF1X «Ко- мандировка сотрудника», изображенную на рис. 2.33. -------А______ ЗАКАЗ ГОСТИНИЦЫ Рис. 2.33. Диаграмма «Командировка сотрудника» 65. Рассмотрим связь между сущностями СОТРУДНИК и КОМАНДИРОВКА. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардпнадаюе число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? ) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя.
Вопросы группы II 109 66. Рассмотрим связь между сущностями КОМАНДИРОВКА и ЗАКАЗ_АВИАБИЛ ТА. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 67. Рассмотрим связь между сущностями КОМАНДИРОВКА и ЗАКАЗ_ТАКСИ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 68. Рассмотрим связь между сущностями КОМАНДИРОВКА и ЗАКАЗ_ГОСТИНИЦЫ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 69. Рассмотрим связь между сущностями ЗАКАЗ_АВИАБИЛЕТА, ЭЛЕКТРОННЫЙ_ БИЛЕТ и БУМАЖНЫЙ_БИЛЕТ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Какого вида категориальный кластер здесь используется — полный или неполный? Не следует ли поменять тип кластера? 5) Приведите пример дискриминатора для этой связи. 70. Добавьте новую сущность под названием ОТЧЕТ_О_РАСХОДАХ. Создайте свя- зи между сущностью ОТЧЕТ_О_РАСХОДАХ и сущностями СОТРУДНИК и КОМАН- ДИРОВКА. 1) Обоснуйте выбор типа связи в каждом случае. 2) Укажите кардинальности новых связей. 3) Дайте имя созданным связям. 4) Перерисуйте диаграмму, изображенную на рис. 2.33, добавив в нее но- вые сущности и связи.
110 Глава 2. модель .сщноеть-с-АЗь.: методы и ередег.з моделирования х. 7л пш>п« новые сущности СЛУЖБЕ НАЯ и ЛИЧ- 71. Измените ваш ответ на вопро , КОМд|_|диРОВКА. Считайте, что СВЯЗЬ идо п Качестве категории сущности twr'iHn/virvoiu-. ™ЧНАЯ " ОРГРАСХОДАХ „с предусматрилаегся 1) Какого вила категориальиый кластер следует иоияь-юв.4ъ полны» или неполный? Обоснуйте свой выбор. 2) Назовите и опишите атрибут, который мог бы использоваться в каче- стве дискриминатора для этого категориального кластера. 3) Перерисуйте диаграмму, изображенную па рис. 2.33, добавив в ш вые сущности и связи. На рис. 2.34 показана концептуальная схема из «Саги о Брюсе и Зельде» в вер- сии IDEF1X. Используйте ее для ответа на вопросы 72-76. Рис. 2.34. Диаграмма из «Саги о Брюсе и Зельде» 72. Рассмотрим связь между сущностями РЫБА и НАБЛЮДЕНИЕ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардинальное число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 73. Рассмотрим связь между сущностями РЕКА и НАБЛЮДЕНИЕ. 1) К какому типу принадлежит эта связь? 2) Чему равно максимальное кардинальное число с обеих сторон связи? 3) Чему равно минимальное кардиншпшое число с обеих сторон связи? 4) Опишите необходимые, на ваш взгляд, изменения кардинальности. Обоснуйте их. 5) Дайте этой связи подходящее имя. 74. Добавьте новую сущность ПУНКТ_НАБЛЮДЕНИЯ в качестве дочерней сущ- ности в идентифицирующей связи принадлежности с сущностью РЕКА. . далите связь между сущностями РЕКА и НАБЛЮДЕНИЕ, а взамен установи- те связь между сущностями НАБЛЮДЕНИЕ и ПУНКТ_НАБЛЮДЕНИЯ. 1) сп^сЗм^а^ИНаЛЬН0СТЬ СВЯЗИ междУ сущностями РЕКА и ПУНКТ_НА- ЬЛЮДЕНИЯ. Обоснуйте выбранные значения. 2) Укажите кардинальность связи между сущностями ПУНКТ НАБЛЮДЕНИЯ и НАБЛЮДЕНИЕ. Обоснуйте выбранные значения.
Вопросы группы II 111 3) Дайте имена новым связям. 4) Перерисуйте схему на рис. 2.34 в соответствии с изменившейся струк- турой. 75. В схему, получившуюся в результате ответа на предыдущий вопрос, до- бавьте новую сущность НАБЛЮДАТЕЛЬ. Установите связь между сущностя- ми НАБЛЮДЕНИЕ и НАБЛЮДАТЕЛЬ. Создайте для сущности НАБЛЮДАТЕЛЬ категориальный кластер с двумя категориями: ПРОФЕССИОНАЛ и ВОЛОНТЕР 1) Какие типы связей следует использовать? Обоснуйте свой ответ. 2) Укажите кардинальность связи между сущностями НАБЛЮДАТЕЛЬ и НА- БЛЮДЕНИЕ. Обоснуйте выбранные вами значения. Дайте имя этой связи. 3) Какой тип должен иметь категориальный кластер? 4) Перерисуйте схему из ответа на вопрос 74 в соответствии с произведен- ными изменениями. 76. Создайте новую сущность под названием ПРЕДМЕТ. Установите связь меж- ду сущностями ВОЛОНТЕР и ПРЕДМЕТ, 1) Какой тип связи следует использовать в данном случае? Обоснуйте свой ответ. 2) Перерисуйте схему из ответа на вопрос 75, добавив в нее новую сущ- ность и связь. 3) Создайте еще одну сущность под названием ЗАНЯТИЯ, которая будет описывать занятия по некоторому предмету с конкретной группой. Там, где это необходимо, удалите ненужные связи и добавьте новые. Для ка- ждой связи назовите ее тип, укажите кардинальность и выберите имя. 4) Перерисуйте схему из ответа па вопрос 75 в соответствии с измени- вшейся структурой. 77. Отдел внешних сношений университета Highline принимает заявки от ор- ганизаций на тематические доклады. Для обработки заявок отдел хочет создать базу данных. В частности, предполагается вести учет тем, доклад- чиков, сделанных докладов, а также организаций, в которых выступали докладчики от университета Highline. 1) Составьте список возможных сущностей для базы данных «Докладчики». 2) Создайте диаграмму «сущность-связь» стандарта IDE FIX, содержа- щую только сущности (аналогично рис. 2.34). Примите, что связь меж- ду сущностями ДОКЛАДЧИК и ТЕМА имеет вид N:M. 3) Для каждой связи на диаграмме укажите тип, а также минимальное и максимальное кардинальные числа для родителя и потомка. Дайте имена всем связям. 4) Повторите шаги 2) и 3). но добавьте на диаграмму новую сущность, ко- торая позволит устранить связь N:M. 5) Является ли структура, получившаяся в результате ответа на вопрос 4), более удачным решением, чем первоначальная? Обоснуйте свои пред- почтения.
112 Глава 2. Модель «сущность-связь», методы и средства Города® ««« Гж,«оп„»о жиЛья выступавшая ” ^^ХравотастГодном к, крупных городов Сред. “сгоЗп'Х” жпюча» пригороды, с общим кодичктюм иастдения около 2 ГмX. человек. Лгапстпо полег учи местоположения, замости жилья для лип с низким» доходами -а 11 переписных учетах города п его пригород». В пределах этих участков имеется около 250 хм- НИЙ где предоставляется жилье малообеспеченным гражданам . реднем в каждом здании имеется 25 квартир и других единиц жилья 78. Агентство хранит информацию по каждому переписному участку гео- графические границы, типичные доходы населения, имена выборных и главных инвесторов важнейших объектов данного района, основные предприятия, а также прочие демографические и экономические данные. Хранится ограниченное количество информации о криминальной обста- новке. Для каждого здания агентство хранит следующую информацию* наименование, адрес, размер, имя и адрес владельца, имя и адре д ника по закладной, данные о ремонте и реконструкции, а также наличие приспособлений, облегчающих жизнь инвалидов. Кроме того, агентство хранит список всех единиц жилья в здании, включая тип, площадь, число спален, число ванных комнат, наличие кухни и столовой, местоположение внутри здания и различные примечания. Агентство хотело бы иметь дан- ные о среднем числе жильцов на квадратный метр для каждой единицы жилья, но на сегодняшний день не имеет возможностей для сбора и хра- нения такого рода данных. Тем не менее, агентство хранит информацию о том, является ли конкретная единица жилья занятой. Городское агентство бюджетного жилья работает как информационная па- лата и предлагает три основных вида услуг. Во-первых, оно ведет работу с политиками, лоббистами и адвокатскими группами в поддержку закона, который поощрял бы развитие жилья для малообеспеченных через нало- говые льготы, выделение предпочтительных зон развития и другие зако- нодательные стимулы. Для этого агентство предоставляет информацию о жилье для граждан с низким доходом руководству штата, округа и горо- да. Во-вторых, посредством выступлений, семинаров, выставок на съездах и другой PR-деятельности официальные лица агентство прилагает уси- лия к повышению осознания обществом потребности в жилье для ма- лообеспеченных людей. Наконец, агентство предоставляет информацию о таком жилье другим агентствам, работающим с малообеспеченными и бездомными. 1) Составьте список возможных сущностей для базы данных Городского агентства бюджетного жилья. 2) Построите диаграмму «сущность-связь» стандарта IDEF1X. включа- ющую сущности из ответа на вопрос 1).
Вопросы к проекту FiredUp 113 3) Дайте имя каждой связи и убедитесь, что вы правильно определили максимальную и минимальную карди1ылыюсти Может случиться, что в ходе ответа па вопрос 2) вам придется добавить, удалить или изменить тс или иные сущности из перечисленных вами вот вете на вопрос 1). Это нормально и даже типично для процесса моделиро- вания данных. Смело вносите модификации, пока не получите диаграмму, которая, на ваш взгляд, будет правильной. Вопросы к проекту FiredUp Вернемся к проекту FiredUp, который был описан в конце главы 1. Предполо- жим, что фирма FiredUp разработала линию из трех горелок: FiredNow, FiredAlways и FiredAtCamp. Предположим далее, что фирма пролает запасные части для каж- дого типа горелок, а также производит их ремонт. В одних случаях ремонт явля- ется бесплатным, поскольку выполняется в течение гарантийного срока, в других случаях взимается только стоимость деталей, в третьих взимается стоимость деталей и работы. Фирма FiredUp желает вести учет всех этих данных. Когда владельцев фирмы спросили о подробностях, они составили следующий список: КЛИЕНТ: Имя, Улица, Дом, Квартира, Город, Штат, Индекс, Страна, ЭлектронныйАд- рес, Телефон ГОРЕЛКА: СерийныйНомер, Тип, ДатаИзготовления, ИнициалыПроверяющего СЧЕТ-ФАКТУРА: НомерСчета, Дата, Клиент (со списком проданных товаров и ука- занием их стоимости), Сумма РЕМОНТ: НомерРемонта, Клиент, Горелка, Описание (со списком деталей, исполь- зованных при ремонте, и указанием их стоимости, если таковая взимается), Сумма ДЕТАЛЬ: Номер, Описание, Стоимость, ПродажнаяЦена 1. Создайте диаграмму расширенной модели «сущность—связь» для базы данных фирмы FiredUp. Задайте на свое усмотрение минимальную и мак- симальную кардинальность для связей между сущностями. Обоснуйте вы- бранные значения кардинальности. Используйте слабые сущности там, где считаете это нужным. Не используйте подтипы. Укажите идентификаци- онно-зависимые сущности, если таковые имеются. 2- Модифицируйте диаграмму из вашего ответа на вопрос 1, представив сущ- ности СЧЕТ-ФАКТУРА и РЕМОНТ соответствующими подтипами. При каких условиях эта структура окажется лучше, чем предыдущая? 3- Преобразуйте ваш ответ на вопрос 2 в диаграмму стандарта ID X. Вне- сите необходимые изменения, касающиеся подтипов и слабых сущностей. 4- Предположим что фирма FiredUp хочет записывать домашний и мобиль- ный телефон факс и несколько адресов электронной почты своих клиен- тов Модифицируйте свою диаграмму, введя множественные значения атрибутов Телефон и ЭлектронныйАдрес. Можете использовать как диаграм- му расширенной модели «сущность-связь», так и диаграмму стандарта «BEF1X — на ваше усмотрение.
114 Глава 2. Модель «сущность—связь»- методы и средства моделирования 5. Предположим, что фирма FiredUp разрабаплваег различные версии одной и тон же горелки, то есть FiredNow-1, FiredNow-2 и г. д. Модифицируй, те необходимым образом вашу диаграмму из ответа на вопрос 4, чтобы учесть эту ситуацию. Можете использовать как диаграмму расширенной модели «сущность—связь», так и диаграмму стандарта IDEF1X — на ваше усмотрение. Вопросы к проекту Twigs Tree Рассмотрим ситуацию с Самантой Грин, с которой мы познакомились в конце главы 1. Саманта владеет фирмой Twigs Tree, занимающейся стрижкой деревьев. Хотя многие из выполняемых ею работ являются разовыми (например, выкорче- вать дерево или пень), есть и повторяющиеся операции, такие как стрижка де- рева или группы деревьев с периодичностью раз в год или раз в два года. Когда дела идут не слишком хорошо, Саманта звонит бывшим клиентам, напоминая им о своей фирме и о необходимости регулярно подстригать деревья. Отрезанные ветки и стволы Саманта измельчает в стружку с помощью измель- чителя щепы, который она цепляет к своему грузовику. Стружка с него падает прямо в кузов грузовика. Вот уже много лет Саманта свозила стружку в центр переработки, но некоторое время назад ей довелось услышать, что стружку мож- но продавать питомникам и другим организациям для использования в качестве мульчи1. А совсем недавно она узнала, что некоторые из ее собственных клиентов хотели бы сами покупать у нее стружку. Да, как это ни странно, находятся люди, готовые запла тить Саманте за спиливание деревьев и измельчение веток, а потом еще и купить у нее свои собственные опилки как мульчу. «Люблю Америку!», — говорит на это Саманта. Саманта ведет- учет следующих данных: ВЛАДЕЛЕЦ ИмяВладельца, Телефон, Дом, Улица, Город, Штат, Индекс ПОВТОРЯЮЩАЯСЯ_РАБОТА: ПериодВМесяцах, Описание, Плата РАБОТА: ДатаВыполнения, Описание, ПредъявленнаяСумма, УплаченнаяСумма, Дага- Оплаты ДОСТАВКА_СТРУЖКИ: ИмяКлиента, Телефон, Дом, Улица, Город, Штат, Индекс, Дата- Доставки, Количество, ПредъявленнаяСумма, УплаченнаяСумма 1. Для начала предположим, что все выполняемые работы являются повто- ряющимися. Создайте диаграмму «сущность—связь» стандарта IDEF1X для сущностей ВЛАДЕЛЕЦ, ПОВТОРЯЮЩАЯСЯ_РАБОТА и РАБОТА. Смоделируйте связь между сущностями ПОВТОРЯЮЩАЯСЯ_РАБОТА и РАБОТА в виде иден- тификационно-зависимой сущности. Назовите тип каждой связи, укажите максимальную и минимальную кардинальности и дайте имена всем связям. 2. 1 еперь предположим, что все работы являются разовыми. Соответственно, нужно удалить сущность ПОВТОРЯЮЩАЯСЯ_РАБОТА и смоделировать сущ- ность РАБОТА как сильную сущность. Создайте диаграмму «сущность— 1 Мульча — перегной, солома, защищающие почву от испарения, замерзания. — Примеч. перев.
Вопросы к проекту Twigs Tree 115 связь» стандарта IDEF1X, назовите тип каждой связи, укажите макси- мальную и минимальную кардинальности и дайте имена всем связям 3. Объедините своп ответы на вопросы 1 и 2, дав сущности, которая опи- сывает повторяющиеся работы, имя ПОВТОРЯЮЩАЯСЯ_РАБОТА, а сущности, которая описывает разовые работы — РАЗОВАЯ_РАБОТА. Создайте порож- дающую сущность РАБОТА и сделайте сущности ПОВТОРЯЮЩАЯСЯ_РАБОТА н РАЗОВАЯ РАБОТА ее категориями. Создайте диаграмму «сущность связь» стандарта IDEF1X, назовите тип каждой связи, укажите максимальную и минимальную кардинальности и дайте имена всем связям. 4. Добавьте в модель, получившуюся в результате вашего ответа на вопрос 3, сущность ДОСТАВКА-СТРУЖКИ. Для начала предположите, что клиенты, для которых Саманта стрижет и спиливает деревья, никогда не покупают у нее стружку. Создайте для учета продаж стружки новую сущность под на- званием ПОКУПАТЕЛЬ_СТРУЖКИ. Постройте диаграмму «сущность связь» стандарта IDEF1X, назовите тип каждой связи, укажите максимальную и минимальную кардинальности в дайте имена всем связям. 5. Ответьте снова па вопрос 4, но теперь предположите, что клиенты, для ко- горых Саманта стрижет и спиливает деревья, могут также покупать у нее стружку. Для моделирования различных типов клиентов используйте сущ- ности категории, подобно тому, как это сделано в вопросе 3. Создайте диа- |рамму «сущность—связь» стандарта IDEF1X, назовите тип каждой связи, укажите максимальную и минимальную кардинальности и дайте имена всем связям.
Глава 3 Создание моделей данных «сущность—связь»: описание процесса и примеры В этой главе описывается процесс создания моделей данных. Из-за чрезвычай- ной важности этой темы мы подойдем к ней с трех различных позиций. Сначала мы рассмотрим последовательность шагов, которые необходимо предпринять для построения модели данных. Затем, исследовав несколько типичных образцов форм и отчетов, мы научимся создавать модели данных на основе информации, предоставляемой пользователями. В заключение мы рассмотрим практический пример разработки модели данных для университета. Каждый из этих трех под- ходов проливает свет на другие два. Соответственно, лучший способ изучить дан- ную главу — прочитать ее два или три раза. Все три раздела тематически объеди- нены внутри одной структуры. Как отмечалось в главе 2, после того как вы поймете основополагающие идеи, следующим шагом будет попытка применить их на практике, разобрав несколь- ко примеров. Поэтому вам следует ответить на вопросы и выполнить задания, приведенные в конце главы. По возможности используйте один из программных продуктов для моделирования данных, описанных в главе 2. Процесс моделирования данных На рис. 3.1 перечислены шаги, составляющие процесс моделирования данных. Первым шагом является планирование проекта. Основные задачи этого шага — получить «добро» от руководства, обеспечить финансирование, собрать рабочую группу, составить перечень задач и распланировать назначения, договориться об используемых средствах, методах и стандартах, чтобы результаты работы отдель- ных членов группы были согласованы, и определить охват проекта. Определение охвата проекта (project scope) особенно важно при моделировании данных, поскольку в большинстве организаций все взаимосвязано. Например, сущности отдела продаж будут связаны с сущностями отдела кредитов, которые.
Процесс моделирования данных 117 в свою очередь, будут связаны с сущностями отдела отношений с клиентами, а те с сущностями операционного отдела, и т. д. Без четкого указания охвата и рамок проекта процесс моделирования данных может выйти из-под контроля Разуме- ется, наличие таких рамок приведет к тому, что некоторые связи будут нс заданм или просто исключены из рассмотрения. • Планирование проекта • Определение требований —► • Определение сущностей ---- • Определение связей ---- • Определение идентификаторов :• Определение атрибутов • Определение доменов • Проверка модели Рис. 3.1. Шаги процесса моделирования данных Определение системных требований Следующий шаг в процессе моделирования данных — определение системных требований (system requirements), в особенности тех, что непосредственно каса- ются базы данных. Эта обширная и важная тема сама по себе заслуживает не- скольких глав в учебнике системного программирования. Здесь же мы просто рассмотрим традиционные источники требований к моделям данных. Более по- дробно о методах определения системных требований вы узнаете из курса систем- ного программирования. Опрос пользователей и наблюдение за их работой Наиболее распространенные источники требований к моделям данных перечис- лены во врезке. Исключительно ценными источниками являются опрос пользо- вателей н наблюдение за их работой, однако они же оказываются и наиболее ^Рудными в применении. Пользователи, как известно, хотят всего и сразу, но при этом часто забывают важные требования. Пользователь, опрашиваемый в начале вериода, в течение которого проводится опрос, может легко забыть требования, относящиеся к концу указанного периода, и т. д. Решение этих проблем выходит За рамки данной книги, ио является важной темой в курсе системного програм- мчрования. Что касается моделирования данных, цель опроса пользователей состоит в том, чтобы определить перечень потенциальных сущностей и связи между ними. Кро- ме того, важно иметь на руках исходные документы, в частности, формы и отче- ты- которые позволяют выявить возможные сущности и их связи, а также список "«тенциальных атрибутов. Вспомните из «Саги о Брюсе и Зельде», что пользо- “атеди смотрят на данные с различных точек зрения, и порой одна и те же вещь
118 Глава 3. Создание моделей данных «сущность связь» может называться у них разными именами, или наоборот, разные вещи могут быть названы одинаково. Цель опроса пользователей - получить адекватное описание того, как пользователь или группа пользователей представляют свои данные, то есть внешней схемы. ИСТОЧНИКИ ТРЕБОВАНИЙ К БАЗЕ ДАННЫХ --------- ♦ Опрос пользователей. ♦ Наблюдение за действиями пользователей ♦ Существующие формы и отчеты. ♦ Новые формы и отчеты. ♦ Существующие ручные записи. ♦ Существующие компьютерные файлы или базы данных. ♦ Формально определенные интерфейсы (XML). ♦ Предметные специалисты При опросе пользователей следует иметь в виду возможность терминологиче- ских расхождений. ИСТОРИЯ_КЛИЕНТА в бухгалтерии может иметь совсем другое значение, нежели ИСТОРИЯ_КЛЦЕНТА в отделе продаж. Опрашивая пользователей отдела продаж, рискованно считать, что вам известно значение термина история клиента только потому, что вы знаете, как интерпретируется это понятие в бух- галтерии. Результаты опроса пользователей и наблюдений фиксируются в виде заме- ток, набросков, определений элементов данных и т. д. Документация, создава- емая членами рабочей группы, должна быть согласованной и храниться в цен- трализованном информационном репозитории. Формы и отчеты Превосходным (а зачастую и наилучшим) источником требований к модели дан- ных являются формы и отчеты. Имеющиеся документы позволяют определить, как происходит обработка данных в настоящий момент, а новые — указывают на изменения в представлении информации или необходимость отслеживания ка- ких-то дополнительных данных. Образцы заполненных форм и отчетов должны храниться в информационном репозитории. Эти документы будут в дальнейшем использоваться для разработки и проверки модели данных. В следующем разделе мы приведем множество примеров создания моделей данных на основе анализа форм и отчетов. Существующие записи Еще один полезный источник требований — существующие записи. Это могут быть записи, сделанные вручную, например список кодов продуктов в записной книжке или картотеке. 1 акне листки и карточки хранятся в информационном ре- позитории в виде фотокопии. Записи могут иметь и цифровую форму — напри- мер, электронные таблицы или персональные базы данных. Копии таких файлов или выдержки из них следует также внести в информационный репозиторий
Процесс моделирования данных 119 Если имеется база данных большого размера, то с помощью таких программ- ных продуктов, как ERWin или Visio из нее можно реконструировать (reverse engineer) модель данных. Созданные таким способом модели базируются на внутренних схемах и не являются по своей сути концептуальными. Их можно скорее охарактеризовать как описание набора взаимосвязанных таблиц Эти модели, подобно концептуальным моделям, являются полными, но, в отличие от них, не имеют логического характера, а служат лишь представлением физиче- ских структур. Сегодня большие базы данных редко создаются с пуля. Гораздо чаще стоит задача модифицировать уже существующую базу данных. Метод реконструкции играет важную роль в таких проектах. Более подробно эта тема будет рассмат- риваться в главе 8 «Перепроектирование баз данных». Отложить ее обсужде- ние мы вынуждены потому, что для понимания данного материала необходимо знать SQL. Формальные интерфейсы Формальный интерфейс (formal interface) — это стандартизированное внешнее представление. Такие интерфейсы создаются правительственными учреждения- ми, промышленными группами и большими предприятиями для упрощения меж- организационвого обмена данными. Иногда одним из требований к вновь созда- ваемым системам баз данных является получение или выдача данных через такой интерфейс. В этом случае формальный интерфейс также входит в число источни- ков требований к модели данных. Формальные интерфейсы как таковые используются уже много лет, но с по- явлением сети Интернет потребность в межорганизационных стандартах еще более возросла. Публикация и использование таких стандартов в значительной степени упрощаются за счет применения XML. Почти каждая профессия в об- ласти бизнеса или крупная промышленная отрасль уже имеют или разрабатыва- ют собственные XML-стандарты. Языку XML будет посвящена глава 13. Из этой главы вы узнаете о тесной связи, имеющейся между базами данных и XML. Например, как SQL Server, так и Oracle могут записывать и считывать данные в формате XML. Можно ожидать, что в будущем роль формальных интерфейсов будет только увеличиваться и что необходимость поддержки таких интерфейсов станет еще более важным источником требований к модели данных. Предметные специалисты Предметные специалисты (domain experts) — это люди, являющиеся экспертами в определенной области знаний. Например, компания ЗМ имеет предметных специалистов в области абразивных материалов, клеящих веществ, стандартов 11 средств обеспечения безопасности, и т. д. Типичных предметных специалистов обычно можно найти в отделе управления персоналом. Соответственно, они вряд ли будут входить в число пользователей новой базы данных, зато могут предоста- ить важную информацию из своей области знаний, необходимую для построе- ния адекватной модели данных.
Глава 3. Создание моделей данных «сущность связь» Например, компания ЗМ выпускает тысячи и тысячи абразивных продуктов В этих условиях способов реализации связей подтип/надтии или категориаль- ных кластеров может быть множество. Бесценную помощь могут оказать здесь предметные специалисты, просмотрев несметное число потенциальных вариан- тов и отклонив неверные. Однако в работе с предметными специалистами есть и свои минусы Н ни чего опаснее при проектировании базы данных, чем группа «экспертов», сидя- щих за столом и заявляющих: «Если бы я был пользователем...». Только пользо- ватели, и никто другой, могут знать, какие данные и в какой форме нужны пользователям. Таким образом, хотя предметные специалис1ы и мо пролить свет на специфику конкретного проекта, основным источником определения требований к модели данных должны служить сами пользователи. Результатом работы по определению требований будет информационный ре- позиторий, содержащий заметки, схемы, формы, отчеты, файлы и другие мате- риалы, которые могут быть использованы при разработке модели данных. Определение сущностей Определившись с требованиями, рабочая группа может приступать к созданию модели данных. На рис. 3.1 определение сущностей, связей, атрибутов и доменов представлено в виде отдельных последовательных шагов. На самом же деле эти процессы зачастую идут параллельно и развиваются по спирали. Например, при анализе форм и отчетов выявляются как сущности, так и их связи. Кроме того, эти документы могут содержать указания на атрибуты. Таким образом, хотя да- лее мы будем описывать эти процессы раздельно, имейте в виду, что они часто происходят одновременно и носят итеративный характер. Сущность — это некий объект, который пользователи хотят отслеживать, о ко- тором они хотят хранить данные. Часто сущности являются физическими объекта- ми (например, ОФИС или ПРОДУКТ), но они могут представлять собой и абстрактные понятия, такие как ЗАКАЗ, ТРАНЗАКЦИЯ или КОНТРАКТ. Сущности идентифициру- емы, то есть их можно отличить друг от друга. В языковых конструкциях сущно- ши, как правило, следует искать среди членов предложения, выраженных суще- ствительными, а не прилагательными или причастиями. Рассмотрим следующий пример: «Сначала я сортирую заказы по их весу брутто». В аилом предложении объектом действия (сортировки) является ЗАКАЗ (существительное). Для выполнения этого действия используется одна из харак- теристик заказа — его вес в упаковке. Несмотря на то, что слово «вес» является существительным, сама эта характеристика может быть естественно выражена при- частием («весящий»). Таким образом, скорее всего, ВесБрутто является атрибутом, екоторые высказывания пользователей не имеют однозначной интерпрета- ции. Рассмотрим следующее высказывание: «Сначала я сортирую сегодняшние заказы по их весу брутто». Сп °В □ *сегодняшние заказы» могут означать, что сущность ЗАКАЗ имеет атри- бут ДатаЗаказа, и по значению этого атрибута делается выборка из множества
Процесс моделирования данных 121 заказов. Но можно ин^третировать это и так, что мы имеем дело с подтипом, я сущностью-категорией, то есть, например, для порождающей сущности ЗАКАЗ Tpe6yeTc« »n^™ ’нЕ7о'м^шГа ПД?Г0ДНЯ Ш Н И Й-ЗАКАЗ’ ЗАКАЗ.ПОСЛ ЕД НЕЙ. НЕДЕЛИ И ЗАКАЗ.ПОСЛЕДНЕГО.МЕСЯЦА. Оба варианта возможны, и чтобы выяснить, какой ИЗ них подходит лучше, необходимо дальнейшее изучение форм, отчетов я других документов. некоторых случаях в модель данных включаются оба варианта (в нашем примере - и атрибут ДатаЗаказа, и подтипы), а исключение неверного варианта происходит позже в ходе уточнения модели. Рассмотрим языковые конструкции вида «нечто чего-то» («х of у»), например, «телефон клиента», «зона ответственности торгового агента» и «уровень загряз- нения реки». Во всех этих конструкциях упоминаются два логически самостоя- тельных объекта (например, зона ответственности и торговый агент), каждый из которых описывается одиночным существительным или словосочетанием. Почти во всех случаях второй объект (выраженный существительным, изменяемая часть которого стоит в родительном падеже) является сущностью. В приведенных выше примерах сущностями являются соответственно КЛИЕНТ, ТОРГОВЫЙ.АГЕНТ иРЕКА. Первый объект (изменяемая часть которого стоит в именительном падеже) часто является атрибутом, однако это может быть и другая сущность. В приме- рах из предыдущего абзаца телефон и уровень загрязнения будут, скорее всего, атрибутами, а зона ответственности может быть как атрибутом, так и самостоя- тельной сущностью. Далее в этой главе мы покажем, как из форм и отчетов извлекать информацию о сущностях, связях и а трибутах. Пока что следует просто знать, что результатом этой деятельности будет список сущностей, подобный тому, который изображен на рис. 3.2. По мере эволюции проекта этот список будет неоднократно модифи- цироваться. Некоторые из сущностей в этом списке будут признаны синонима- ми, некоторые будут удалены, поскольку не несут интересующей нас информа- ции. Возможно также, что список пополнится новыми сущностями. РАСТЕНИЕ ПОКУПКА КЛИЕНТ ЗАКАЗ ДОСТАВКА ПОКУПАТЕЛЬ ПОДАР ОЧНЫЙ.СЕРТИФИКАТ ВОЗВРАТ СЧЕТ МЕБЕЛЬ a Рис. 3.2. Список сущностей для а — первоначальный вариант; б ПРОДУКТ ПОКУПКА КЛИЕНТ ПОСТАВЩИК ЗАКАЗ ВОЗВРАТ ВОЗВРАТ-ПОСТАВЩИКУ питомника Padden Creek: — окончательный вариант ШоГоП*’СОк на Рис. 3.2 был создан в процессе моделирования данных для неболь- Пей адовоДСтва-пит°мника. Здесь показаны первоначальный набор сушно- набор, который получился по окончании процесса моделирования. ут°Чнения модели рабочая группа рришла к выводу, что необходимость
Глава 3. Создание моделей данных <<сущность Свнзь» в сущностях ДОСТАВКА п ПОДАРОЧНЫЙ_СЕРТИФИКАТ отсутствует. по лому они был* исключены из схемы. Сущности РАСТЕНИЕ и МЕБЕЛЬ были при шаны различными подтипами отсутствующей в первоначальной схеме сущности ТОВАР. Введя эту сущность группа проанализировала требования к модели данных и пришла к вы- воду, что’необходимость в подтипах РАСТЕНИЕ и МЕБЕЛЬ не является нас твой, поэтому данные сущности были удалены В ходе дальнейшей) анализа группа обнаружила, что сущности СЧЕТ и ЗАКАЗ представляют собой синонимы, и в каче- стве предпочтительного термина был выбран ЗАКАЗ. Недостающие щно и ПОСТАВЩИК и ВОЗВРАТ были добавлены в модель. Наконец, рабочая группа реши- ла зарезервировать термин ПОКУПКА для обозначения покупки, сделанной клиен- том у питомника, а термин ЗАКАЗ - для покупки, сделанной питомником у одно- го из поставщиков. Это последнее обстоятельство указывает на необходимость определения зна- чений и способов использования сущностей на стадии выяснения требований. В табл. 3.1 показаны определения, которые использовались в питомнике Padden Creek. Таблица 3.1. Описание сущностей Сущность Описание ТОВАР Товар заказанный у поставщика и приобретенный клиентом. Товары идентифицируются по названию растения или по типу, а не по конкретным экземплярам. Таким образом, товаром может быть «Пион» или «Декоративная кадка», но не конкретные пион или кадка ПОКУПКА Запись о товарах, приобретенных клиентом. Многие покупки регистрируются как сделанные за наличный расчет и не включают информацию о покупателе. К записям о покупках, сделанных при помощи кредитной карты, прилагается квитанция, но цели отслеживать данные кредитной карты клиента не ставится. Данные, идентифицирующие покупателя, записываются при покупках на сумму свыше $150, а также при покупках, совершаемых постоянными клиентами КЛИЕНТ Лицо, приобретающее нечто у питомника Padden Creek ПОСТАВЩИК ЗАКАЗ ВОЗВРАТ ВОЗВРАТ ПОСТАВЩИКУ Идентификационные данные хранятся только для некоторых клиентов Поставщик растений, мебели и других товаров питомнику Padden Creek Заказ товаров у поставщика Запись о товаре, который был возвращен питомнику клиентом Запись о товаре, который был возвращен поставщику питомником Определение связей В модель данных входит описание всех связей между сущностями. Описание связи ж по iaei в соя идентификаторы родительской и дочерней сущностей, тип связи, минимальную и максимальную кардинальности и имя связи. Сущности и их свя- vбычи« С/1ОМО1«Ь№ Диаграмм расширенной модели «сущ- п связь», или UML, а также других стандартизированных методик. Для выявления связей применяются два подхода. Один состоит в том, что рассматриваются все возможные комбинации из двух сущностей для выявления
Процесс моделирования данных 123 •нячи между ними. Если связь признается возможной, пл следующем шаге про 3воД|,тСЯ анализ требований с целью определения кардинальностей и других 1'п’>актер1,СТ1,к связи. При втором подходе информация о связях извлекается Х* иосредственно из документов, описывающих требования к модели данных Иногда используется сочетание обоих подходов. Для исследования всех возможных комбинаций из двух сущностей составляет- ся таблица с именами всех сущностей в строках и столбцах, подобная изображен ной на рис. 3.3. Затем последовательно рассматривается каждая пара сущностей и если связь между этими сущностями возможна, в соответствующую ячейку ставится метка. Например, в первой строке таблицы па рис. 3.3 сущность КЛИЕНТ проверяется на наличие связи с каждой из сущностей базы данных питомника Padden Creek. Здесь потенциальными кандидатами на связь с сущностью КЛИЕН являются сущности ПОКУПКА и ПОСТАВЩИК. ' •- s < ' : : •' , -' - | КЛИЕНТ | ЗАКАЗ 1 1 ПРОДУКТ 1 1 ПОКУПКА I ВОЗВРАТ I ПОСТАВЩИК | ВОЗВРАТ_ПОСТАВЩИКУ | КЛИЕНТ X Y Y ЗАКАЗ X Y ПРОДУКТ Y X Y Y Y ПОКУПКА Y Y X ВОЗВРАТ и Y Y X ПОСТАВЩИК Y X Y ВОЗВРАТ ПОСТАВЩИКУ Y Y X Y -> да, существует потенциальная прямая связь Пусто -> связь маловероятна Рис. 3.3. Таблица потенциальных связей Не существует такого понятия, как односторонняя связь. Если сущность КЛИЕНТ имеет связь с. сущностью ПОКУПКА, то и сущность ПОКУПКА, в свою оче- редь, имеет связь с сущностью КЛИЕНТ. Таким образом, если таблица на рис. 3.3 Полнена правильно, она должна иметь симметричный вид. Бывают, однако, СИтУациц, когда приложение использует некоторую связь только в одном на- бавлении, и никогда - в противоположном. Например, приложение может Житься к сущности ЗАКАЗ и далее найти все связанные с нею сущности "осТАВЩик, но никогда не поступает наоборот - то есть не ищет заказы, связан- Г* с конкретным поставщиком. В этом случае потенциальная диаграмма связей УДет асимметричной. Вообще говоря, так бывает нечасто.
124 Глава 3. Создание моделей данных «сущнос тс Снизь» Выявив возможную связь, рабочая груина ио моделированию данных ан*, лизирует все требования к модели, чтобы определил», существует ЛИ «та связь в действительности. Если да, связь фиксируется в модели данных; если нет а ответствующая ей пометка удаляется из таблицы связей. Если модель данных объемна, использование таблицы связей становится не- целесообразным. Представьте себе модель, содержащую 50 сущностей. Тогда нам придется проанализировать (50 х 50 - 50)/2 - 1225 проверок! Исследовать такое количество сочетаний - долгий, утомительный и трудоемкий процесс, результат которого, скорее всего, не будет стоить затраченных усилий В этой ситуации для выявления связей рабочей группе следует положиться на анализ форм, отчетов и других требований. Определение идентификаторов Каждая настоящая сущность имеет идентификатор — атрибут или группу атри- бутов, которая уникальным образом идентифицирует экземпляр сущности. Если оказывается, что сущность не имеет идентификатора, то либо в ней не хватает каких-то атрибутов, либо она в действительности не является сущностью. Рас- смотрим, например, потенциальную сущность РЕЖИМ_ПОСТАВКИ с атрибутами {Поставщик, Дата, Стоимость}. Ни один из этих атрибутов не является хорошим идентификатором для сущности РЕЖИМ_ПОСТАВКИ. Скажем, атрибут Поставщик мо- жет быть идентификатором сущности ПОСТАВЩИК, но никак не РЕЖИМ_ПОСТАВКИ. Возможно, в данной схеме недостает атрибута СпособПоставки, а может быть, эти атрибуты в действительности относятся к другой сущности — например, ЗАКАЗ. Разумеется, идентификационно-зависимые сущности содержат только часть своего идентификатора. Например, сущность КВАРТИРА имеет идентификатор {Но- мерДома, НомерКвартиры}, но из этих двух атрибутов только НомерКвартиры принад- лежит сущности КВАРТИРА. Атрибут НомерДома принадлежит сущности ЗДАНИЕ — родителю сущности КВАРТИРА в идентификационно-зависимой связи. Таким об- разом, если не удается найти подходящий идентификатор для сущности, которая была классифицирована как не являющаяся идентификационно-зависимой, ино- гда с ши ( проверить, не является она в действительности идентификационно- зависимой от некоторой другой сущности. Может оказаться, что родительская сущность даже отсутствует в модели Сущноети, имеющие одинаковые идентификаторы, следует изучить особен- но пцатсльно. Возможно, они просто синонимичны. Есть также вероятность, чю они являются подтипами, или категориями, одной и той же сущности. 6,0P° лицензирования транспортных средств каждая из сущностей ЛЕГКОВОИ_АВТОМОБИЛЬ, ГРУ30В0Й_АВТ0М0БИЛЬ, ЛОДКА, ТРЕЙЛЕР и САМОЛЕТ может иметь идешификаюр НомерЛицензии. В этом случае возможно, что они все явля- катег°Риями- некоторой обобщенной сущности - скажем, НАЛОГООБЛАГАЕМОЕ_ТРАНСПОРТНОЕ_СРЕДСТВО. Все же в некоюрых редких ситуациях бывает, что две сущности, абсолютно разли шые по своей природе, имеют одинаковые идентификаторы. Например, сущноети ТРУДНИК и БЭЙДЖ могут иметь общий идентификатор НомерСотруд-
Процесс моделирования данных 125 ника. Можно представить сущность БЭЙДЖ как идентификационно-зависимую от сущности СОТРУДНИК, и в этом случае полным идентификатором сущности ЗНАЧОК будет сочетание {НомерСотрудника, ДатаВыдачи}. Иногда выбор между такими альтернативами осуществляется из чисто эстетических соображений. Определение атрибутов и доменов Следующие два шага — определить атрибуты и домены. Обычно атрибуты выяв- ляются при анализе форм, отчетов, существующих файлов и других документов и присваиваются соответствующей сущности. Каждый раз, когда в модель дан- ных добавляется новый атрибут, рабочая группа проверяет, нельзя ли отнести этот атрибут к одному из уже определенных доменов. Если да, этот домен стано- вится доменом данного атрибута. Если нет, определяется новый домен. Изначально каждый новый атрибут будет требовать введения нового домена. По мере продвижения этого процесса, с увеличением количества определенных доменов, вновь создаваемым атрибутам все чаще будут назначаться уже суще- ствующие домены. Закончив с определением атрибутов, полезно просмотреть список доменов на предмет того, не являются ли некоторые из них синонимами или подтипами дру- гих доменов. Внеся соответствующие коррективы, следует еще раз пройтись по списку атрибутов и посмотреть, не требуются ли какие-либо дополнительные изменения в определении доменов. В программах для моделирования данных имеется широкая гамма средств для документирования доменов. Некоторые из них позволяют, определив домен, создавать атрибуты на его основе путем перетаскивания мышью символа домена в прямоугольник сущности. По умолчанию имя атрибута будет совпадать с име- нем домена (при необходимости это имя можно изменить). Наследование свойств доменов В главе 2 обсуждались некоторые практические преимущества использования доменов. Эти преимущес тва обусловлены главным образом тем, что свойства до- мена наследуются всеми атрибутами, принадлежащими к этому домену. Когда свойства доменов изменяются, вместе с ними изменяются и свойства соответ- ствующих атрибутов. Например, если изменится тип данных домена, все атрибу- ты, принадлежащие к этому домену, унаследуют этот тип данных. Кроме типа данных, к наследуемым свойствам доменов относятся определе- ние домена и комментарии. Последнее может показаться тривиальным, однако в действительности комментарии весьма полезны. Например, комментарий, со- общающий, что домен КодДетали базируется на определении, принятом в 2001 го- ду, может иметь важное значение. Если любой атрибут, принадлежащий к до- мен; КодДетали, унаследует данный комментарий, это поможет сэкономить труд 11 предотвратить возможные недоразумения. Наконец, домены имеют такие свойства, как начальное значение и ограниче- ния. Начальное значение — это значение, которое присваивается каждому ново- му экземпляру атрибута, происходящего из данного домена. Ограничения - это
126 Глава 3. Создание моделей даннъоо<суи4ность---связьи правила ограничивающие множество значении, которые может принимать три 6vJ Например, домену КодДетали могут быть присвоен... начальное я. иие Т0000" и ограничение, в соответствии с которым значения атрибутов эго.ю до- мена должны начинаться с символов «Р» или «Z», а за ними должно следов, четырехзначное число. Оба эти свойства будут унаследованы всеми атрибутами, базирующимися на данном домене. Домены как средство реализации политики стандартизации данных Разумеется, можно игнорировать домены и определять каждый атрибут как уни- кальный и независимый от всех остальных. В сущности, как раз это и делается в таких продуктах, как Microsoft Access. Разработчик отдельно задает свойства для каждого столбца таблицы. Идея доменов здесь никак не используется. В организациях подобная практика может привести к несовместимости типов данных и систем. Например, если КодДетали определен в одной системе как целое число в интервале от 10 000 до 99 999, а в другой как строка формата ххппппп, где хх — это буквы «РС», а ппппп — десятичное число, большее или равное 10 000, совместить эти две системы будет сложно. Коды деталей, которые должны со- впадать, будут представляться различными, поэтому потребуется написать специ- альную процедуру, которая бы преобразовывала коды одной системы в коды другой системы. Эта ситуация вдвойне досадна, поскольку в действительности обе системы используют один и тот же код детали, только записывают его в раз- ных форматах. Чтобы предотвратить такого рода несовместимость, некоторые организации разрабатывают так называемые словари данных (data dictionaries), содержащие перечень стандартизированных доменов и описание их свойств. Информацию из этих словарей можно импортировать в программы моделирования данных и ис- пользовать при создании атрибутов. При такой организации работы каждый проект по моделированию данных будет использовать одни и те же стандартизи- рованные компоненты. Естественно, некоторые проекты потребуют определения новых доменов, однако цель состоит в том, чтобы делать это лишь тогда, когда пи один из существующих доменов не подходит. Это относится к функциям администратора данных, которые мы будем обсуждать подробно в главе 9. Атрибуты, указывающие на недостающие сущности и связи И.югда атрибуты могут указывать на необходимость добавления в модель каких- либо сущностей или связей. В частности, признаками недостающей сущности или связи могут быть атрибуты, являющиеся именами или названиями чего-то другого, нежели сущности, которой они принадлежат. Например, наличие у сущности ТОРГОВЫЙ_АГЕНТ атрибута ЗонаОтветственности ЧПНдТтпгштп^ипгтм В°ЗМОЖНО’ следУет ввес™ новую сущность под названием a_uIILIВЬННОСТИ. Если эта мысль верна, атрибут ЗонаОтветственности заменя- ется связью между сущностями ТОРГОВЫЙ_АГЕНТ и 30НА_0ТВЕТСТВЕНН0СТИ. Анало-
Процесс моделирования данн«.. 127 гпчным образом, наличие у сущности ДЕТАЛЬ атрибута Категория наводит на мысль о возможной сущности КАТЕГОРИЯ, имеющей связь с сущностью ДЕТАЛЬ Атрибуты, чьи идентификаторы включают в себя слово «имя» или «название», являются в этом отношении главными подозреваемыми. Так, наличие у сущно- сти ЗАКАЗ атрибута НазваниеТранспортнойКомпании указывает на необходимость введения новой сущности ТРАНСПОРТНАЯ_КОМПАНИЯ, имеющей связь с сущностью ЗАКАЗ. Это явление следует иметь в виду, поэтому, определив атрибуты для всех сущностей, рабочая группа должна исследовать получившуюся модель на пред- мет атрибутов, которые могут служить указанием на недостающие сущности Ра- зумеется, тог факт, что сущность в принципе существует, не означает, что эту сущность непременно нужно добавить в модель. Может оказаться, что хотя вве- дение сущности ТРАНСПОРТНАЯ_КОМПАНИЯ теоретически возможно, реальная по- требность в ней отсутствует. Может быть и так, что определение этой сущности выходит за рамки диапазона охвата проекта. В этом случае наилучши.м способом предохранить модель от «расползания» по организации може т быть как раз со- хранение атрибута ТранспортнаяКомпания. Проверка модели Последним шагом процесса моделирования данных является проверка модели данных. Это, вероятно, самый важный шаг, поскольку если модель данных не- верна, то неверной будет и структура базы данных, построенной на ее основе. Формы, отчеты и другие элементы приложения будут неправильными либо станут конфликтовать со структурой базы данных, из-за чего построение таких отчетов и форм окажется сложным и дорогим процессом. Кроме того, на данном этапе из- менение модели данных сводится просто к изменению диаграммы «сущность- связь», а для модификации уже построенной базы данных могут потребоваться значительные усилия, как вы узнаете из главы 8. Как говорят инженеры-машино- строители, «лучший способ решить проблему — это прежде всего не иметь ее». Что делает модель данных неверной? Один чрезвычайно важный вопрос, которым зачастую пренебрегают из-за кажу- щейся очевидности ответа, — это вопрос о том, что делает модель данных невер- ной. Есть искушение сказать, что модель данных должна отображать реальный мир, и если модель не соответствует реальности, то она неверна. Проблема за- ключается в том, что модели данных вовсе не моделируют реальность. Этот ис- ключительно важный момент труден для понимания, но уяснив его, вы сможете сэкономить себе массу времени, а ваша работа в команде по моделированию дан- ных будет гораздо успешнее. Немецкий философ Иммануил Кант был первым, кто заявил, что наше вос- приятие реальности целиком и полностью детерминировано природой нашего мышления и органов чувств. Здесь можно провес ти аналогию с компьютером: У компьютера имеется фиксированный набор команд, который ограничивает его вычислительные возможности. Мыслительный аппарат человека также имеет
128 Глава 3. Созланиямоделей данных «сущность—связь» -------------- свой «набор команд». Этот набор команд ограничивав. то, что мы мо щм иать, то как мы мыслим. Мир в том виде, как мы его воспринимаем и .наем, Кант называет термином феноменальный мир. Мир вещей самих но себе, вещей, какими они были бы вне нашего восприятия, суть вещей он называет ноуменальным миром Как человеческие существа, мы не можем ничего знать о ноуменальном мире Все это говорится к тому, что нельзя аргументированно предпочесть какую- либо модель на том основании, что она является лучшим представлением «ре- ального мира». Никто из нас не знает ничего о «реальном мире». Наш мысли- тельный аппарат не позволяет нам знать о нем. Возможно, вы скажете: «Постойте, но ведь есть модели, которые лучше дру- гих отображают то, что люди называют термином реальный мир. Например, сущность ПОЖАРНАЯ-МАШИНА с атрибутами КоличествоПарусов и ДатаПоследне- гоПовышенияВЗвании будет крайне неудачной моделью, поскольку пожарные ма- шины не имеют парусов и их никогда не повышают в звании». Чтобы ответить на этот вопрос, прежде всего следует сказать, что человек соз- дает модели ноуменального мира с помощью своего мыслительного аппарата. На протяжении всей человеческой истории лучшими моделями были те, которые наиболее эффективно помогали нашему виду в деле выживания. Это все, что можно сказать по данному поводу. Мы не можем утверждать, что эти модели являлись наиболее адекватным представлением ноуменального мира, поскольку мы не в состоянии ничего знать об этом мире. Единственное, что мы можем постулировать, — это что упомянутые модели работают достаточно хорошо для того, чтобы люди могли мыслить и общаться друг с другом способом, который по сию пору обеспечивал выживание человечества как биологического вида. Если распространить эти рассуждения на мир компьютеров, можно сказать следующее: модель данных моделирует не реальность, а существующую в чело- веческом представлении модель реальности, какой бы она ни была. Модель дан- ных, описывающая пожарную машину, — это модель существующей в человече- ском представлении модели пожарной машины. Если вы еще не потеряли нить дискуссии, вы можете возразить: «Но челове- ческих моделей пожарной машины могут быть сотни! Некто, видевший пожар- ную машину только на фотографии, имеет одну модель, кто-то другой, чей дом был спасен от от ня пожарной машиной, имеет другую модель, а третий, прорабо- тавший пожарным в течение 30 лет, тоже имеет свою модель, отличную от этих двух. Какую из моделей мы должны взять за основу для нашей модели данных?» Вот этот вопрос ведет нас в правильном направлении, и на него у нас есть от- ве i. Мы должны построить такую модель данных, которая наилучшим образом моделирует ментальную модель, существующую в представлении пользователей системы. Точка. Нам необходимо знать, насколько адекватно наша модель отра- жает то, как пользователи представляют свой мир. Я лично потерял десятки, если не сотни часов на встречах, где кто-то пытался обосновать свою модель данных, говоря, что это «лучшая модель реальности». Очевидно, что любой человек, обладающий другим жизненным опытом и ду-
Процесс моделирования данных 129 мающий по-другому, будет иметь другую «модель реальности» и, соответствен' но, будет возражать против э того утверждения. Особенно тяжело, когда такого рода спор происходит между двумя моделистами, пытающимися обосновать не просто две различные внешние схемы (которые, возможно, удастся интегрировать, как в случае с Брюсом и Зельдой), а две различные версии одной и той же концеп- туальной схемы. Как вы знаете, концептуальная схема может быть только одна. Подведем итог: никому не подвластно создание модели, являющейся адекват- ным представлением реальности. Вместо этого люди создают ментальные моде- ли реальности, более или менее удачно функционирующие для целей выжива- ния. В свою очередь, специалисты по моделированию данных создают модели этих ментальных моделей. Единственно уместным вопросом при тестировании модели данных является следующий: «Насколько хорошо данная модель соот- ветствует ментальным моделям людей, которые будут пользоваться этой систе- мой?» Сам разработчик, занимающийся моделированием данных, может считать, что конструируемая им модель представляет собой довольно странный способ восприятия мира, однако это не должно его заботить. Единственное, что должно иметь значение, — это то, насколько его модель соответствует пользовательско- му видению мира. Надеюсь, теперь, когда вы поняли, что является объектом моделирования, вы никогда не будете говорить. «Моя модель является лучшей моделью реально- сти». Ничего подобного быть просто не может1. Методы проверки модели данных Наиболее распространенный способ проверки модели данных — посредством се- рии обсуждений. Сначала рабочая группа по моделированию данных проводит обсуждение модели данных в своем кругу. Иногда команда из нескольких членов рабочей группы, создавшая часть модели, представляет результаты своей работы тру 1 он команде, создавшей другую часть модели. В процессе обсуждения модель проверяется на соответствие системным требованиям. Разумеется, если требова- ния не очень четкие, то обсуждение может быть лишь поверхностным. Это еще о ша причина, по которой столь важно задать как можно более исчерпывающий набор требований. В ходе обсуждений рабочая группа проверяет, все ли требования, выявлен- ные как при опросе пользователей, так и в процессе наблюдения за их работой, Переводя обсуждение на столь глубокнЛ философский у,х>вень. автор неосторожно упускает из виду 04,111 с> щественнын момент. Дело в том. что пользователи также являются для разработчика частью внешне го мира Сасдовательно. если исходить из принципиальной непознаваемости этого мира, кото- рую так настойчиво подчеркивает автор, то утверждение: «Моя модель более адекватно представляет пользовательскую модель реальности» имеет подсобой ничуть не больше оснований, чем утвержде- ние «Моя модель более адекватно представляет реальность». Нам видится, что объяснение может ’ЫТ^Г?₽а‘,Л0 ,,РОЩС вза"мояеГ,ств“е пользователей с информационной системой оказывается бо- * аффективным. если структура этой системы отражает представления пользователей о деловом еш1 ' И,1ЫМИ <ловам,ь если система «говорит на одном языке» с пользователями. Кроме того есть 1 старое как мир правило: «Клиент всегда прав». - Примеч. пере».
130 Глава 3. Создание моделей данны ^сущность—связь» поддерживаются моделью данных. Кроме тою. группа должна убедиться, что сконструированная ею коицеигуальиая схема позволяет строить все внешние схемы, соответствующие требуемым формам и отчетам. Если предусмотрена поддержка внешних интерфейсов, группа исследует модель данных с целью удо- стовериться, что все требования этих интерфейсов выполняются. На стадии об суждений в рабочей группе часто возникают вопросы, касающиеся требований. Эти вопросы необходимо записывать, чтобы получить разъяснения от пользова телей на следующем этапе. После того как будут исправлены недочеты в модели данных, обнаруженные в ходе обсуждения в рабочей группе, проводится второй раунд обсуждений, на этот раз с самими пользователями. Обычно в данном процессе участвуют один или два «ключевых» пользователя из каждой группы, которая будет работать с новой системой. На этом этапе пользователи дают ответы на все вопросы, воз- никшие при обсуждении модели данных в кругу разработчиков. Кроме того, не- которые аспекты модели могут быть решены исходя скорее из художественных предпочтений, чем из насущной необходимости. Например, одна и та же цель может быть достигнута несколькими способами. В этом случае пользователей просят прокомментировать различные альтернативы. Лучший (но не всегда возможный) способ проведения опроса пользователей — объяснить им значения символов, используемых на диаграмме «сущность—связь», и попросить их дать комментарии по поводу модели данных, как она изображена на диаграмме. Хотя пользователям эта символика вряд ли будет знакома, многие из них способны ее понять и эффективно использовать. Иногда, однако, пользователи будут не способны или не склонны обсуждать модель данных в формате диаграммы «сущность—связь». В таких случаях необ- ходимо сконструировать образцы форм и отчетов, которые отражали бы проект- ные решения, реализованные в модели данных. Например, образец бланка зака- за, в котором есть место для указания имени только одного агента, отражает тот факт, что кардинальное число связи между заказом и агентом на стороне послед- него равно 1. Если пользователь спрашивает: «А куда мне вписать второго аген- та?», очевидно, что максимальное кардинальное число в этом случае должно быть больше единицы. Эгу идею можно развить еще дальше, создавая прототипы форм и отчетов. Однако построение таких прототипов может быть дорого, и часто они делаются юлько для наиболее критичных аспектов модели данных. Проверка модели данных — сложная тема, и ей можно было бы посвятить не одну главу. Но все же лучший способ научиться моделированию данных и провер- ке моделей — поработать вместе с опытными разработчиками моделей над реаль- ными проеюами. В этой области ничто не может заменить собственный опыт. Результатом фазы проверки является модель данных, которая, по мнению разработчиков и пользователей, обладает достаточной устойчивостью для удов- летворения всех требований к новой системе. На основе этой модели можно раз- рабатывать реальную базу данных и другие компоненты.
Построение моделей данных на базе анализа форм и отчетов 131 Построение моделей данных на базе анализа форм и отчетов В этом разделе описывается процесс построения моделей данных, основыва- ющийся на анализе форм и отчетов. Мы будем использовать символы стандарта IDEF1X, но в принципе годится любая методика моделирования. Ваша цель должна состоять в том, чтобы понять, как интерпретировать пользовательские документы и трансформировать объекты, представленные в них, в сущности и связи. Одиночные сущности На рис. 3.4, а показан отчет, в основе которого лежит одиночная сущность под на- званием ИНВЕНТАРЬ. Мы знаем, что речь идет об одиночной сущности, поскольку все присутствующие в отчете атрибуты относятся к одной и той же теме. Сущ- ность ИНВЕНТАРЬ изображена на рис. 3.4, б. ИНВЕНТАРНЫЙ ЯРЛЫК: ИнвентарныйНомер: 100 Описание: Стол ДатаПриобретения: 27.02.2002 Стоимость: $350.00 ИНВЕНТАРНЫЙ ЯРЛЫК: ИнвентарныйНомер: 200 Описание: Лампа ДатаПриобретения: 01.03.2002 Стоимость: $39.95 а ИНВЕНТАРЬ ИнвентарныйНомер Описание ДатаПриобретения Стоимость б Рис. 3.4. Одиночная сущность: а — отчет, базирующийся на одиночной сущности; б — сущность, описывающая отчет с рис. 3.4, а Одиночные сущности, не имеющие связей с другими сущностями, встречают- ся крайне редко. Они действительно существуют, но когда вы обнаруживаете та- кую сущность, следует присмотреться к пей повнимательнее. Может оказаться, что эта сущность участвует в связи, которая демонстрируется другой формой или отчетом. Например, в отчете о проекте может быть приведен список инвен- таря, задействованного в этом проекте. В таком случае надо пересмотреть опре- деление сущности ИНВЕНТАРЬ и включить в него эту связь. В последнем разделе этой главы вы увидите примеры того, как эволюционируют сущности и связи в процессе уточнения модели данных.
132 Глава 3. Создание моделей данных «сущность зязь» Идентифицирующие связи принадлежности ГостнничньЯ счет, изображенный на рис. 3.5, а, ян шстся примером отчета, со- повторяющиеся «„«. Зд«ь группа (Дата. Категория, Стоииость) SZeror в документе несколько раз. Такая повторяющаяся группа указывает I” °™что базовая Сущность (пазовом се ГОСТИНИЧНЫМ .СЧЕТ) может быть свяггава С несколькими экземплярами некоторой другой сущности (назовем се СТРОКА- РАСХОДОВ). ОТЕЛЬ ГРЭНДВЬЮ Си Блафс, Калифорния Номер счета: 1234 Дата поселения: 12.10.2003 Имя клиента: Мэри Джонс 10.12.2003 Проживание $ 99.00 10.12.2003 Питание $ 37.55 10.12.2003 Телефон $ 2.50 10.12.2003 Налог $ 15.00 10.13.2003 Проживание $99.00 10.13.2003 Питание $47.90 10.13.2003 Налог $ 15.00 Итого $315.95 ГОСТИНИЧНЫЙ_СЧЕТ НомерСчета ДатаПоселения ИмяКлиента Итого СТРОКА_РАСХОДОВ ДатаНачисления КатегорияРасходов Сумма --------б------- Итого $315.95 а Рис. 3.5. Идентифицирующие связи принадлежности: а — образец счета; б — идентифицирующая связь принадлежности Но какой тип связи имеет место быть между сущностями ГОСТИНИЧНЫЙ_СЧЕТ и СТРОКА_РАСХОДОВ? Это определенно связь принадлежности, но какого рода — идентифицирующая или нендептифицнрующая? Группа вроде {12.10.2002, Но- мер, $99.00} не имеет смысла вне гостиничного счета. Сама по себе эта группа представляет собой просто некие данные, без всякого контекста. Поэтому связь являегся идентифицирующей, как показано на рис. 3.5, б. Обратите также вни- мание, что для того, чтобы уникальным образом идентифицировать отдельную строку расходов в контексте конкретного счета, необходим композитный иден- тификатор вида {ДатаНачисления, КатегорияРасходов}. Из отчета на рис. 3.5, а мы не можем определить минимальную кардиналь- ность связи между сущностями ГОСТИНИЧНЫЙ.СЧЕТ и СТРОКА_РАСХОДОВ. Она мо- жет быть либо «ноль ко многим», либо «один ко многим». Это пример вопроса, ответ на который дается пользователями. Создается ли счет прежде, чем по- явятся какие-либо расходы, или нет? Пускай в данном случае ответ будет поло- жительный. Тогда минимальное кардинальное число будет равняться нулю, что
Построение моделей данных на базе анализа форм и отчетов 133 и демонстрирует рис. 3,5, б. (Если бы минимальное кардинальное число равня- юсь 1. рядом с закрашенным кружком стоял бы индекс Р.) С противоположной стороны связи минимальное кардинальное число равно 1, поскольку каждая идентификационно-зависимая сущность должна иметь (юдителя. Па рпс. 3.6, а показана вторая версия гостиничного счета, в которой имеется два повторяющихся элемента: один из них — это данные строки расходов, а дру- I ой — имя клиента. Поскольку эти группы не зависят друг от друга, для их пред- ставления используются две различные связи. На рис. 3.6, б изображены две идешификациоипые связи принадлежности, соответствующие этим двум повто- ряющимся группам. ОТЕЛЬ ГРЭНДВЬЮ Си Блафс, Калифорния Номер счета: 1234 Имя клиента: Мэри Джонс Фред Джонс Сэлли Джонс Дата поселения: 12.10.2003 10.12.2003 10.12.2003 10.12.2003 10.12.2003 Проживание Питание Телефон Налог $ 99.00 $ 37.55 $ 2.50 $ 15.00 Итого $315.95 10.13.2003 10.13.2003 10.13 2003 $ 99.00 $ 47.90 $ 15.00 Проживание Питание Налог а ГОСТИНИЧНЫЙ СЧЕТ СТРОКА_РАСХОДОВ КЛИЕНТ ДатаНачисления КвтегорияРасходов Сумме ИмяКлиента Рис. з.е. Гостиничный счет с двумя повторяющимися группами: а — образец счета; о — две идентифицирующие связи принадлежности
134 глава 3. Создание моделей панны» .сущность-связь- сплвниге пне 36 с рис. 3.7. Здесь иАе.пифищщиОШ.о-з.висимщ, сушиоеп СЛОЖНАЯ ОТОКА РАСХОДОВ содержит в себе другую илептифиющисиио-ззвисн ™ С,ЩЙ« Ь (ПОДОТРОКА_ААСХОДОВ). На рис. 3.7, б. таким образом, имеется еще Х^тифипируюша» связь принадлежности - связь между сущностями СЛОЖНАЯ СТРОКА РАСХОДОВ и ПОДСТРОКА РАСХОДОВ. ОТЕЛЬ ГРЭНДВЬЮ Qu ВлаФсЛалиЛОЦния Номер счета. 1234 Дата поселения: 12.10.2003 Имя клиента Мэри Джонс ГОСТИНИЧНЫЙ.СЧЕТ НомерСчета ДатаПоселения ИмяКлиента Итого 10.12.2003 Проживание $99.00 10.12.2003 Питание Завтрак $ 15.25 Обед $ 22 30 $ 37.55 10.12.2003 Телефон $ 2.50 10.12.2003 Налог $ 15.00 10.13.2003 Проживание $ 99.00 10.13.2003 Питание Завтрак $ 15.25 Закуска $ 5.50 Обед $ 27.15 СЛОЖНАЯ_СТРОКА_ РАСХОДОВ ДатаНачисления Категория Расходов ВсегоПоКатегории ПОДСТРОКА_РАСХОДОВ Подкатегория Сумма б $ 47.90 10.13.2003 Налог $ 15.00 Рис. 3.7. Гостиничный счет с вложенными группами: а — образец счета; б — вложенные идентифицирующие связи принадлежности Неидентифицирующие связи принадлежности На рис. 3.8 и 3.9 приведены примеры неидентифицирующих связей принадлеж- ности. На рис. 3.8, а в поле Закреплен за сотрудником есть место для имени одного < /дника, а в поле Служебный автомобиль — для названия одного автомобиля. Таким образом, из этих форм следует, что максимальная кардинальность связи между сущностями АВТОМОБИЛЬ и СОТРУДНИК равна 1:1. Сущности и связи, моде- лирующие ситуацию, показаны на рис. 3.8, б. Ин формации о минимальной кардинальности связи, представленные на рис. 3.8, а, формы не несут. Об этом следует спросить пользователей. Одна из возможностей показана на рис. 3.8, б\ здесь каждый автомобиль должен быть
Построение моделей данных на базе анализа форм и отчетов 13В закреплен за одним сотрудником, ио отдельно взятый сотрудник не обязан иметь служебный автомобиль. ДАННЫЕ ТРАНСПОРТНОГО СРЕДСТВА Номер лицензии Серийный номер Производитель Тип | Год выпуска | Цвет Закреплен за сотрудником ДАННЫЕ О СОТРУДНИКЕ Имя сотрудника Номер сотрудника Почтовый ящик Отдел | Телефон Код оплаты Код квалификации Дата приема на работу Прикрепленный автомобиль а ТРАНСПОРТНОЕ СРЕДСТВО НомерЛицензии СерийныйНомер Произеодитель Тип ГодВыпуска Цвет СОТРУДНИК НомерСотрудника ИмяСотрудника ПочтовыйЯщик Отдел Телефон КодОплаты КодКвалификации ДатаНайма 1 б Рис. 3.8. Неидентифицирующие связи принадлежности вида 1:1: а — образец формы; б — неидентифицирующая связь принадлежности На рис. 3.9, а изображена ситуация, которая часто возникает на практике. От- чет' о занятости общежития демонстрирует связь между общежитием и студента- ми, которые в нем проживают. Однако форма с данными о студенте не содержит информации о связи студента с каким-либо общежитием. Указанием на такую связь может служить атрибут МестныйАдрес, но в действительности местный адрес не обязательно должен быть названием общежития. Это пример случая, когда нет даже намека на одну из сторон связи. Как уже отмечалось выше, не бывает такой вещи, как односторонняя связь. Если А связано с Б, то и Б связано с А, и никак иначе. Поэтому когда вы обна- руживаете две сущности, имеющие связь только в одном направлении, ищите свидетельства наличия этой связи с другой стороны. Если вам не удается найти ни одной формы или отчета, которые бы демонстрировали обе стороны связи, необходимо узнать кардинальные числа связи с недостающей стороны от поль- зователей. На рис. 3.9, б показано, что связь между сущностями ОБЩЕЖИТИЕ и СТУДЕНТ имеет вид «О ко многим», то есть студент не обязан жить в общежитии, хотя и может.
136 Глава 3. Создание моделей данных < Г ОТЧЕТ О ЗАНЯТОСТИ ОБЩЕЖИТИЯ , , Общежитие Ингерсолл Има£.туайнта Адамс, Элизабет Бейкер, Рекс Бейкер, Брайди Чарльз, Стюарт Скотт, Салли Тейлор, Линн Ответственный ПР°«ич-|«-щии Сара и Аллен Френч №'.13 710 104 744 319 447 810 3-556? Курс 80 FR JN so so FR а ОБЩЕЖИТИЕ СТУДЕНТ НазваниеОбщежития НомерСтудента ОтветстеенныйПроживающий Телефон ИмяСтудента Специализация Руководитель Курс Школа ПредыдущийКолледж МестныйАдрес МестныйТелефон ОБЩЕЖИТИЕ НазваниеОбщежития _ДолжностьАссистента_ Телефон _Проживание_ ИмяСтудента Специализация Руководитель Курс Школа ПредыдущийКолледж МестныйАдрес МестныйТелефон СТУДЕНТ НомерСтудента б е Рис. 3.9. Неидентифицирующие связи принадлежности вида 1:14: а — образцы форм неидентифицирующая связь принадлежности; в — использование связи для представления ответственного проживающего
Построение моделей данных на базе анализа форм и отчетов 137 Рисунок 3.9, а ставит перед памп интересную дилемму. Обратите внимание, что сведения об ассистенте по общежитию входят в информацию об общежитии Однако ассистент является студентом. Поэтому, вместо того чтобы помещать атрибут АссистентПоОбщежигию в сущность ОБЩЕЖИТИЕ, можно создать вторую связь между сущностями ОБЩЕЖИТИЕ и СТУДЕНТ, которая представляла бы ноле Ассистент по общежитию. Эта альтернатива изображена на рис. 3.9, в. Но и у этой структуры есть свой недостаток. Согласно отчету о занятости об- щежития, ассистентами по общежитию являются Сара и Аллен Френч. Однако это семейная пара, а не отдельный студент. Означает ли это, что, кроме сущности СТУДЕНТ, нам потребуется еще и сущность СЕМЕЙНАЯ_ПАРА? Соответствующие исправления внести можно, единственный вопрос — будет ли результат стоить того. Вполне возможно, что представлять ассистента с такой точностью и не нужно и что поле Ассистент по общежитию имеет скорее характер примечания, чем указания на связь с определенным студентом пли семейной парой. Это дилемма являет собой весьма показательный пример решений, которые приходится принимать в процессе моделирования данных. Четкого ответа на та- кого рода вопросы не существует: решение должно приниматься на базе скорее .эстетических предпочтений, чем инженерных принципов. Лучшее, что можно сделать, — обсудить эти вопросы с пользователями, по они вряд ли будут в состоя- нии попять все нюансы проблемы, и еще мепыпе шансов, что им вообще будет какое-то дело до этого. Возможно, пн один из подходов не будет полностью удовлетвори тельным, так что вам придется выбирать, чем пожертвовать. Неспецифические (N:M) связи Па рис. ЗЛО, а показаны две формы из книжного магазина, указывающие на необ- ходимость связи вида N:M. Кинга связана с множеством авторов, а автор связан с множеством книг. Соответствующая диаграмма модели IDEF1X изображена па рнс. ЗЛО, 6. Как вы помните из главы 2, некоторые люди считают, что несиецпфнческих связей не существует и что всегда есть какая-то недостающая сущность, посред- ством которой связь N:M может быть разбита па две связи 1:N. Случай с книж- ным магазином представляет собой контрпример к этому утверждению. Мы, ра- зумеется, можем вообразить для этой ситуации какие-то недостающие сущности, по нее они будут выглядеть здесь ненатурально. Не существует какой-либо есте- ственной сущности, которая бы могла стоять между сущностями АВТОР и КНИГА. Следовательно, в этом случае связь нужно оставить в модели данных как име- ющую вид N:M. или песнецпфическую. Что делать с такими связями, вы узнаете чл главы 5, где будет обсуждаться проектирование баз данных. Рассмотрим теперь другую связь вида N:M, которая имеет место в архитек- турной фирме Предположим, из опроса пользователей был сделан вывод о иеобхо- димостн сущностей АРХИТЕКТОР и ПРОЕКТ. Пусть для выявления потенциальных рабочая группа использует диаграмму, подобную изображенiioii на рис. 3.3.
138 Глава 3. Создание моделей давньпо^ун^ uu> inxiiTCKTopV может бЫ1ь И" |1КК,)ЛЬК„ т«™ екгов. и на ОДИН „ ПРОЕКТ должна иметь вид N М образом, связь между сущностям и АРХИ i см и АВТОР Имя ГодыЖизни КНИГА ISBN Название >-------- Издательство ДатаКопирайта б Рис. 3.10. Связь N:M: а — образец формы; б — неспецифическая связь Однако на более позднем этапе группа обнаруживает отчет о назначениях архитекторов на проекты (рис. 3.11, а). Этот отчет демонстрирует необходи- мость еще в одной сущности — НАЗНАЧЕНИЕ. Согласно рис. 3.11, б, сущность НАЗНАЧЕНИЕ имеет две идентифицирующих связи принадлежности: одна — с сущ- ностью ПРОЕКТ, а другая — с сущностью АРХИТЕКТОР. Из опроса пользователей разработчики модели выясняют, что каждый архитектор имеет по меньшей ме- ре одно назначение, но при этом могут быть проекты, на которые не назначен ни один архитектор. Соответствующие минимальные кардинальности показаны на рисунке. Сущность НАЗНАЧЕНИЕ не имеет собственного идентификатора. Как и свой- ственно сущностям, являющимся подчиненной стороной в двух связях, она будет иметь идентификатор, являющийся комбинацией из двух идентификато- ров, унаследованных от сущностей АРХИТЕКТОР и ПРОЕКТ. На рис. 3.12 показан третий пример неспецифических связей. Теперь речь идет о самолетах, пилотах и рейсах. Здесь мы имеем сильную сущность под названием РЕЙС, у которой есть две связи принадлежности: одна с сущностью САМОЛЕТ, а другая с сущностью ПИЛОТ. Различие между рис. 3.11, б и 3.12, б со- стоит в том, что сущность РЕЙС имеет собственный идентификатор, НомерРейса, а связи, в которых участвует эта сущность, не являются идентифицирующими.
Построение моделей данных на базе анализа форм и отчетов 139 Отчет о назначении на проект Название проекта Дом Абернати Менеджер проекта Дж. Смит Начало проекта 11.11.2003 Окончание проекта Архитектор Б. Джексон Телефон 232-8878 Номер офиса J-1133 Начало работы по назначению 12.15 2003 Окончание работы по назначению 3.15 2004 Максимальные трудозатраты по бюджету 345 Максимальные затраты на трудовые ресурсы $27,500 Максимальные затраты на материальные ресурсы $17,500 а ПРОЕКТ НазваниеПроекта МенеджерПроекта НачалоПроекта ОкончаниеПроекта АРХИТЕКТОР НАЗНАЧЕНИЕ НачалоНазначения ОкончаниеНазначения МаксТрудозатраты МаксЗатратыТруд МаксЗатратыМат ________.__________J б Рис. 3.11. Связь, описывающая назначение а — отчет о назначении; б — две идентифицирующие связи принадлежности Рассмотрим диаграммы на рис. 3.10, б, 3.11, б и 3.12, б как некоторую общ- ность. Они образуют континуум возможных связей вида N;M. На рис. 3.10, б сущ- ности КНИГА и АВТОР не имеют между собой никакой промежуточной сущности, и связь между ними моделируется как связь вида N:M. Ни во что другое эта связь не преобразуется. На рис. 3.11, б связь между сущностями ПРОЕКТ и АРХИТЕКТОР, на первый взгляд, имеет вид N:M, но потом обнаруживается промежуточная сущность НАЗНАЧЕНИЕ, которая разбивает данную связь на две связи вида 1:N. рис. 3.12, б ситуация сходна с той, которая имеет место на рис. 3.11, б, но сущность РЕЙС является сильной, а не идентификационно-зависимой. В теории, сущности САМОЛЕТ и ПИЛОТ могли бы иметь связь вида N:M, однако этого не про- исходит благодаря наличию сильной сущности РЕЙС.
140 Гиява 3. Создание ^УН ЭДНАЯДИКОН Я АВИАКОМПАНИЯ ------------------ ---ЛДТА 30 07.2003 ИСХОДНЫЙ ПУНКТ Сиэм ПУНКТ НАЗНАЧЕНИЯ Гонконг ТОПЛИВО НА ВЗЛЕТЕ ВЕС НА ВЗЛЕТЕ_________________________________- САМОЛЕТ Хвостовой номер njzjct ТиП 7148 Вместимость_ 140 _______________________________ ПИЛОТ Имя Номер Часов налета Майкл Нильсон 32887 18,348 ЙЙЙ «моте Межодиаролной а САМОЛЕТ ХвостовойНомер Тип ОбщаяНаработкаПланера ОбщаяНаработкаДвигателя НаработкаДвигателяПослеКапре монта ТекущаяВместимость ДапьностьПолетаПоКонфигурации и ПИЛОТ Номер Имя НомерСоциальнойСтраховки Адрес Город Штат Индекс Телефон ЭкстрТелефон ДатаПоследнегоВылета Часы ДатаПоследнегоОсмотра РЕЙС НомерРейса Дата ИсходныйПункт ПунктНазначения Толли воНаВзлете ВесНаВзлете б 1 i < £ 1 с I Рис. 3.12. Потребность в сильной сущности РЕЙС: а — образец документа; б — две неидентифицирующие связи принадлежности
Построение моделей данных на базе анализа форм и отчетов 141 Подтипы и категории Подтипы и категории сущностей1 могут возникать и процессе моделирования данных по разным причинам. Иногда разработчики обнаруживают, что есть не- сколько сущностей, которые описывают одно и то же. Например, в питомнике Padden Creek сущности РАСТЕНИЕ и МЕБЕЛЬ оказались вариациями одной и той же сущности ПРОДУКТ (см. рис. 3.2). А иногда при анализе идентифицирующей связи выясняется, что идентификационно-зависимая сущность не имеет другого идентификатора, кроме идентификатора родительской сущности. В таких случаях рассматриваемая сущность является категорией, или подтипом, а не идентифика- ционно-зависимой сущностью. Иногда сами формы могут наводить на мысль о необходимости подтипов или категорий. Так, например, затененная часть формы на рис. 3.13, а показывает, что имеется два вида постоянных лицензий на вылов рыбы. Когда вам встречаются формы с затененными полями и другими характеристиками, указывающими на различные типы чего-либо, подумайте о том, чтобы ввести подтипы, или категории. На рис. 3.13, бив показаны две разные версии диаграммы стандарта IDE1X, моделирующей ситуацию с лицензированием рыбной ловли. Во второй версии определена сильная сущность СУДНО, являющаяся самостоятельной по отноше- нию к сущности КОММЕРЧЕСКАЯ_ЛИЦЕНЗИЯ. Обратите внимание, что сущности- категории (пли подтипы) могут иметь не только различные атрибуты, но и раз- личные связи с другими сущностями. Выбор между этими двумя схемами будет содержать в себе долю эстетических предпочтений. Обе схемы могут считаться правильными. Скорее всего, решение будет определяться тем, есть ли где-либо еще надобность в сущности СУДНО. Если нет, го можно использовать вариант на рис. 3.13, б. Модель ЗАКАЗ Завершим мы этот раздел анализом формы, которая настолько распространена, что вы должны значь, как ее смоделировать, просто исходя из своего жизненного опыта. Кроме того, это пример формы, в основе которой лежат сразу несколько сущностей. На рис. 3.14, а изображена форма заказа для мебельной фирмы. Черные линии на .ной форме представляют границы между сущностями. Сначала идет сущность, описывающая саму форму (ЗАКАЗ), затем черная линия, затем данные о покупа- теле (КЛИЕНТ), снова черная линия, затем данные о продавце (ТОРГОВЫЙ_АГЕНТ). Таблица представляет многозначную группу, которая моделируется зависимой сущностью СТРОКА_ЗАКАЗА. Исследовав строку заказа, вы обнаружите, что в ней содержатся как данные, относящиеся к самому заказу' (количество и стоимость), так и описания отдельных товаров. Следовательно, имеется потребность в само- стоятельной сущности ТОВАР. Подтипы относятся к расширенной модели «сущность—связь», а сущности-категории — к модели н)1 FIX Как вы знаете из главы 2. они несколько различаются (сущности-категории, пршщдлежа- Щие одному категориальному кластеру, всегда являются взаимоисключающими). Здесь это различие несущественно, и мы используем оба термина как эквивалентные.
142 Глава 3. Создание моделей данных «сущность-свяАл Лицензия на ловлю рыбы Сезон 2003 г Штат ххххх Номер лицензии* 03-1123432 Имя. - — Улица' Город: I Штат: [ | Индекс: Только для коммерческой ловли Только для спортивной ловли Номер судна. Количество лет по данному адресу: Название судна: Номер лицензии прошлого года: Тип судна: Налоговый идентификатор: а ЛИЦЕНЗИЯ_НА_ЛОВЛЮ НомерЛиценэии Имя Улица Город Штат Индекс КОММЕРЧЕСКАЯ_ЛИЦЕНЗИЯ СПОРТИВНАЯ ЛИЦЕНЗИЯ НомерСудна НазваниеСудна ТипСудна НалогоаыйИдентификатор ЛетПоДанномуАдресу НомерЛицензииПредыдГода ЛИЦЕНЗИЯ_НА_ЛОВЛЮ в Рис. 3.13. Пример категориальной связи: а — форма, демонстрирующая потребность в категориях (подтипах); б — категориальный кластер с двумя категориями; в — одна категория имеет дополнительную саязь
Построение моделей данных на базе анализа форм и отчего» 143 ПРОДАВЕЦ КЛИЕНТ КЛИЕНТ ПРОДАВЕЦ б в Рис. 3.14. Форма заказа: а — образец формы; б — сущность СТРОКА_ЗАКАЗА с двумя идентифицирующими связями; а — сущность СТРОКА_ЗАКАЗА с одной идентифицирующей связью На рис. 3.14, б приведены результаты нашего анализа. Обратите внимание, что сущность СТРОКА_ЗАКАЗА зависит как от сущности ЗАКАЗ, так и от сущности ВАР, Эта сущность имеет композитный идентификатор (НомерЗаказа, КодТова- Ра). Это означает, что конкретный товар может фигурировать в заказе не более одного раза. Также обратите внимание на то, что атрибут ЦенаТовара имеется как в сущности ТОВАР, так и в сущности СТРОКА_ЗАКАЗА Атрибут ТОВАР.ЦенаТовара
144 Глава 3. Создание моделей данных «сущность ет»аь» „кта,reuymvH, цепу товар;,. а атрибут ОТОКА.>ЛК«Л.ЦтаТоад. и,у Хара на помет покупки. При тала,..ЯШ зиичеии» з™х а.рибуто».<»» дают, но потом они могут оказаться различными Нарве 314 « изображено альтернативное решение, при котором оди и от же товар может фигурировать в заказе иеоднокраию. Здесь илнпифицируммдад связь между сущностями ТОВАР и СТРОКА JAKA3A была заменена на неид< чти фннпруюпию Для того чтобы сущность СТРОКА ЗАКАЗА имела идентификатор, создается специальный атрибут НомерСтроки. Теперь полный идентификатор сущности СТРОКА_ЗАКАЗА имеет вид {НомерЗаказа, НомерСтроки}. Второй вариант предпочтительнее, если товар может появляться более чем в одной строке одно го и того же заказа. Итак, в этом разделе были приведены примеры распространенных типов сущностей и связей. В следующем разделе мы покажем, как происходит разра- ботка модели данных при моделировании последовательности взаимосвязанных форм и отчетов. Разработка модели данных: пример Предположим, что администрация вымышленного университета Highline ре- шила создать базу данных, в которой содержались бы сведения о колледжах, кафедрах, профессорско-преподавательском составе и студентах. С целью опре- деления требований к модели данных группа, разработчиков собирает серию отчетов. Далее мы проанализируем эти отчеты и создадим на их основе модель данных. Отчет о колледже Отчет, изображенный на рис. 3.15, содержит данные об одном из колледжей уни- верситета, а именно о колледже бизнеса. Университет имеет подобные отчеты обо всех своих колледжах — инженерном колледже, колледже социальных наук и т. д. Задача группы разработчиков — собрать достаточное количество образцов отчетов о колледжах, чтобы получилась репрезентативная выборка. Допустим, чю отчет на рис. 3.15 отвечает требованию репрезентативности. В рассматриваемом отчете приводятся данные как о колледже в целом (на- звание колледжа, имя декана, номер телефона и местный адрес), так и о каждой кафедре, имеющейся в колледже. Отсюда мы делаем вывод, что модель данных должна содержать сущности КОЛЛЕДЖ ц КАФЕДРА, между которыми имеется связь (рис. 3.16). Связь на рис. 3.16 не является идентифицирующей. Вас, возможно, интересует, как определить, в каком случае использовать идеи гифицнрующую связь, а в ка- ком - неидентифицирующую. Вопрос, который нужно себе для этого задать, звучит так: «Имеет ли сущность-потомок (здесь это КАФЕДРА) явный идентиф»-
Разработка модели данных пример !4в катер, который нс содержит в себе идентификатор сущности родителя?» Ес. I да, то потомок является сильной сущности), и следует испольюпатъ иеи.«-н- тмфп пирующую связь. В нашем случае сущность КАФЕДРА имеет явный иден- тификатор НазваниеКафедры, полому она является сильной сущностью и имеет нсидентпфицирующую связь с сущностью КОЛЛЕДЖ Колледж бизнеса Мзри Джефферсон, декан Телефон: 232-1187 Местный адрес Корпус бизнеса, комната 100 Кафедра Заведующий Телефон Всего ст у;литов Бухгалтерский учет Джексон, Сеймур П. 232-1841 318 Финансы Хью Тень, Сьюзен 232-1414 211 Информационные Браммер, Натаниэль Д. 236-0011 247 системы Менеджмент Татл, Кристин А. 236-9988 184 Производство Барнс, Джек Т. 236-1184 212 Рис. 3.15. Образец отчета о колледже КОЛЛЕДЖ КАФЕДРА Рис. 3.16. Модель данных, построенная на базе отчета о колледже Из отчета на рис. 3.15 невозможно определить, может ли кафедра принад- лежать нескольким колледжам. Ответ на этот вопрос должны дать пользова- тели или дальнейшее исследование форм и отчетов. Здесь мы предположим, что согласно информации, полученной от пользователей, кафедра может принад- лежать только одному колледжу, и таким образом, связь между сущностями КОЛЛЕДЖ и КАФЕДРА имеет вид 1:N. Определить минимальную кардинальность отчет на рис 3.15 также не позволяет. Опять-таки предположим, что согласно информации, полученной от пользователей, любой колледж должен, иметь по крайней мере одну кафедру, а каждая кафедра должна существовать хотя бы в одном колледже. Отчет о кафедре и преподавателях Отчет о кащедре, показанный па рис. 3.17, содержит информацию о кафедре и спи- сок преподавателей, работающих на этой кафедре. Обра’цтге внимание, что в отче-
146 Глава 3. Создание моделей данных «сущность—связь» те указан местный адрес кафедры. Поскольку эти данные отсутствуют в сущности КАФЕДРА, изображенной на рис. 3.16, следует изменить определение этой сущно- сти, добавив в него соответствующие данные (рис. 3.18, а). Эта ситуация являет ся типичной для процесса моделирования данных: сущности и связи постоянно модифицируются по мере анализа форм, отчетов и прочих требований. На рис. 3.18, а связь между сущностями КАФЕДРА и ПРЕПОДАВАТЕЛЬ изображена как неспецифическая. Это было сделано потому, что преподаватель может рабо- тать по совместительству. Команда разработчиков должна произвести дальней- ший анализ требований и определить, разрешено ли в университете совмещение. Если нет, эта связь может быть переопределена как неидентифицирующая связь принадлежности (рис. 3.18, б). Кафедра информационных систем Колледж бизнеса Заведующий: Телефон. Местный адрес: Браммер, Натаниэль Д. 236-0011 Корпус социальных наук, комната 213 Джонс, Пол Д. Паркс, Мэри Б. By, Элизабет Офис Корпус социальных наук, комната 219 Корпус социальных наук, комната 308 Корпус социальных наук, комната 233 Телефон 232-7713 232-5791 232-9113 Рис. 3.17. Образец отчета о кафедре Еще одна возможность заключается в том, что группа может найти форму, отчет или какое-то другое требование, относящееся к сочетанию кафедры и пре- подавателя. Допустим, что группа разработчиков модели данных университета Highline нашла отчет, содержащий сведения о звании и условиях найма каждого преподавателя на каждой кафедре. На рис. 3.18, в показана сущность ДОЛЖНОСТЬ, представляющая этот отчет. Обратите внимание, что сущность ДОЛЖНОСТЬ яв- ляется идентификационно-зависимой как от сущности КАФЕДРА, так и от сущно- сти ПРЕПОДАВАТЕЛЬ. Это означает, что идентификатор сущности ДОЛЖНОСТЬ пред- ставляет собой сочетание идентификаторов сущностей КАФЕДРА и ПРЕПОДАВАТЕЛЬ, то есть {НазваниеКафедры, ИмяПреподавателя}. Во всем последующем обсужде- нии мы будем использовать именно эту модель связи между кафедрой и пре- подавателем. Заведующий кафедрой является преподавателем, поэтому можно внести в мо- дель еще одно усовершенствование, убрав атрибут Заведующий из сущности КАФЕДРА и заменив его связью с сущностью ПРЕПОДАВАТЕЛЬ. Это было проделано на рис. 3.18, г: в связи .Заведование. сущность ПРЕПОДАВАТЕЛЬ является родите- лем. Преподаватель может (но не обязан) заведовать кафедрой, притом макси- мум одной; у каждой кафедры должен быть ровно один заведующий.
Разработка модели данных, пример 147 КОЛЛЕДЖ НазваниеКолледжа ИмяДекана Телефон Корпус Комната КАФЕДРА Р НазваниеКафедры ПРЕПОДАВАТЕЛЬ Заведующий ИмяП; «подавателя Телефон . Корпус ЧислоСтудентов НомерОфиса Корпус Телдфом Комната ~ а КОЛЛЕДЖ КАФЕДРА НазваниеКолледжа Р НазваниеКафедры Р ИмяДекана Телефон Корпус Комната Заведующий Телефон ЧислоСтудентов Корпус Комната ИмяПреподавателя б Корпус НомерОфиса Телефон ПРЕПОДАВАТЕЛЬ КОЛЛЕДЖ КАФЕДРА Р ПРЕПОДАВАТЕЛЬ ДОЛЖНОСТЬ Звание Условия КОЛЛЕДЖ НазваниеКолледжа ИмяДекана Телефон Корпус Комната ДОЛЖНОСТЬ Звание Условия г Рис. 3.1В. Альтернативные модели связи между сущностями КАФЕДРА и ПРЕПОДАВАТЕЛЬ а — модель с неспецифической связью; б — модель с неидентифицирующей связью, в — модель с сущностью ДОЛЖНОСТЬ; г — модель с постом заведующего. представленным в виде связи
148 Глава 3. Создание моделей данных «сущность связь» Благодаря наличию связи _3аведование_ необходимоегь в атрибуте jate. „. дня сущности КАФЕДРА отпадает, и мы удаляем этот атрибут Как правило, у за- ведующего кафедрой имеется собственный кабинет и офисе кафедры Если это так, атрибуты Телефон, Корпус п Комната сущности КАФЕДРА будут дуб ировать атрибуты Телефон, Корпус н НомерОфиса сущности ПРЕПОДАВАТЕЛЬ. В связи с этим, вероятно, можно удалить атрибуты Телефон, Корпус и Комната из сущности КАФЕДРА С другой стороны, телефон преподавателя может не совпадать с официальным телефоном кафедры, и у преподавателя может быть свой офис вне кафедрального офиса Из-за этой возможности мы оставим атрибуты Телефон, Корпус и Комната в сущности КАФЕДРА Отчет о студентах кафедры На рис. 3.19 представлен отчет о кафедре и студентах, для которых данная ка- федра является профильной. Этот отчет указывает на необходимость новой сущности под названием СТУДЕНТ Поскольку студенты не являются идентифи- кационно-зависимыми от кафедр, связь между сущностями КАФЕДРА и СТУДЕНТ определена как неидентифицирующая (рис. 3.20). Исходя из содержимого этого отчета, сущности СТУДЕНТ были присвоены атрибуты НомерСтудента, ИмяСту- дента и Телефон. Список студентов Кафедра информационных систем Заведующий: Браммер, Натаниэль Д Телефон: 236-0011 Имя Студента Номер студента Телефон Джексон, Робин Д. 12345 237-8713 Линкольн, Фред Дж. 48127 237-8713 Мэдисон, Дженис А 37512 237-8713 Рис. 3.19. Второй отчет о кафедре В такой интерпретации отчета есть две тонкости. Во-первых, обратите вни- мание, что атрибут, описывающий имя студента, получил у нас название не Имя- СтудентаКафедры (как если бы мы следовали терминологии отчета), а просто Имя- Студента. Это было сделано потому, что ИмяСтудента — более общее название. Название ИмяСтудентаКафедры не имеет смысла вне связи Специализация. Кроме того, заголовок отчета на рис. 3.19 содержит в себе потенциальную неоднознач- ность. Какой телефон в нем указан - кафедры (КАФЕДРА.Телефон) или заведу- ющего ею преподавателя (ПРЕПОДАВАТЕЛЬ.Телефон)? Этот вопрос должен быть решен с пользователям)г. Скорее всего, имеется в виду кафедральный телефон, то есть атрибут КАФЕДРА.Телефон.
Разработка модели данных пример СТУДЕНТ НомерСтудента ИмяСтудента Телефон Рис. 3.20. Модель с сущностью СТУДЕНТ На pm. 3.21 изображено письмо-приглашение, которое университет рассылает поступившим в нею студентам. Для целей моделирования данных это письмо мо- жет рассматриваться как отчет. Элементы, которые должны быть представлены в модели данных, выделены жирным шрифтом. Кроме данных о студенте, в отчете указана профильная кафедра студента и приведена информация о руководителе. Мистеру Фреду Парксу 123, Эльм-Стрит Лос-Анджелес, Калифорния 98002 Уважаемый мистер Паркс, рад сообщить, что Вы приняты на кафедру бухгалтерского учета университета Highline начиная с осеннего семестра 2000 года. Кафедра бухгалтерского учета находится по адресу: корпус бизнеса комната 210. Вашим руководителем назначена профессор Элизабет Джонсон, номер ее телефона 232-8740, офис расположен в корпусе бизнеса, комната 227 Просьба назначить встречу с руководителем сразу по прибытии в университетский городок Поздравляю, и добро пожаловать в университет Highline' Искренне Ваш, Ян П Сматерс, Президент Рис. 3.21. Письмо-приглашение
150 Глава 3. Создание моделей данных «сущность связь» Основываясь на этом письме, мы добавим в нашу модель связь „Руководство^, Но какая сущность должна играть роль родителя в этой связи? Поскольку руково- дитель является преподавателем, первым побуждением будет сделать родителем сущность ПРЕПОДАВАТЕЛЬ. Однако преподаватель выполняет функции руководите- ля в контексте конкретной кафедры. Поэтому правильнее будет сделать родителем сущность ДОЛЖНОСТЬ (рис. 3.22). Для создания отчета, подобного изображенно- му на рис. 3.22, мы от заданной сущности СТУДЕНТ переходим к сущности ДОЛЖНОСТЬ, а затем к ее родителю, сущности ПРЕПОДАВАТЕЛЬ, из которой и полу- чаем интересующие нас сведения о преподавателе. Но это не просто шаблонное решение. Выбор сущности ПРЕПОДАВАТЕЛЬ в качестве родителя имеет под собой веские основания. Согласно этой модели данных, студент имеет максимум одну специализацию и максимум одного руководителя. Эти ограничения не следуют из какого-либо рассмотренного нами отчета. Возможно, студенты могут иметь и по несколько специализаций, но данный конкретный студент имел только одну. Разработчики должны получить ответ на этот вопрос у пользователей. Рис. 3.22. Модель данных со связью ^Руководство В заголовке письма-приглашения используется обращение мистер. Поэтому в сущность СТУДЕНТ добавлен новый атрибут Обращение. Кроме того, как видно из письма, сущность СТУДЕНТ нуждается в атрибутах, описывающих домашний адрес студента.
Разработка модели данных пример 151 И еще одна проблема обнаруживается в связи с этим письмом- студента зо вут Фред Паркс, но для хранения имени студента в сущности СТУДЕНТ выделен только один атрибут. Трудно с абсолютной точностью выделить имя и фами- лию из одной строки, поэтому лучше иметь два атрибута, в одном из которых будет храниться имя (ИмяСтудента), а в другом фамилия (ФамилияСтудента). Что касается имен преподавателей, то они до сих пор хранились нами в формате «Джонсон, Элизабет». В письме же мы видим это имя в формате «Элизабет Джонсон». Чтобы можно было использовать оба формата имени, разделим ат- рибут ИмяПреподавателя сущности ПРЕПОДАВАТЕЛЬ на два атрибута — ИмяПре- подавателя и ФамилияПреподавателя. Аналогичным образом необходимо преоб- разовать атрибут ИмяДекана. Окончательный вид нашей модели, учитывающий эти изменения, показан на рис. 3.23. ПРЕПОДАВАТЕЛЬ КАФЕДРА КОЛЛЕДЖ Рис. 3.23. Окончательный вид модели данных Этот раздел должен был дать вам представление о работе в реальном проекте по моделированию данных. Формы и отчеты анализируются последовательно, и по мере изучения каждого нового документа происходит постепенное уточне- ние модели данных. Типичной является ситуация, когда модель данных пере- сматривается несколько раз на протяжении процесса моделирования.
152 Глава 3. Создание моделей данных «сущно :ть--свяЗы Домены Хотя стандарт IDEF1X н включает в себя концепцию доменов, он не предусмат ривает какого-либо стандартного способа их описания или отображения. Соот- ветственно, в разных программах для моделирования данных используютоя раз- личные способы определения доменов. На рис. 3.24 изображены домены для модели данных университета Highline, определенные в программе для моделирования данных ERWin. Посмотрите на домен String, и вы увидите что в этом домене определен типовой домен Address (Адрес). В домене Address, в свою очередь, определены типовые домены City (Го- род), State (Штат), Street (Улица) и Zip (Индекс). ERWin позволяет задавать широкий диапазон характеристик домена. На рис. 3.24, б изображен словарь домена (domain dictionary). В этом примере пока- заны свойства домена BuildingName (НазваниеЗдания). В верхнем диалоговом окне отображается тип данных этого атрибута - Char(25), что соответствует фиксиро- ванной символьной строке длиной до 25 байт. Атрибуту НазваниеЗдания назна- чен список допустимых значений. В раскрывающемся списке Valid (Допускается) показывается имя BuildingNameList (СписокНазванийЗданий). При нажатии на кноп- ку с многоточием открывается диалоговое окно Validation Rules (Правила проверки диапазона). Для домена BuildingNameList (СписокНазванийЗданий) имеется прави- ло, задающее список допустимых значений. Один из вариантов использования доменов изображен на рис. 3.25. Он анало- гичен рис. 3.23, за исключением того, что к названиям атрибутов присоединены названия доменов. Например, атрибут ИмяДекана происходит из домена Имя. Атрибуты, использующие домен НазваниеЗдания, обведены на рисунке черным фломастером; всего таких атрибутов три. Если бы потребовалось изменить одно из свойств домена НазваниеЗдания (например, добавить еще одно здание в список допустимых значений), то это изменение было бы унаследовано всеми этими тремя атрибутами. С помощью такого рисунка можно также выявить атрибуты, имеющие разные имена, но происходящие из одного и того же домена. Точно так же можно найти атрибуты, имеющие одинаковые имена, но проис- ходящие из различных доменов и поэтому различающиеся по своей сути. ERWin и другие программные продукты для моделирования данных предла- гают множество других возможностей по использованию доменов. Из данного примера вы можете видеть, как это делается и почему это важно. На этом мы завершаем обсуждение моделирования данных с использовани- ем модели «сущность—связь». Как уже говорилось в начале этой главы, для усвоения приведенного здесь материала полезно будет прочесть его два или три раза. Следующая часть книги будет посвящена проектированию баз данных. В гла- ве 4 мы определим важнейшие термины реляционной модели и обсудим процесс нормализации. Затем из главы 5 вы узнаете, как соединить это все воедино, что- бы на основе моделей данных проектировать реляционные базы данных.
Разработка модели данных пример 153 Qfc Domans Й ? <unknown> • еюь Ф Datetime ft H# Number JS’j CoonlOIM8|Or$ ttft HighltnePlWHsNiMite ‘ RoomNumber ' £j StudentNumber Siring £•£] Academic! ill* S Address : CJ City . £j Stele L3 Sheet •• (j Zip .'•• £j CuildmgNene Г'} CoiiegeNene fr'j DepaftnentName ;',' 4 Er-ploy-rertlerms й p | PetsonName • (, I FirstName f '1 LasJName • - Qj Sa’ualat’ionTitle & t/oJti ; Subject Domains a £d'lMcde. jLogcaJ д| _ Soil ........... •... ‘ -v- AJph^et;crs8y i . НйгзгеЫмЯу bc-mem ’ ' '' • .' ; .. -Cl Acade-n сТй'е -T~l Address -Co Civ ? -Cd swe -CD Sued H^z-P "СЗ^ЕЗилЕЗ X'J; -Cd CcHeceMane -Cp DepalmenlName h-Ci Err.clcvmcnlT eims ;T: > f fiyeJ .MO** | Ltf atsyie ’ -. ?CHARf25|......... ffifflBT 4)ATE IDEDMAL inFriMAin : £’' Requited .. j '• VaSd |Butdin54lerreLisl IN 'themes НгВ' ‘McKrtey h'H'' ( 3 л б Рис. 3.24. Представление доменов в ERWin: а — иерархии доменов; б — определение характеристик домена BuildingName (НазваниеЗдания)
! 54 Глава 3. Создание моделей данных «сущность-связь» Рис. 3.25. Модель данных с именами доменов Резюме Первым шагом процесса моделирования данных является планирование про- екта. Оно включает получение одобрения у руководства, формирование рабо- чей группы, разраоотку стандартов и планирование задач и назначений. По- сле этого определяются системные требования. Разработчики проводят опрос пользователей, наблюдают со стороны за их работой, получают образцы форм и отчетов, исследуют существующие и новые файлы, анализируют формаль- ные интерфейсы и советуются с предметными специалистами. Результатом ра- боты по определению требований является единый информационный репози- торий, содержащий различные заметки, документы, описания структуры файлов
Резюме 105 и другие материалы, которые могут быть использованы при создании модели данных. После того как план проекта составлен и требования определены, начинается собственно процесс моделирования. Он состоит из пяти шагов: определение сущностей, определение связей, определение идентификаторов, определение ат- рибутов и определение доменов (см. рис. 3.1). В действительности этот процесс никогда не является строго последовательным: в ходе определения связей может возникнуть потребность в новых сущностях, в ходе определения атрибутов — в новых доменах, и т. д. Обычно элементы модели данных создаются парал- лельно. Сущности — это некие объекты, за которыми пользователи хотят следить. Потенциальные сущности можно выявлять, анализируя реплики пользовате- лей, наблюдая за их работой, исследуя формы, отчеты и другие документы. Сущности в модели данных имеют динамический характер: по мере продви- жения проекта сущности будут неоднократно добавляться, удаляться и моди- фицироваться. Связи можно выявлять путем исследования всех возможных пар сущностей в модели данных (см. рис. 3.3) либо путем анализа требований. Не существует такого понятия, как односторонняя связь: связи всегда существуют в обоих на- правлениях. Бывает, однако, что в конкретном приложении используется только одно направление связи. В этом случае кардинальные числа для неиспользуемо- го направления связи выясняются в беседе с пользователями. Каждая реальная сущность имеет идентификатор. Если возникают затрудне- ние с определением идентификатора сущности, обычно это говорит о том, что с этой сущностью что-то не в порядке. Возможно, она должна быть частью дру- гой сущности, подтипом или категорией, а может быть, ей требуются одна или несколько идентифицирующих связей. Проблемы с идентификаторами указыва- ют на возможность корректировки модели данных. Атрибуты обычно выявляются в ходе анализа форм, отчетов, описаний струк- туры файлов и других документов. Каждый раз, когда в модель данных добав- ляется новый атрибут, список существующих доменов исследуется на пред- мет того, нет ли в нем домена, который подходил бы для нового атрибута. Если нет, создается новый домен. Домены полезны, поскольку атрибуты на- следуют их свойства: при изменении какого-то свойства домена все атрибу- ты, основанные на этом домене, унаследуют это изменение. Домены могут также использоваться для проведения политики стандартизации данных. Не- которые атрибуты могут указывать на недостающие сущности и связи. Осо- бенно это характерно для атрибутов, содержащих в себе слова «имя» или «на- звание». После того как модель данных построена, производится ее проверка. Никакая модель данных не моделирует реальность, ибо это невозможно. Модель данных является моделью человеческого представления о реальности. Модель неверна
156 Глава 3. Создание моделей данных «сущность связь» только в том случае, если она неадекватно отображает способ, которым пользе, вателп видят свой мир. Проверка модели данных осуществляется в ходе серии обсуждении Как правило, сначала идут обсуждения в кругу разработчиков, а затем в кругу пользователей. Часто модель данных может описываться пользователям не- посредственно в терминах модели «сущность-связь», ио иногда для объясне- ния различных аспектов модели данных требуется создавать разного рода маке- ты и прототипы. Во втором разделе главы было показано, как формы и отчеты используются для построения модели данных, а в заключительном разделе процесс, моделиро- вания данных был проиллюстрирован на примере простой базы данных для вы- мытленного университета. Вопросы группы I 1. Перечислите шаги процесса моделирования данных. 2. Опишите задачи, которые предстоит решить на этапе планирования проекта. 3. Перечислите распространенные источники требований. 4. Как опрос пользователей и наблюдение за их работой используются для разработки компонентов модели данных? 5. Почему' так важно прояснять терминологию в ходе опроса пользователей? 6. Как формы и отчеты используются для разработки компонентов модели данных? 7 Как существующие файлы используются для разработки компонентов мо- дели данных? 8. Что означает термин реконструкция в контексте моделирования данных? 9 Объясните, как формальные интерфейсы могут быть источником требо- ваний 10. Почему использование.формальных интерфейсов растет? И Кто такие предметные специалисты? Каковы преимущества и недостатки работы с предметными специалистами при определении требований? 12. У кажите возможную сущность и возможный атрибут в следующей фразе: «Я группирую заявления от студентов по дате...». 13. У кажше возможную сущность и возможный атрибут в следующей фразе: «Я использую название кафедры преподавателя.. ». Может ли эта фраза ссылаться на Две сущности? Если да, то какие? 14. Ооъяснпте, почему синеок сущностей, вероятнее всего, будет меняться по мере , аботы над проектом.
Вопросы группы I 167 15. Почему важно четко определять значение и способ использо* ния сук» постен? 16. Из каких элементов состоит определение связи? 17. Опишите два способа выявления связей. 18. Объясните своими словами, почему не бывает односторонних связей 19. Может ли быть, чтобы в приложении использовалось только одно направ- ление связи? Почему? 20. Пр1 ведите пример сущности, не имеющей явного идентификатора. Что следует сделать с этой сущностью? 21. Приведите пример (отличный от данного в тексте) двух различных сущ- ностей, имеющих один и тот же идентификатор. 22. Как связаны атрибут и домен? 23. Как создаются домены? 24. Объясните преимущества наследования атрибутами свойств доменов. 25. Как домены могут использоваться для проведения в жизнь политики стан- дартизации данных в организации? 26. Приведите два примера атрибутов, указывающих на необходимость введе- ния новой сущности. Пусть в одном примере атрибут содержит слово «имя» пли «название», а в другом не содержит. 27. Почему важно проверять модели данных? 28. Объясните, почему высказывание: «Моя модель данных более адекватно моделирует реальность, чем твоя», является ложным. 29. Если бы некто высказал вам утверждение, описанное в вопросе 28, что бы вы ему ответили? 30 Объясните смысл следующих двух предложений: «Мы не можем сказать, что человеческие модели являются адекватным представлением реального мира, потому что мы ничего не знаем об этом мире. Единственное, что мы можем утверждать, — это что данные модели работают достаточно хорошо, чтобы люди могли мыслить и общаться друг с другом способом, который по сию пору обеспечивал выживание челове- чества как биологического вида». 31. В чем заключается единственный критерий оценки модели данных? 32. Опишите, как проходит этап обсуждения модели данных в кругу разработ- чиков. 33. Опишите, как проходит этап обсуждения модели данных с пользователями. 34. Покажите, как с помощью макета продемонстрировать пользователям смысл понятия максимальной кардинальности связи между двумя сущ- ностями.
158 Глава 3. Создание моделей данных «сущность < вяз»»» Вопросы группы II Ответьте на следующие вопросы, псцользуя символнку стандарта ШПГ1Х; 35. Исследуйте подписной бланк па рис. 3.26. Щ №Н* PaipejewOMiFofefflsiJw '' »W4* W оМ!«И'®®й,аи,ий’1 (За1ф^(Ш211№фа&<Ч^^>1^иОД №_____________________ ---------------------- Гад ifa Ш_____________ Ошривш Прааггрииынеиа 1И^"^ЯС№№0Ы9ва Ой аЬркы/а. Рис. 3.26. Подписной бланк Основываясь на структуре этого бланка, выполните следующее: 1) Создайте модель, состоящую из одной сущности. Укажите ее иденти- фикатор и атрибуты. 2) Создайте модель с двумя сущностями. Укажите идентификаторы, ат- рибуты, имя связи, ее тип и кардинальность. 3) При каких условиях вы предпочтете первую модель второй? 4) При каких условиях вы предпочтете вторую модель первой? 36. Изучите форму акта о нарушении правил дорожного движения, представ- ленную на рис. 3.27. Закругленные углы служат подсказкой о том, где про- ходят границы сущностей. 1) Создайте модель данных с пятью сущностями. Основываясь на элемен- тах данных, имеющихся в акте, определите идентификаторы и атрибу- ты сущностей. 2) Определите связи между сущностями. Дайте каждой связи имя и ука- жите ее тип и кардинальность. Укажите, какие значения кардинальных чисел были определены в результате анализа данных формы, а какие необходимо уточнить в разговоре с пользователями системы. 37. На рис. 3.28 изображен список сообщений электронной почты с полями From (отправитель), Subject (тема), Date (дата) и Size (размер). Основыва- ясь на этом списке, выполните следующее: 1) Создайте модель данных с одной сущностью. Укажите ее цдентифика тор и атрибуты.
Вопросы группы II 15ft 2) Измените свой ответ на вопрос (1), включив в модель сущности ОТ- ПРАВИТЕЛЬ и ТЕМА. Укажите идентификаторы и атрибуты сущностей, а также типы и кардинальности связей. Укажите, какие значения кардинальных чисел были определены в результате анализа данных на рис. 3.28, а какие необходимо уточнить в разговоре с пользовате- лями системы. 3) В колонке From (Отправитель) на рис. 3.28 можно наблюдать два раз- ных стиля написания адресов электронной почты. Один стиль преду- сматривает отображение реального адреса, а другой — отображение имени абонента в адресной книге электронной почты. Создайте две категории сущности ОТПРАВИТЕЛЬ для этих двух стилей. Укажите их идентификаторы и атрибуты. ДОРОЖНЫЙ ПАТРУЛЬ ШТАТА ВАШИНГТОН. УВЕДОМЛЕНИЕ ОБ ИСПРАВЛЕНИИ НАРУШЕНИЯ ФАМИЛИЯ Кренке ИМЯ Дэвид М. АДРЕС 88-я авеню, 5053 ГОРОД Мисер Айленд ШТАТ Ваш. ИНДЕКС 98040 ВОД. ЛИЦЕНЗИЯ 00000 ШТАТ Ваш. У, ДАТАРОЖД. 27.02.1946 РОСТ 180 ВЕС 70 ЦВ. ГЛАЗ Голуб /К ЛИЦ. ТРАНСП. СР-ВА AAA000 ШТАТ Ваш. ЦВЕТ ГОД 90 МАРКА Saab ТИП 900 VIN ЗАРЕГИСТРИРОВАНО ВЛАДЕЛЕЦ АДРЕС ДАТА НАРУШЕНИЯ МЕС. 11 ДЕНЬ 7 ГОД 2003 ВРЕМЯ (Ч): 9.35 РАЙОН 2 КОМАНД- 17 МЕСТО 17 МИЛЬ К востоку ОТ Энумкума ПО SR410 нарушения Написание текста во время управления транспортным средством ПОДПИСЬ ДОЛЖН ЛИЦА: С. Скотт ЛИЧНЫЙ НОМЕР: 850 3 Это предупреждение, дальнейшие действия не требуются 2 Вы .х-ясА «даетесь для ; тпраеки транспортного средства в ремонт. Дальнейшая эксплуатация не разрешается. 3 НЕМЕДЛЕННО ИСПРАВЬТЕ НАРУШЕНИЯ. В «дмчютас подтверждения аздвдотите эту карточку со своей подписью в течение 15/30 дней (если в этой графе стоит пометка) ПОДПИСЬ ВОДИТЕЛЯ Рис. 3.27. Акт о нарушении правил дорожного движения
160 Глава 3. Создание моделей данных «сущность- связь» 4" lmail.com Big Wind 5/13/200? зкв 4 KB Update 5/12/2002 WOA22S9@sa lmeil.com , ,г . WOA2259@sa Imail :qm Re: Saturday Am ! i'.T 5/11/200? 4 У» WDA2259.@sa Imai com Re: Weather windowl 5/10/2002 4 kfe WDA2259@sa Imail com Re- Howdy* 5/10/2002 « зио " '..Г WOA2259®'sailmail.com Still here . •- - - 5/9/2002 зкв -. - '• WDA2259<s?sa)lmail.com Re: Turle Bay 5/8/2002 4 кв Т tiVDA2259g»sailmail.com Turle Bay Л.-. ...лх.. i 5/8/2002 4 кВ ..р.-. W[>A22S9<?,sailmoi|.co n Re; Hi 5/8/2002 ! зкв WD A22S9<j?$eiirndil .com Sunday, Santa Mane 5/2 ~ ЗКВ Ki6vu® aol.com Cabo, Thurs. Noon 5/2/2002 2 КВ ~~ г WDA2259@$a»lmail .com turbo -< Й у s «:-• < V 5/1/2002 3 КВ г WOA2CS9@sailmail .com on our way ''i-fl-.ji Xv;-.*.1. . 4/28/2002 ЗКВ г Tom Cooper RE: Hole 4/26/2002 3 КВ г Tom,Cooper RE. Holai .. .C4! ... .... 4/Z4/2£)02, 2 КВ Рис. 3.28. Список сообщений электронной почты 38. На рис. 3.29 представлена таблица курсов акций со столбцами Symbol (обозначение), Name (название), Last (последнее значение), Change (изме- нение) и % Chg (изменение в процентах). Основываясь на данных этой таблицы, выполните следующее. 1) Создайте модель данных с одной сущностью. Укажите ее идентифика- тор и атрибуты. 2) Измените свой ответ на вопрос 1), включив в модель сущности КОМ- ПАНИЯ и ИНДЕКС. Укажите идентификаторы и атрибуты сущностей, а также типы и кардинальности связей. Укажите, какие значения кардинальных чисел были определены в результате анализа данных на рис. 3.29, а какие необходимо уточнить в разговоре с пользовате- лями спщ-емы. 3) Таблица на рис. 3.29 содержит данные о стоимости акций по состоя- нию на определенную дату и время. Предположим, что таблица была изменена, и теперь в ней отображается стоимость акций на момент закрытия торгов, а кроме того, имеется новый столбец Дата. Внесите соответствующие модификации в модель, построенную вами в ответе на вопрос 2). 4) Измените ваш ответ на вопрос 3), добавив возможность отслеживания портфеля акций. Пускай портфель акций имеет такие характеристики, как имя владельца, его телефон, адрес и список пакетов акций. Список пакетов должен включать наименование компании и количество акций в пакете. Укажите все вновь созданные сущности, их идентификаторы и атрибуты, а также тип и кардинальность всех связей.
Вопросы группы II 161 Symbol Name Last Change «спи JCOMPX Nasdaq Combined Composite Indan 1.400 74’ 4 87 -035» JINDU Dow Jones Industrial Average Index 9,25510* -1880 -0 21» JINX S8P 500 INDEX 971 14 * -594 -0 80» ALTR Altera Corporation 1345* -0450 -3 24» AMZN Amazon com, Inc 15 62 - *0 690 *4 55» CSCO Cisco Systems, Inc 13 39 » 0 280 -2 05» DELL Dell Computer Corporation 24 58* -0170 -0 69» ENGCX Enterprise Growth C 14 60 * -0 210 -1 42» INTC Intel Corporation 1812» -0 380 -2 05» JNJ Johnson 8 Johnson 53 29 * -0.290 0 54» KO Coca-Cola Company 56 70 » -0 5-80 -t 01» MSFT Microsoft Corporation 53 96* *1.040 *1 97» NKE NIKE, Inc 57 34 * *и’адО *1 02» Рис. 3.29. Таблица курсов акций 5) Измените ваш ответ на вопрос 4), добавив возможность отслежива- ния покупки и продажи акций в портфеле. Укажите все сущности, их идентификаторы и атрибуты, а также тип и кардинальность всех связей. 39 На рис. 3.30 показана таблица сравнительных характеристик однофазных воздушных компрессоров со столбцами HP (мощность в л. с.), Model (мо- дель), Tank Gal (емкость бака), Pump RPM (количество оборотов в мину- ту), CFM Disp (вытеснение в кубических футах в минуту) и DEL’D Air (подача в кубических футах в минуту). Обратите внимание, что в таблице фигури- рует две категории продуктов, различающиеся по давлению воздушного потока: модели серии А обеспечивают давление 125 фунтов на квадратный дюйм, а модели серии Е — 150 фунтов на квадратный дюйм. Основываясь на данных этой таблицы, выполните следующее. 1) Создайте категориальный кластер доя представления этих двух серий. По- рождающая сущность будет иметь атрибуты, являющиеся общими для всех однофазных компрессоров, а сущности-категории будут содержать атрибуты, значение которых различается в разных сериях. Предполо- жим, что серий может быть больше, чем две. Укажите сущности, иден- тификаторы, атрибуты, связи, тип категориального кластера и возмож- ный детерминант. 2) На рис. 3.31 показана альтернативная модель данных о компрессоре. Объясните смысл изображенных сущностей, укажите их тип, а также вид и кардинальность связи. Хорошо ли эта модель подходит для пред- ставления данных с рис. 3.30? 3) Сравните ваш ответ на вопрос 1) с моделью на рис. 3.31. В чем заключа- ются принципиальные различия между двумя этими моделями? Какая из моделей, по вашему мнению, является лучшей?
162 Глава 3. Создание моделей данных «сущность -связь* Single Stage ИО v SI »lr« iVjiUbl». wbrtitm*"6" <»r“A" In modtl r.«mW. !«.. К15АЭ0 КИ&ЭО HF Model Tank Gal Ан Performance Approx I Ship Weight Dimenstonf 1 А ф 125 Е® 150 L 1 w H Pump RPM CFM Dlsp DEL'D Air Pump RPM CFM Dlsp DEL'D I Ah | 1/2 F12A-17 17 680 34 2.2 600 2.9 ie | 136 ] 37 | 14 Ы 3/4 F34A-17 17 1080 5.3 3.1 050 4.7 2.3 | 140 | 37 | 14 25 3/4 F34A-30 30 1080 53 3 1 960 47 23 | ieo | I38 1 16 31 | 1 К1А-30 30 560 6.2 4.0 500 5.7 3.1 I 190 ] 38 16 34 | 1 1/2 К15А-30 30 870 08 62 860 0.7 5.8 | 205 | 40 | 20 d 1 1/2 К15А-60 60 870 е.е 6 2 860 0.7 Se I 315 ] 38 16 2 К2А-30 30 1140 13.1 80 1060 12 0 70 I 205 | 40 I20 39 I 2 К2А-60 60 1140 13.1 8.0 1060 120 _LZJ 315 48 120 34 j 2 GC2A-30 30 480 13.1 0 1 460 12 4 ...Z£ . 270 38 16 36 | 2 GC2A-60 60 480 13.1 0.1 460 12.4 7.8 370 40 20 41 I 3 ОСЗА-60 60 770 21.0 140 740 10 9 12.3 288 38 16 36 | 5 GC5A-80 60 770 21.0 14.0 740 10.0 12.3 J 388 40 20 41 i 5 GC5A-60 60 1020 27.8 178 910 24.6 15.0 410 40 120 41 j 5 GC5A-80 80 1020 27.8 17.8 910 24.6 15 0 450 62 20 41 | 5 J5A-80 60 780 28.7 10.0 770 28 6 18 0 | 570 40 23 43 ! 5 J5A-80 80 780 28.7 10.0 770 28.6 18.0 010 63 23 431 Рис. 3.30. Сравнительные характеристики воздушных компрессоров КОМПРЕССОР ТИП Модель 2 ДавлениеВоздушногоПотока HP ЕмкостьБака ПриблВесБрутто Длина Ширина Высота ОбМин Вытеснение Подача Рис. 3.31. Альтернативная модель данных о компрессорах 4) Предположим, что перед вами стоит задача объяснить различия между этими двумя моделями сообразительному пользователю. Как бы вы это сделали? 40. На рис. 3.32 показано расписание показов фильма «Люди в черном-2» в кинотеатрах Сиэтла. Оно имеет вид списка, каждый элемент которого выглядит следующим образом: название кинотеатра, после него в скоб- ках расстояние в милях от центра, в следующей строке адрес кинотеатра, а в третьей и последующих строках - список сеансов, Взяв за образец эти данные, выполните следующее.
Вопросы группы II 103 Men in Black II Even Tommy Lee Jones at his funniest can’t save Will Struth or this goofy alien flick from sequel-itis. Local Theaters and Showtime* 40 mile» from the center of Seattle, WA Ar? ft Tue, Jul 9 Thy Гц Displaying 1 - 32 results, sorted by distance. A.MC Pacific Place 11 (0.5 miles) 600 Pine St, Seattle (206) 652-2404 Showtimes: 11:00 am, 12:00 pm, 12:45 pm. 1:30 pm. 2:30 pm, 315 pm, 4:00 pm, 5:00 pm, 5:45 pm, 6:30 pm, 7:30 pm, 8:30 pm, 9:00 pm, 10:00 pm, 10 45 pm Neptung Theatre (3.9 miles) 1303 NE 45th, Seattle (206) 633-5545 Showtimes: 11:20 am, 1:30 pm, 3:40 pm, 5:50 pm, 8:00 pm, 10:10 pm Req^l S.tiUevuejGaHer»a„l £ (6.2 miles) 500 106th Ave NE, Bellevue (425) 451-7161 Showtimes: 11:00 am, 11:30 am, 1:00 pm, 1:39 pm, 3:00 pm, 3:30 pm, 5:05 pm, 5:35 pm, 7:10 pm, 7:40 pm, 9:20 pm, 9:50 pm I.С E OaIt. Tree Cine<n-a (6.6 miles) 10006 Aurora Ave N., Seattle (206) 527-1748 Showtimes: 11:45 am, 2:15 pm, 4:45 pm, ?;15 pm, 9:45 pm LCE Ffycton^ Cinemas 8 (7.8 miles) 3505 Factoria Blvd SE. Bellevue (425) 641-9206 Showtimes: 12:00 pm, 1:00 pm, 2:15 pm, 3:15 pm, 4:30 pm, 5:45 pm, 7:30 pm, 8:15 pm, 9:45 pm, 10:30 pm .KirHand..Parkplace X'inema (8 miles) 404 Parkplace Ctr, Kirkland (425) 827-9000 Showtimes: 12:15 pm, 2:30 pm, 4:45 pm, 7:20 pm, 9:35 pm Рис. 3.32. Расписание сеансов 1) Создайте модель данных для этого отчета, состоящую из сущностей ФИЛЬМ, КИНОТЕАТР и СЕАНС, Предположим, что в кинотеатрах могут де- монстрироваться и другие фильмы. Хотя изображенный здесь отчет от- носится к определенной дате, ваша модель данных должна позволять указывать расписание сеансов и для других дней. Укажите идентифи- каторы и атрибуты сущностей. Дайте имя каждой связи, укажите типы связей и их кардинальность. Укажите, какие значения кардинальных чисел можно логически вывести из рис. 3.32, а какие необходимо уточ- нить в разговоре с пользователями системы. Примем, что расстояние от центра города является атрибутом сущности КИНОТЕАТР. 2) Данный отчет был сделан для пользователя, который живет недалеко от центра Сиэтла. Пускай требуется составить такой же отчет, но те- перь для жителя пригорода, такого как Беллевью, Рентон, Редмонд или Такома (все это пригороды Сиэтла). В этом случае расстояние от цен- тра города не может быть атрибутом сущности КИНОТЕАТР. Измените ваш ответ на вопрос 1) для этой ситуации. Укажите идентификаторы и атрибуты сущностей. Дайте имя каждой связи, укажите типы связей и их кардинальность.
164 Глава 3. Создание моделей данных «сущность-связь» Теперь пусть стоит задача построить модель национального масшта- ба Модифицируйте ваш ответ на вопрос 2), чтобы его можно было использовать для различных городов, измените соответствующим об- разом ответ на вопрос 1). Укажите идентификаторы и атрибуты сущ- ностей. Дайте имя каждой связи, укажите типы связей и их карди- нальность. RICE KRISPIES NUTRITION INFORMATION SERVING &2Г iOZ(28.4 9.AaOUTlCUPJ SERVINGS PER PACKAGE. 13 MIHfcCW VITMWSA4D CALORIES PROTEIN CARBOHYDRATE FAT CHOLESTEROL SODIUM POTASSIUM 110 150* 2fi 6g 25 c 3ig OS 08’ 0 mg Omg" 290 mg 3$0mg 35 mg 240mg PERCENTAGE OF U.S. RECOMMENDED DAILY ALLOWANCES (U.S. RDA) PROTEIN 2 10 VIT AMIN A 25 30 VITAMIN C 25 25 THIAMIN 35 40 RIBOFLAVIN 35 45 niacin 35 35 CALCIUM 15 IRON 10 10 VITAMIN D 10 25 VITAMIN 8, 35 35 FOLIC ACID 35 35 PHOSPHORUS 15 MAGNESIUM z 6 ZINC 2 COPPER 2 ТЖ.?11/ AH APOTOW. 30 INGREDIENTS.- RICE. SUGAR Sai T CORN SYRUP, MALT FLAVORING WTAMIN C (SOOIUM ASCORBATE AND ASCORBIC ACID) NIACINAMIDE. IRON VITAMIN 8. IP¥- WDOXINE HYDROCNI ORIDB, VITAM N A (^!LaJ^,Tam‘n b* («’BOFlZJin* B< (THtAMfN HYDROCHLORIDE) AND VITAMIN 0 }' TO KEEP THIS CEREAL FRESH BHT HAS BEEN ADDED TO THE PACKAGING Отчет управления по контролю за продуктами и лекарстаами № 6272 Дата: 30.06.2003 Корпорация Kellogg's Название отчета: сводные данные о продуктах по ингредиентам Кукуруза Corn Flakes Krispix Nutngrain (Кукуруза) Кукурузный сироп Rice Krispies Frosted Flakes Sugar Pops Солод Rice Krispies Sugar Smacks Пшеница Sugar Smacks Nutrigrain (Пшеница) a СПИСОК ПОСТАВЩИКОВ Дата: 06.30.2003 Кукуруза Пшеница Ячмень Wilson J Perkins Pollack McKay Adams Kroner Schmidt Wilson Pollack 2.80 2 72 2.83 2.80 1.19 1.19 1.22 0.85 084 6 Рис. 3.33. Отчеты о содержании пищевых ингредиентов 4) Измените ваш ответ на вопрос 3), включив в модель имена ведущих актеров. Предположим, что роли, которые играют актеры, моделиро- вать не требуется. Укажите идентификаторы и атрибуты новых сущно-
Вопросы группы II 1вв стей. Дайте имя каждой вновь созданной связи, укажите типы связей и их кардинальность. 5) Измените ваш ответ на вопрос 4), включив в модель имена ведущих актеров. Теперь предположим, что роли моделировать нужно. Укажите идентификаторы и атрибуты новых сущностей. Дайте имя каждой вновь созданной связи, укажите типы связей и их кардинальность. 41. Изучите три отчета на рис. 3.33. Данные, указанные в них, типичны для подобного рода отчетов. 1) Создайте список потенциальных сущностей, содержащий столько эле- ментов, сколько, по вашему мнению, требуется. 2) Определите, не являются ли какие-либо из сущностей в вашем списке синонимами. Если да, оставьте в списке только один из каждой группы синонимов. 3) Постройте диаграмму стандарта IDEF1X, демонстрирующую связи ме- жду вашими сущностями. Дайте имя каждой связи и укажите карди- нальность. Укажите, какие значения кардинальных чисел можно логи- чески вывести из рис. 3.33, а какие необходимо уточнить в разговоре с пользователями системы. 42. Изучите обложку компакт-диска, изображенную на рис. 3.34. В верхней половине левой части обложки указаны название произведения, его авто- ры (автор идеи, автор книги, по которой написан мюзикл, авторы музыки и либретто), дирижер/хореограф, продюсеры и аранжировщики. В нижней половине левой части перечислены роли и актеры, их играющие. В правой части обложки перечислены композиции — порядковый номер, название, длительность и герои, исполняющие композиции. (Композицию под номе- ром 10 исполняет актриса Marilyn Horne.) 1) Укажите идентификаторы и атрибуты для сущностей КОМПАКТ-ДИСК, АРТИСТ, РОЛЬ и КОМПОЗИЦИЯ. 2) Сконструируйте диаграмму стандарта IDEF1X, демонстрирующую связи между этими сущностями. Дайте имя каждой связи и укажите карди- нальность. Укажите, какие значения кардинальных чисел можно вывес- ти из содержимого обложки компакт-диска, а какие необходимо уточ- нить в разговоре с пользователями системы. 3) Рассмотрите случай с компакт-диском, на котором записан не мю- зикл, а что-то другое. Очевидно, в этом случае отпадает необходимость в сущности РОЛЬ. Тем не менее, у нас есть необходимость во введении еще одной сущности — АВТОР. Создайте диаграмму стандарта IDEF1X, включающую сущности КОМПАКТ-ДИСК, АРТИСТ, КОМПОЗИЦИЯ и АВТОР. Пускай АРТИСТ может быть как одним лицом, так и группой. Предполо- жим, что некоторые артисты записывают произведения как в составе коллектива, так и по отдельности.
166 Глава 3, Создание моделей данных «сущность^связ^ West Side Story Based on a conception of Jerome Robbins Book by ARTHUR LAURENTS Music by LEONARD BERNSTEIN Lynes by STEPHEN SONDHEIM Entire Original Production Directed end Choreographed by JEROME ROBBINS________ Ongtnally produced on Broadway by Robert E. Griffith and Harold S Prince by arrangemenl with Roger L. Slevens Orchestration by Leonard Bernstein with Sid Ramm and Irwin Kostal HIGHLIGHTS FROM THE COMPLETE RECORDING f Maria........... KIRI ТЕ KANAWA Tony...............JOSE CARRERAS Anita..........TATIANA TROYANOS Riff................KURT OLLMAN and MARILYN HORNE singing «Somewhere» Rosalia..........Louise EdeikenDiesel...... .... Marty Nelson Consuela .. Stella Zambalis Baby John . Stephen Bogardus Fanctsca . Angelina ReauxA-rab Peter Thom Action .... David LivingstonSnowboy.. . ..... Todd Lester Bernardo .. Richard Harrell ГЛ Jet Sono 1—1 (Riff. Action, Beby John Arab Chorus [~2~] Somethings Coming ___, (Tony) [3] Merle ____ (Tony) [4| Tonight (Marla. Tony) [~5~| America (Anita Rosalia Chorus) [~б] Cool (Riff, Chorus) I 7 I One Hand. One Heart ____ (Tony Maria) I 8 | Tonight (Ensemble) ।___ (Entire Cast) I 9 1 I Feel Pretty (Maria. Chorus) [to] Somewhere (A Girt) |~tt] Geo OFicer Krupke (Action, snowboy. Diesel, A-rab. r—i Baby John. Chorus) LlxJ A Boy Like That .—। (Anita, Maria) U2J । Have a Love (Mana Anita) fid] Taunting Scene (Orchestra) fis] Finale L—' (Maria. Tony) t?**l И 47) K37J IW4 (340J (T22j И1Ч [2TSJ I3-3C4 П-21) [2-40] Рис. 3.34. Обложка компакт-диска 4) Объедините модели, разработанные вами при ответе на вопросы 2) и 3). Если это необходимо, создайте новые сущности, но стремитесь к тому, чтобы модель оставалась как можно более простой. Укажите идентификаторы и атрибуты новых сущностей. Дайте имя каждой вновь созданной связи, укажите типы связей и их кардинальность. Задачи по моделированию 43. Танцевальный клуб Джефферсона производит обучение танцам и предла- гает индивидуальные и групповые занятия. Плата составляет S45 в час с человека или пары при индивидуальных занятиях, и S6 в час с человека при групповых занятиях. Индивидуальные занятия проводятся на протя- жении всего дня, с полудня до 22 часов, шесть дней в неделю. Групповые занятия проводятся по вечерам. В танцевальном клубе работают два вида инструкторов: постоянные и при- ходящие. Постоянные инструкторы еженедельно получают фиксированную зарплату, а приходящие получают установленную сумму либо за вечер, либо за работу с конкретным классом. Кроме занятий, танцевальный клуб Джефферсона два раза в неделю орга- низует танцевальные вечеринки с музыкальными записями. Входная пла- та составляет $5 с человека. Танцевальный вечер в пятницу пользуется большей популярностью и собирает в среднем около 80 человек; воскрес-
Задачи по моделированию L 167 ный вечер собирает около 30 посетителей. Цель этих танцевальных вече- ров — предоставить ученикам место для пракгики. Еда и напитки не пре- дусматриваются. Танцевальный клуб хотел бы разработать информационную систему, ко- торая позволяла бы вести учет проведенных занятий и учеников. Помимо того, менеджеры клуба хотели бы знать количество и типы занятий, прове- денных каждым инструктором, а также иметь возможность подсчитать среднюю прибыль, приносимую каждым инструктором за одно занятие. Предположим, танцевальный клуб нанял вас для проектирования базы данных. Первым делом вы решаете создать модель данных. Вы знаете, что вам потребуется опросить пользователей и собрать формы, отчеты и дру- гие документы, могущие быть источником требований. Однако перед этим вы хотите сконструировать пробную модель данных. Вы надеетесь, что эта модель сможет помочь вам сформулировать конкретные вопросы, которые вы будете задавать персоналу танцевального клуба. 1) Для построения пробной модели прочтите описание работы клуба в пре- дыдущих абзацах и выделите из него все важные существительные. Из этих существительных составьте список потенциальных сущностей. 2) Исследуйте список, составленный вами при ответе на вопрос 1), и ис- ключите из него синонимы. Кроме того, идентифицируйте сущности, являющиеся подтипами или категориями. Укажите вероятный иденти- фикатор для каждой сущности. Удалите из модели сущности, суще- ствование которых трудно обосновать. 3) Приведенное выше описание содержит недостаточно данных, чтобы указать атрибуты для выявленных вами сущностей. Поэтому создайте дширамму стандарта IDEF1X, на которой будут показаны только сущ- ности и связи. Дайте имя каждой созданной связи, укажите типы свя- зей и их кардинальность. Обоснуйте принятые решения. 4) Теперь щюанализируйтс вашу модель и составьте список вопросов, от- веты на которые вы хотели бы получить у пользователей, чтобы соста- вить адекватную модель данных. 5) Как по-вашему, является ли удачной идея создания пробной модели данных до проведения опросов пользователей? В чем преимущества та- кого подхода? В чем его недостатки? 44. Бюро проката яхт Сан-Хуана — посредническая фирма, занимающаяся прокатом парусных яхт. Яхты не являются собственностью фирмы — она сдает их от имени владельцев, которые хотят получать доход от своих яхт, когда не пользуются ими. За свои услуги фирма Сан-Хуана берет плату. Фирма специализируется на яхтах, которые могут использоваться для многодневных или недельных походов: самая маленькая из яхт имеет дли- ну 28 футов, а самая большая — 51 фут.
Глава 3. Создание моделей данных «сущность-связь» Каждая яхта на момент сдачи в аренду полностью экипирована. Большая часть инвентаря предоставляется владельцами, но некоторый инвентарь добавляется фирмой. Инвентарь, предоставляемый владель м и, включа- ет в себя предметы, закрепленные на яхте, то есть радиос акции, компасы, глубиномеры и прочий инструмент, плиты и холодильники. Есть и другой инвентарь предоставляемый владельцами, но не являющийся частью яхты. Это могут быть паруса, лини, якоря, спасательные шлюпки, спасательные жилеты, а также то, что находится в каютах: блюда, столовое серебро, кухонные принадлежности, постельные принадлежности и т. д. Фирма Сан-Хуана предоставляет также расходуемый инвентарь и припасы — кар- ты, навигационные книги, таблицы приливов и течений, мыло, полотенца для посуды, туалетную бумагу и тому подобные предметы. Важной составляющей обязанностей фирмы Сан-Хуана является учет инвентаря, имеющегося на яхтах. Часть инвентаря является дорогой, а не- которая его часть, в частности та, что не закреплена на яхте, может легко потеряться или быть украдена. В течение срока проката яхты ответствен- ными за инвентарь являются клиенты. Фирма Сан-Хуана ведет подроб- ный учет клиентов и истории проката яхт. Это требуется не только для маркетинговых целей, но и для того, чтобы иметь записи о путешествиях клиентов. Некоторые маршруты и погодные условия более опасны, чем другие, поэтому фирма желает знать об опыте своих клиентов. По большей части фирма занимается только прокатом яхт, то есть капитан или команда не предоставляется. В некоторых случаях однако, клиенты заказывают услуги капитана или каких-либо других членов команды, и то- гда фирма нанимает соответствующий персонал на договорной основе. Яхты часто требуют обслуживания. Контракты, заключенные фирмой Сан-Хуана с владельцами лодок, требуют от фирмы ведения тщательной записи всех операций по обслуживанию и связанных с этим расходов, включая обычные операции, такие как мойка или замена масла, а также внеплановые ремонты. Иногда ремонт может потребоваться во время рей- са. Например, у яхты может отказать двигатель, когда она будет находить- ся далеко от доков Сан-Хуана. В этом случае клиенты вызывают по радио диспетчера фирмы, который определяет наиболее подходящее место для проведения ремонта и направляет персонал оттуда на аварийную яхту. Чтобы принимать все эти решения, диспетчерам требуется информация об имеющихся ремонтных доках, а также сведения о качестве и стоимости предыдущих ремонтов. Предположим, фирма Сан-Хуана наняла вас для проектирования базы данных. Первым делом вы решаете создать модель данных. Вы знаете, что вам потребуется опросить пользователей и собрать формы, отчеты и дру- гие документы, которые могут быть источником требований. Однако пе- ред этим вы хотите сконструировать пробную модель данных. Вы надее-
Вопросы к прочету *ичШр 1«t тесь, что эта модель сможет помочь вам сформулировать конкретные вопросы, которые вы будете задавать персоналу фирмы 1) Для построения пробной модели прочтите описание работы клуб* в f е- дыдущих абзацах и выделите из него все важные существительные Из этих существительных составьте список потенциальных сущностей 2) Исследуйте список, составленный вами при ответе на вопрос 1), и ис- ключите из него синонимы. Кроме того, идентифицируйте сущности, являющиеся подтипами или категориями. Укажите вероятный иденти- фикатор для каждой сущности. Удалите из модели сущности, суще- ствование которых трудно обосновать. 3) Приведенное выше описание содержит недостаточно данных, чтобы указать атрибуты для выявленных вами сущностей. Поэтому создайте диаграмму стандарта IDEF1X, на которой будут показаны только сущ- ности и связи. Дайте имя каждой созданной связи, укажите типы свя- зей и их кардинальность. Обоснуйте принятые решения. 4) Теперь проанализируйте вашу модель и составьте список вопросов, от- веты на которые вы бы хотели получить у пользователей, чтобы соста- вить адекватную модель данных. 5) Как по-вашему, является ли удачной идея создания пробной модели данных до проведения опроса пользователей? В чем преимущества та- кого подхода? В чем его недостатки? Вопросы к проекту FiredUp Вернитесь к вопросам проекта FiredUp, приведенным в конце главы 2, и ответь- те на них, если вы еще этого не сделали. 1. Рассмотрите шаги процесса моделирования данных (см. рис. 3.1) в контек- сте фирмы FiredUp. Без доступа к персоналу фирмы планирование проек- та по моделированию данных невозможно. Вместо этого составьте список вопросов, ответы на которые позволили бы вам составить план проекта. 2. Рассмотрите возможные источники требований (см. врезку «Источники требований к базе данных»). Как, по вашему мнению, все эти типы требо- ваний могли бы быть применимы к фирме FiredUp? Как вы документиро- вали бы выявленные вами требования? 3. Обратитесь к вашему ответу на вопрос 5 к проекту FiredUp, приведенный в конце главы 2. Как вы осуществили бы проверку этой модели данных? Составьте список вопросов, которые вы задали бы персоналу фирмы FiredUp. Как вы использовали бы макеты? Как вы использовали бы про- тотипы?
170 Глава 3. Создание моделей данных «сущность связь» Вопросы к проекту Twigs Tree Вернитесь к вопросам проекта Twigs Tree, приведенным в конце главы 2, и ответь- те на них, если вы еще этого нс сделали. 1. Рассмотрите шаги процесса моделирования данных (см. рис. 3.1) в контек- сте фирмы Twigs Tree. Без доступа к Саманте и другому персоналу фирмы (если он есть) планирование проекта по моделированию данных невозмож- но. Вместо этого составьте список вопросов, ответы па которые позволили бы вам составить план проекта. 2. Рассмотрите возможные источники требований (см. врезку «Источники требований к базе данных»). Как, по вашему мнению, все эти типы требо- ваний могли бы быть применимы к фирме Twigs Tree? Как вы документи- ровали бы выявленные вами требования? 3. Обратитесь к вашему ответу на вопрос 5 проекта Twigs Tree в конце пре- дыдущей главы. Как вы осуществили бы проверку этой модели данных? Составьте список вопросов, которые вы задали бы Саманте. Как вы ис- пользовали бы макеты? Как вы использовали бы прототипы?
Часть II Проектирование баз данных Во второй части книги рассматриваются вопросы проектирования баз данных. В главе 4 описываются реляционная модель и нормализация. Реляционная мо- дель является стандартом, в соответствии с которым проектируется большинство баз данных на сегодняшний день. Этот стандарт лежит в основе большей части современных СУБД. Важность нормализации состоит в том, что она позволяет проверить качество реляционной схемы. В главе 5 на базе идей, изложенных в гла- ве 4, описывается процесс преобразования моделей данных «сущность—связь» в не зависимые от СУБД реляционные схемы.
Глава 4 Реляционная модель и нормализация Реляционная модель является промышленным стандартом хранения и обработки информации в базах данных. В этой главе будут представлены основные понятия и идеи этой модели. Кроме того, будет рассмотрена нормализация - методика преобразования отношений, имеющих нежелательные свойства, в другие отно- шения, свободные от этих свойств. В главах 6—8 будет описываться SQL язык для определения и обработки отношений. Реляционная модель была впервые предложена Э. Ф. Коддом (Е. F. Codd) в эпохальной статье1 1970 года. Изначально реляционная модель воспринима- лась промышленностью как чересчур «теоретическая», медленная и громоздкая для высокоскоростной обработки транзакций. Это предубеждение было по- ст епенпо преодолено, и к 80-м годам XX века благодаря таким продуктам, как DB2 и Oracle, реляционные базы данных уже активно и успешно использова- лись для обработки больших объемов транзакций. Начнем паше изложение с определения нескольких ключевых понятий. Отношения В главе 1 было сказано, что реляционные СУБД хранят данные в форме таблиц. В действительности это не совсем так. Реляционные СУБД хранят данные в форме отношений, которые представляют собой особую разновидность таблиц. Отно- шением (relation) называется двухмерная таблица, обладающая характеристиками, которые перечислены в приведенной ниже врезке. Во-первых, каждая строка та- кой таблицы содержит данные, описывающие некоторую сущность или ее часть. Во-вторых, каждый столбец таблицы представляет один из атрибутов данной сущности. Так, например, в отношении СОТРУДНИК каждая строка содержит дан- 1 о ределенном сотруднике, а каждый столбец содержит определенную ха- рактеристику сотрудника - имя, телефон или адрес электронной почты, 1 OR W7^td377 эд,tional Model of Data for Ur2° Shared Databanks», Communication of the ACM, vU. 1J/U, Ij. Л! 1—лЦ/
Отношение 17> ХАРАКТЕРИСТИКИ ОТНОШЕНИЯ ------------------------------------------—--------I ♦ Строки содержат данные о сущности. ♦ Столбцы содержат данные об атрибутах сущности ♦ Ячейки таблицы содержат одиночные значения ♦ Все записи в одном столбце имеют один и тот же тип ♦ Каждый столбец имеет уникальное имя ♦ Порядок следования столбцов не важен ♦ Порядок следования строк не важен ♦ Не может быть двух идентичных строк. Кроме того, чтобы таблица могла считаться отношением, каждая ее ячейка должна содержать одно и только одно значение; повторяющиеся элементы в ячей- ке недопустимы. Еще необходимо, чтобы все записи в одном и том же столбце принадлежали к одному и тому' же типу. Например, если третий столбец первой строки таблицы содержит табельный номер сотрудника, то и во всех остальных строках третий столбец также должен содержать табельный номер Каждый столбец отношения имеет уникальное имя, и порядок расположения столбцов несуществен. Наконец, в отношении не может быть двух идентичных строк. Пример отношения и две таблицы, не являющиеся отношениями Таблица 4.1 носит название СОТРУДНИК. Рассмотрим эту таблицу в свете характери- стик, перечисленных во врезке «Характеристики отношения». Во-первых, в каж- дой ее строке содержатся данные о конкретном экземпляре сущности СОТРУДНИК, а каждый столбец представляет определенный атрибут сотрудника. Первые два условия, таким образом, выполнены. В каждой ячейке содержится только одно значение, и все ячейки в столбце принадлежат к одному и тому же типу’. Имена столбцов являются уникальными, а порядок следования столбцов и строк можно свободно менять, не опасаясь потери информации. Наконец, в таблице нет одина- ковых строк. Поскольку данная таблица удовлетворяет всем требованиям, пере- численным во врезке, мы можем классифицировать ее как отношение. Таблица 4.1. СОТРУДНИК НомерСотрудника Имя Фамилия Отдел АдресЭлПочты Телефон 100 Джерри Джонсон Бухгалтерия JJ@somewhere.com 236-9987 200 Мэри Абернати Финансы MA@somewhere.com 444-8898 300 Лиз Сматерс Финансы LS@somewhere.com 777-0098 400 Том Карутерс Бухгалтерия TC@somewhere.com 236-9987 500 Том Джексон Производство TJ@somewhere.com 444-9980 600 Элеонора Калдера Юридический EC@somewhere.com 767-0900 700 Ричард Бандалон Юридический RB@somewhere. com 767-0900 Таблицы 4.2, а и 4.2, б не являются отношениями. Таблица СОТРУДНИК не яв- ляется отношением потому, что в столбце Телефон имеются ячейки, содержащие
174 Глава 4. Реляционная модель и нормализация несколько значении (табл. 4.2, «). Для Тома Карутерса указано три номера теле- фона, а для Ричарда Бандалона - два. Мы же с вами знаем, что в ячейке отноше- ния недопустимы множественные записи. Таблица 4.2, а. Таблица, где важен порядок строк НомерСотрудника Имя Фамилия Отдел АдресЭлПочты Телефон 100 Джерри Джонсон Бухгалтерия JJ@somewhere.com 236-9987 200 Мэри Абернати Финансы М A@somewhere. com 444-8898 300 Лиз Сматерс Финансы LS@somewhere com 777-0098 400 Том Карутерс Бухгалтерия TC@somewhere.com 236-9987, 266-9987, 555-7171 500 Том Джексон Производство TJ@somewhere.com 444-9980 600 Элеонора Калдера Юридический EC@somewhere.com 767-0900 700 Ричард Бандалон Юридический RB@somewhere.com 767-0900 Таблица 4.2, б. Таблица, где в одной ячейке имеется несколько записей НомерСотрудника Имя Фамилия Отдел АдресЭлПочты Телефон 100 Джерри Джонсон Бухгалтерия JJ@somewhere.com 236-9987 200 Мэри Абернати Финансы MA@somewhere.com 444-8898 300 Лиз СмаУерс Финансы LS@somewhere.com 777-0098 400 Том Карутерс Бухгалтерия TC@somewhere. com Факс Домашний телефон: 236-9987 266-9987 555-7171 500 Том Джексон Производство TJ@somewhere.com 444-9980 600 Элеонора Калдера Юридический EC@somewhere.com Факс Домашний телефон: 767-0900 236-9987 555-7171 700 Ричард Бандалон Юридический R B@somewhere .com 767-0900_ 1 аблица 4.2, б не является отношением но двум причинам. Во-первых, порядок следования строк является в ней существенным. В строке, следующей за строкой с именем Тома Карутерса, указан номер его факса. Если мы изменим порядок строк, мы можем потерять связь между Томом Карутерсом и номером его факса, торая причина заключается в том, что не все значения в столбце АдресЭл.Почты имеют одинаковый тип. Одни из них являются адресами электронной почты, & Другие характеристиками номеров телефонов. Обратите внимание, между прочим, что хотя в ячейке отношения может быть максимум одно значение, длина его может быть различной. Таблица 4.3 пред- ставляет собой модификацию табл. 4.2, отличающуюся тем, что в нее добавлен столбец переменной длины под названием Комментарий Хотя комментарии мо- гут быть весьма длинными, а длина их колеблется от строки к строке, в одной ячейке по-прежнему содержится только один комментарий. Таким образом, табл. 4.3 является отношением.
Таблица 4.3. Отношение с атриоутом переменной длины НомерСотрудника 100 Имя Фамилия Отдел АдресЭлПочты Джерри Джонсон Бухгалтерия JJ©somewherecom Телефон 230 9987 Комментарии Приступил к работе а бухгалтерии а марта, получив степень магистра делового администрирования. Этой осенью будет сдавать экзамен на дипломироаамюгр бухгалтера Мэри Абернати Лиз Сматерс Том Карутерс Том Джексон Эгих»юра Калдера Ричард Бандалон Финансы MA®>somewhere com 444-8898 Финансы LS®somewhere com 777-0098 Бухгалтерия TC©somewher® com 238-9987 Производство Tj4»svHX>wtM?re com 444-9980 Юридический EC ' vi. recom 767-0900 Юридический RB чч-иЛм-ге com 767-0900 Работает в ко метео постои «юга «оисутмтанта «рнмимсяого отдела на условиях
176 Глава 4. Реляционная модель и нормализация Замечание по терминологии В мире баз данных термины таблица и отношение используются обычно как си- нонимы Соответственно, с этого момента на протяжении всей книги мы будем этого придерживаться. Теперь каждый раз, используя термин таблица мы будем иметь в виду таблицу, обладающую качествами, которые перечислены во врезке «Характеристики отношения». Но имейте в виду, что есть такие таблицы, кото- рые в строгом смысле слова не являются отношениями. Иногда, особенно в контексте традиционной обработки данных, вместо ти- мина отношение используются термины файл (file) или файл данных (data file). При этом строки отношения называются записями (records), а столбцы полями (fields). Но на этом путаница не кончается. Теоретики баз данных также исполь- зуют свою собственную терминологию: отношения они называют отношениями, столбцы - атрибутами (attributes), а строки - кортежами (tuples). Кроме того, зачастую люди смешивают эти наборы терминов. Обычное дело — слышать рас- суждения об отношении, у которого есть строки и поля. Пока вы знаете, о чем идет речь, это смешение не играет роли. Но прежде чем мы двинемся дальше, необходимо упомянуть еще один потенци- альный источник недоразумений. Согласно врезке «Характеристики отношения», таблица, имеющая одинаковые строки, не является отношением. На практике, однако, этим условием часто пренебрегают. Иногда, особенно при манипулиро- вании отношениями с помощью SQL, мы можем получить таблицу, в которой будут одинаковые строки. Чтобы превратить эту таблицу в отношение, нам сле- довало бы удалить дубликаты. Но если размеры таблицы велики, проверка на наличие одинаковых строк может занимать слишком много времени, поэтому по умолчанию в СУБД такая проверка не выполняется. Итак, на практике сущест- вуют таблицы с дублирующимися строками, которые, тем не менее, называются отношениями. С примерами этой ситуации вы столкнетесь в главе 6. Типы ключей Ключ (key) — это один или несколько столбцов, идентифицирующие строку отношения. Ключ может быть уникальным или неуникальным. Например, для отношения в табл. 4.1 столбец НомерСотрудника является уникальным ключом (unique key), поскольку имеет место взаимно однозначное соотношение между значением атрибута НомерСотрудника и строкой отношения СОТРУДНИК. Таким образом, запрос, предписывающий найти все строки отношения СОТРУДНИК, в ко- торых значение атрибута НомерСотрудника равно 200, выдаст единственную стро- ку. Атрибут Отдел является неуникалъиым ключом (non-unique key). Он является ключом, поскольку с его помощью можно идентифицировать строку отношения, но он не уникален, поскольку потенциально одно и то же значение атрибута Отдел может иметь несколько строк отношения. Запрос, предписывающий найти все строки отношения СОТРУДНИК, в которых значение атрибута Отдел равно Бухгал- терия, выдаст несколько строк.
Типы ключе i 177 Из данных табл. 4.1 может создаться впечатление, что атрибуты НомерСотруд- ника, Фамилия и АдресЭлПочты Являются уникальными идентификаторами. Но для того, чтобы решить, так ли это на самом деле, одних приведенных здесь данных недостаточно. О том, является ли тот или иной столбец уникальным, разра- ботчики должны спросить у пользователей или у других специалистов в данной области. Хороший пример — столбец Фамилия. Скорее всего, это просто случай- ность, что все фамилии в наших данных оказались различными. Если спро- сить пользователей, они, вероятно, скажут, что столбец Фамилия в отношении СОТРУДНИК не всегда является уникальным. Композитные ключи Допустим, пользователи говорят, что в общем случае столбец Фамилия не явля- ется уникальным, зато этим свойством обладает комбинация столбцов Фамилия и Отдел. Видимо, у пользователей есть какие-то соображения, позволяющие за- ключить, что в одном и том же отделе ни при каких условиях не будет двух со- трудников с одинаковыми фамилиями. Если это так, то комбинация {Фамилия, От- дел) является уникальным ключом. Ключ, содержащий два или более атрибута, называется композитным ключом (composite key). Например, уникальная комби- нация {Имя Фамилия, Отдел), будет представлять собой композитный ключ с тремя атрибутами. Первичные ключи и ключ и-кандидаты Теперь предположим, что, по словам пользователей, уникальными ключами яв- ляются атрибут НомерСотрудника, атрибут АдресЭлПочты и комбинация атрибутов {Имя, Фамилия, Отдел). Как вы узнаете из следующей главы, при проектировании базы данных один из этих уникальных идентификаторов необходимо выбрать на роль первичного ключа (primary key). Прочие уникальные ключи называются ключами-кандидатами (candidate keys), поскольку они являются кандидатами на роль первичного ключа. Первичный ключ важен не только тем, что с его помощью можно однознач- но ссылаться на строки, но и тем, что он может представлять строки отношения в связях. (Пример использования идентификационных ключей вы могли видеть в главе 1, в описании базы данных фирмы Lakeview.) Кроме того, во многих СУБД используется способ хранения отношений, основывающийся на значении первичного ключа. СУБД также строят индексы и другие специальные структу- ры, облегчающие и ускоряющие нахождение строк на физическом носителе по значению первичного ключа. Иногда для обозначения отношений применяется следующая схема: сначала указывается имя отношения, а за ним в скобках перечисляются имена атрибутов. Первичный ключ отношения подчеркивается. Например следующая запись обо- значает отношение под названием КЛИЕНТ, имеющее столбцы НомерКлиента, Имя, АдресЭлПочты, Телефон и Баланс: КЛИЕНТ (НзвыКлиента, Имя, АдресЭлПочты, Телефон, Баланс)
178 Глава 4. Реляционная модель и нормализация Первичным ключом огиошеппя КЛИЕНТ яиляекя стлбен НоиерКлиен» У т. го отношения могут быть также ключи •кандидаты, ио они нри данном записи не показываются. функциональные зависимое! и Чтобы понять, что такое функциональные зависимости, сделаем небольшой экс- курс в алгебру. Представьте, что вы покупаете печенье в коробках, и вам говорят что одна коробка стоит $4. Зная это г факт, вы можете вычислить стоимость не- скольких коробок печенья по формуле. СтоимостьПеченья = КоличествоКоробок х $4 Если мы захотим выразить связь между стоимостью печенья и количеством коробок в более общем виде, мы скажем, что стоимость печенья зависит от коли- чества коробок. Это высказывание сообщает нам о характере связи между сто- имостью печенья и количеством коробок, хотя и не дает конкретной формулы. Говоря более формальным языком, стоимость печенья функционально зависит от количества коробок. Данное утверждение может быть записано так: КоличествоКоробок -» СтоимостьПеченья Это выражение можно также прочесть следующим образом: «КоличествоКоро- бок определяет СтоимостьПеченья». Переменная, стоящая слева (в данном случае это КоличествоКоробок), называется детерминантом (determinant). В следующем примере мы вычисляем стоимость приобретаемых деталей, умножая количество деталей на цену одной детали: Стоимость = Количество х Цена В этом случае мы можем сказать, что стоимость функционально зависит от количества и цены, иначе говоря, (Количество, Цена) —> Стоимость Здесь комбинация (Количество, Цена) является детерминантом величины Стоимость. Теперь разовьем эти идеи несколько дальше. Допустим, перед вами лежит ме- шок, о котором вы знаете, что он содержит красные, синие и желтые объекты. Известно также, что красные объекты весят 2 кг, синие 1 кг, а желтые 1,5 кг. Если ваш приятель заглянет в мешок, увидит некоторый объект и сообщит вам его цвет, вы сможете определить вес этого объекта. Этот процесс можно формализо- вать точно так же, как это делалось в предыдущих примерах: ЦветОбъекта -> Масса Таким образом, масса функционально зависит от цвета объекта, или цвет объекта определяет массу. Имеющаяся здесь связь не подразумевает равенства, ио функциональная зависимость, тем не менее, остается. Зная цвет объекта, мы можем определить его массу. Если мы при этом знаем, чго красные объекты имеют форму шара, а синие и желтые — куба, можно также утверждать, что ЦветОбъекта -> (Масса, Форма)
Типы ключей 179 Итак, цвет объекта определяет его массу и форму. Один из способов выразить все эти факты — составить таблицу наподобие следующей. ЦветОбъекта Масса Форма Красный 2 Шар Синий 1 Куб Желтый 1,5 Куб Эта таблица удовлетворяет всем условиям, перечисленным в разделе «Отно- шения» (врезка «Характеристики отношения»), поэтому мы можем называть ее отношением. Первичным ключом этой таблицы является столбец ЦветОбъекта. Записать это отношение можно так: ОБЪЕКТ (ЦветОбъекта, Вес, Форма) Вам может показаться, что мы для получения этого отношения проделали ка- кой-то хитрый трюк, но на самом деле единственное применение отношений — это именно хранение экземпляров функциональных зависимостей. Если у нас есть отношение вида РАСТЕНИЕ (Вид, НомерРастения, Стоимость, Цена) мы храним факты о функциональной зависимости НомерРастения -> (Вид, Стоимость, Цена) Функциональные зависимости с композитными группами Компоипные группы, такие как (Количество, Цена), могут появляться на обеих сторонах функциональной зависимости. Но значение группы меняется в зависи- мости от того, на какой стороне она находится. Например, НомерЗаказа -> (НомерКлиента, КодТовара, Количество) означает, что, зная помер заказа, мы можем определить номер клиента, код товара и количество. Это выражение можно записать как совокупность трех выражений: НомерЗаказа -> НомерКлиента НомерЗаказа -> КодТовара НомерЗаказа -> Количество С другой стороны, выражение (НомерКлиента, КодТовара, Количество) -> Стоимость будет означать, что, зная номер клиента, код товара и количество товара, мы мо- жем определить его стоимость. Обратите внимание, что здесь мы не можем разде- лить детерминант на отдельные составляющие. Например, из приведенной выше формулы не следует, что НомерКлиента —> Стоимость Чтобы получить значение атрибута Стоимость, нам необходимы все три состав- ляющие детерминанта.
180 Глава 4. Реляционная мод.дь и нормали 18ци« Разница между первичным ключом и детерминантом Прежде чем мы двинемся дальше, важно, чтобы вы поняли следующую иь хотя первичный ключ всегда является детерминантом детерминант не </л,а» телъно является первичным ключом. Рассмотрим следуют» »- отношение ПРОЖИВАНИЕ (НомерСтжни. НазваниеОбщежития, Плата) Здесь НомерСтудента является идентификатором студента, НазваниеОб^Жг ,। говорит само за себя, а Плата - это плата за проживание в общежитии Прем» дожим. что все студенты, проживающие в одном общежитии, платят одинаковую СУММУ. Поскольку НомерСтудента является первичным ключом, мы знаем, что Номер- Студента -> (НазваниеОбщежития, Плата). Таким образом. НомерСтудента - это од- новременно и первичный ключ, и детерминант. Кроме того, поскольку все студен- ты, проживающие в одном общежитии, платят одинаково, то НазваниеОбщежития —> Плата. Следовательно, НазваниеОбщежития является детерминантом, но не первич- ным ключом. Нормализация К сожалению, не все отношения одинаково желательны. Таблица, отвечающая минимальному определению отношения, может иметь неэффективную или не- подходящую структуру. Для некоторых отношений изменение данных может привести к нежелательным последствиям, называемым аномалиями модифика- ции (modification anomalies). Аномалии могут быть устранены путем разбиения исходного отношения па два или более новых отношения. В большинстве случаев переопределенные, или нормализованные, отношения являются более предпочти- тельными. Аномалии модификации Рассмотрим отношение СЕКЦИЯ на рис. 4.1. Если мы удалим строку с данными о студенте номер 100, мы потеряем информацию не только о том, что этот студент является лыжником, но и о том, что абонемент в секцию лыж стоит $200. Это на- зывается аномалией удаления (deletion anomaly). Суть ее в том, что удаляя ин- формацию об одной сущности (студент с номером 100 является лыжником), мы теряем факты, относящиеся к другой сущности (плата за абонемент в секцию лыж составляет $200). Выполнив одну операцию удаления, мы теряем информа- цию о двух сущностях. Па примере тою же самого отношения можно продемонстрировать аномалию вставки (insertion anomaly). Допустим, нам нужно записать в базу данных ин- формацию о том, что абонемент в секцию подводного плавания стоит $175. Но мы не можем ввести эти сведения в отношение СЕКЦИЯ, пока хотя бы один сту- ден7 не запишется в секцию подводного плавания. Это ограничение выглядит глупо. Почему для того, чтобы указать стоимость абонемента, требуется ждать,
Нормализация 181 пока кто-нибудь не запишется в секцию? Это ограничение называется аномали- ей вставки. Суть его в том, что мы не можем записать в таблицу некоторый факт об одной сущности, не указав дополнительно некоторый факт о другой сущности СЕКЦИЯ (Нь-мооСтудонта. Секция, Плата) Номер Студента Секция Плата 100 Лыжи 200 150 Плавание 50 175 Сквош 50 200 Плавание 50 Рис. 4.1. Отношение СЕКЦИЯ Отношение на рис. 4.1 может быть использовано в некоторых приложениях, но оно имеет явные проблемы. Мы можем устранить как аномалию удаления, так и аномалию вставки, разделив отношение СЕКЦИЯ на два отношения, каж- дое из которых будет содержать информацию на определенную тему. Например, в одно отношение мы поместим атрибуты НомерСтудента и Секция (назовем это отношение СТУДЕНТ—СЕКЦИЯ), а в другое — атрибуты Секция и Плата (назовем это отношение СЕКЦИЯ—ПЛАТА). На рис. 4.2 изображены те же данные, что и на рнс. 4.1, но разнесенные по двум отношениям. СТУДЕНТ—СЕКЦИЯ (ЧЗМййСтУДйИИ, Секция) Номер Студента Секция 100 Лыжи 150 Плавание 175 Сквош 200 Плавание СЕКЦИЯ—ПЛАТА (СЕКЦИЯ. Плата) Секция Номер Студента Лыжи 200 Плавание 50 Сквош 50 Рис. 4.2. Два отношения, полученных из отношения СЕКЦИЯ Теперь, если мы удалим запись о студенте с номером 100 из таблицы СТУДЕНТ СЕКЦИЯ, мы уже не потеряем тот факт, что абонемент в секцию лыж стоит $200. Более того, мы можем добавить в таблицу СЕКЦИЯ ПЛАТА секцию подводного плавания с указанием стоимости абонемента, не дожидаясь, пока кто-либо запи- шется в эту секцию. Таким образом, аномалии удаления и вставки устранены. Разбиение одного отношения на два имеет, тем не менее, один недостаток. Представим себе ситуацию, когда студент хочет записаться в несуществующую секцию. Пусть, например, студент номер 250 хочет записаться в секцию ракетбо- ia. Мы можем вставить соответствующую строку в отношение СТУДЕНТ СЕКЦИЯ (эта строка будет содержать запись (250, Ракетбол)), но следует ли это делать? Стоит ли разрешать студенту записываться в секцию, которая отсутствует в отно- шении СЕКЦИЯ—ПЛАТА? Другими словами, должна ли система каким-либо обра- зом препятствовать добавлению строк в таблицу СТУДЕНТ—СЕКЦИЯ, если название соответствующей секции отсутствует в таблице СЕКЦИЯ—ПЛАТА? Ответ на этот “опрос содержится в требованиях пользователей. Если такое действие должно
182 Глава 4 Реляционная модель и нормализация быть запрещено, данное ограничение (а оно является не чем иным, как бизнес, правилом) необходимо внести в схему базы данных. Позже, па стадии рсализд. цпп выполнение этого ограничения будет возложено па СУБД, если исно.чьзу емая СУБД предоставляет такую возможность. Если нет, то соблюдение ограни ченпя должно обеспечиваться прикладными iipoi раммами Допустим, пользователи говорят, что спортивные секции могут существо- вать п ю того, как кто-лиоо в них запишется, однако студент нс можс! ^апи** саться в секцию, для которой не указан размер абонементной платы (то есть в секцию, данные о которой отсутствуют в таблице СЕКЦИЯ—ПЛАТА). При проек- тировании базы данных это ограничение можно сформулировать любым из сле- дующих способов: «множество значений атрибута Секция в отношении СТУДЕНТ- СЕКЦИЯ является подмножеством множества значений атрибута Секция в отноше- нии СЕКЦИЯ—ПЛАТА», либо «СТУДЕНТ—СЕКЦИЯ [Секция] является подмножест- вом СЕКЦИЯ—ПЛАТА [Секция]», либо «СТУДЕНТ—СЕКЦИЯ [Секция] с СЕКЦИЯ—ПЛАТА [Секция]». Квадратные скобки в этой записи обозначают столбец данных, извлекаемый из отношения. Смысл этих выражений в том, что атрибут Секция в отношении СТУДЕНТ—СЕКЦИЯ может принимать только те значения, которые имеет атрибут Секция в отношении СЕКЦИЯ—ПЛАТА. Это означает также, что прежде чем ввести название какой-то секции в отношение СТУДЕНТ—СЕКЦИЯ, мы должны проверить, что такое название уже существует в отношении СЕКЦИЯ—ПЛАТА. Ограничения, подобные этому, называются ограничениями ссылочной целостности (referential integrity constraints). Суть нормализации Аномалии, присутствующие в отношении на рис. 4.1, можно интуитивно описать следующим образом. Проблемы возникают из-за того, что отношение СЕКЦИЯ со- держит факты, относящиеся к двум различным темам, а именно: 1) кто из студентов какую секцию посещает; 2) какова абонементная плата в каждой из секций. Дооавляя новую строку, мы вынуждены указывать в ней информацию, затра- I ивающую две различные темы; точно так же, удаляя строку, мы поневоле удаля- ем данные, относящиеся сразу к двум темам. Суть процесса нормализации состоит в следующем. Каждое нормализован- ное 01 ношение должно иметь одну-единствеиную тему. Любое отношение, затрагивающее две или более темы, следует разбить на два или более отношения, у каждого из которых будет только одна тема. Когда мы обнаруживаем отноше- ние с аномалиями модификации, мы устраняем эти аномалии, разбивая отно- шение на два или более новых отношения, каждое из которых имеет собствен- ную тему. При этом не стоит забывать, что разбивая отношение, мы, возможно, порож- даем ограничение ссылочной целостности. Поэтому всякий раз, выполнив эту операцию, следует проверять, не возникли ли новые ограничения
Нормализация 183 В оставвгейся части главы вам предстоит познакомиться с правилами норма- лизации. Все эти правила представляют собой частные случаи только что они сапного процесса. Классы отношений Отношения можно классифицировать по типам аномалий модификации, кото- рым они подвержены. В 1970-х годах теоретики реляционных баз данных посте- пенно сокращали количество этих типов. Кто-то находил аномалию, классифи- цировал ее и думал, как предотвратить ее возникновение. Каждый раз, когда это происходило, критерии построения отношений совершенствовались. Эти классы отношений и способы предотвращения аномалий называются нормальными фор- мами (normal forms). В зависимости от своей структуры, отношение может быть в первой, второй или какой-либо другой нормальной форме. Как показывает рис. 4.3, эти нормальные формы как бы вложены друг в дру- га. То есть отношение во второй нормальной форме является также отношением в первой нормальной форме, а отношение в 5НФ (пятая нормальная форма) на- ходится одновременно в 4НФ, НФБК, ЗНФ, 2НФ и 1НФ. Первая нормальная форма (1НФ) Вторая нормальная форма (2НФ) Третья нормальная форма (ЗНФ) Нормальная форма Бойса—Кодда (НФБК) Четвертая нормальная форма (4НФ) Пятая нормальная форма (5НФ) * Доменно-ключевая нормальная форма (ДКНФ) Рис. 4.3. Взаимосвязь нормальных форм Будучи весьма полезными, нормальные формы имели одно серьезное ограни- чение: не существовало теории, гарантирующей, что какая-либо из этих форм устранит все аномалии. Каждая форма могла устранить только определенные их виды. Эта ситуация разрешилась в 1981 году, когда Р. Фагин (R. Fagin) ввел новую нормальную форму, которую он назвал доменно-ключевой нормальной формой (domain/key normal form), или ДКНФ (DKNF). В важной статье Фагин показал, что отношение в ДКНФ свободно от аномалий модификации всех ти- пов . Он также показал, что любое отношение, свободное от аномалий модифи- кации, должно находиться в ДКНФ. До введения ДКНФ теоретикам реляционных баз данных приходилось про- должать поиск все новых и новых аномалий и нормальных форм. Доказательство 4 агина упростило ситуацию. Если мы можем привести отношение к ДКНФ, то можем быть уверены, что в нем не будет аномалий модификации. Вся загвоздка в том, как привести отношение к ДКНФ. 'К111. «А Normal Form for Relational Databases That Is Based On Domains and Keys», ACM Transactions >n Database Systems, September 1981, pp. 387-415.
184 Глава 4. Реляционная модель и нормализация Нормальные формы от первой до пятой О любой таблице лютых, удомеп«>р«»Ш’П оп^лм-пто отношения что она находится в первой нормальной форме (first normal form, INF) Как эд помните, для того, чтобы таблица была m ношением, она должна обладать дадам- терпстпками, перечисленными в разделе «О i ношения». Отношение на рис. 4.1 находится в первой нормальной форме Как мы толы» что убедились, отношения в первой нормальной форме могут иметь аномалии модификации. Чтобы устранить эти аномалии, мы разбиваем исходное отноше- ние на два пли более новых отношения. Когда мы делаем это, новые отношения оказываются в некоторой другой нормальной форме. Какая именно форма это будет, зависит от того, какие аномалии мы устранили, а также от того, каким аномалиям подвержены получившиеся отношения. 9 1 С Вторая нормальная форма (2НФ) Чтобы понять, что такое вторая нормальная форма, рассмотрим отношение СЕКЦИИ на рис. 4.4. Это отношение имеет аномалии модификации, подобные тем, которые мы рассматривали ранее. Если мы удалим строку с данными о студенте номер 175, мы потеряем тот факт, что абонемент в секцию сквоша стоит S50. Кро- ме того, мы не можем ввести информацию о новой секции, пока в эту секцию не запишется хотя бы один студент. Таким образом, данное отношение подвержено как аномалии удаления, так и аномалии вставки. •Й СЕКЦИИ (НомерСтудента, Секция, Плата) Номер Студента Секция Плата 100 Лыжи 200 100 Гольф 65 150 Плавание 50 175 Сквош 50 175 Плавание 50 200 Плавание 1 50 200 Гольф 65 я Pup. 4.4. Отношение СЕКЦИИ Проблема с этим отношением состоит в том, что оно содержит зависимость, затрагивающую только часть ключа. Ключом является комбинация (НомерСтудента. Секция), но отношение содержит зависимость Секция -> Плата. Детерминант этой зависимости (Секция) представляет собой лишь часть ключа (НомерСтудента, Секция). В этом случае мы можем сказать, что атрибут Плата частично зависит от ключа таб- лицы. номалий модификации не оыло бы, если бы Плата зависела от всего ключа, т ы устранить эти аномалии, мы должны разделить отношение на два отношения. Данный пример приводит нас к определению второй нормальной формы (second normal lonn, 2NF): отношение находится во второй нормальной форме, если каждый из его неключевых атрибутов зависит от всего ключа. В соответ-
Нормальные формы от первой др пятой 186 ствии с этим определением, если отношение имеет в качестве ключа единственный атрибут то оно автоматически находится во второй нормальной форме По- скольку’ключ состоит из одного атрибута, то само собой разумеется, что каждый неключевой атрибут зависит от всего ключа, и частичных зависимостей быть не может. Таким образом, вторая нормальная форма представляет интерес только для тех отношений, которые имеют композитные ключи. Отношение СЕКЦИИ может быть разбито на два отношения во второй нормаль- ной форме. Это те самые отношения, которые изображены на рис. 4 2, а именно СТУДЕНТ—СЕКЦИЯ и СЕКЦИЯ—ПЛАТА. Мы знаем, что новые отношения находятся во второй нормальной форме, поскольку у них обоих ключ состоит из одного атрибута. Третья нормальная форма (ЗНФ) Отношения во второй нормальной форме также могут иметь аномалии. Рассмот- рим отношение ПРОЖИВАНИЕ на рис. 4.5, а. Ключом здесь является НомерСтудента, и имеют место функциональные зависимости НомерСтудента -> Общежитие и Обще- житие -> Плата. Эти зависимости возникают потому, что каждый студент живет только в одном общежитии, и каждое общежитие взимает со всех проживающих в нем студентов одинаковую плату. Например, каждый живущий в общежитии Рэндольф-Холл платит $3200 за квартал. ПРОЖИВАНИЕ (Н.-ыиаСтулиНта, Общежитие, Плата) Ключ: НомерСтудента Функциональные зависимости: Общежитие -> Плата НомерСтудента -> Общежитие -> Плата Номер Студента Общежитие Плата 100 Рэндольф 3200 150 Ингерсолл 3100 200 Рэндольф 3200 250 Питкин 3100 300 Рэндольф 3200 а СТУДЕНТ—ПРОЖИВАНИЕ (НоыеоСтУЭДНта Общежитие) Номер Студента Общежитие 100 Рэндольф 150 Ингерсолл 200 Рэндольф 250 Питкин 1 300 Рэндольф ОБЩЕЖИТИЕ—ПЛАТА (Общежитие. Плата) Общежитие Плата Рэндольф 3200 Ингерсолл 3100 Питкин 3100 б р«. 4.5. Устранение транзитивной зависимости: а — отношение с тп^т-,.;. зависимостью, б - два отношения, не имеющие транзи7ив™Х^^
186 Глава 4. Реляционная модель и нормализация Поскольку атрибут НомерСтудента определяет атрибут Общежитие, а атрибут Общежитие определяет атрибут Плата, то косвенным образом НомерСтудента -> Пла- та Такая структура функциональных зависимое!ей называется тпраизитпиииьй зависимостью (transitive dependency), поскольку атрибут НомерСтудента опреде- ляет атрибут Плата через атрибут Общежитие. Ключом отношения ПРОЖИВАНИЕ является одиночный атрибут НомерСтудента, следовательно, отношение находится во второй нормальной форме (и Общежитие и Плата определяются атрибутом НомерСтудента). Несмотря на это, отношение ПРОЖИВАНИЕ имеет аномалии, обусловленные транзитивной зависимостью Что произойдет, если мы удалим вторую строку отношения на рис. 4.5, я? Мы потеряем не только информацию о том, что студент номер 150 живет в Ингер- солл-Холле, но и тот факт, что проживание в этом общежитии стоит $3100. Это аномалия удаления. А как нам зафиксировать тот факт, что плата за проживание в Кэрригг-Холле составляет $3500? Никак, пока в него не решит вселиться хотя бы один студент. Это аномалия вставки. Чтобы удалить аномалии из отношения во второй нормальной форме, необ- ходимо устранить транзитивную зависимость, что приводит нас к определе- нию третьей нормальной формы (third normal form, 3NF): отношение находится в третьей нормальной форме, если оно находится во второй нормальной форме и не имеет транзитивных зависимостей. Отношение ПРОЖИВАНИЕ можно разделить на два отношения в третьей нормаль- ной <|юрме. На рис. 4.5, б мы видим два отношения, получившиеся в результате этой операции: СТУДЕНТ—ПРОЖИВАНИЕ (НомерСтудента, Общежитие) и ОБЩЕЖИТИЕ- ПЛАТА (Общежитие, Плата). Отношение СЕКЦИЯ па рис. 4.1 также имеет транзитивную зависимость. В этом отношении атрибут НомерСтудента определяет атрибут Секция, а атрибут Секция определяет атрибут Плата. Поэтому' отношение СЕКЦИЯ не находится в третьей нор- мальной форме. Разбиение данного отношения на отношения СТУДЕНТ—СЕКЦИЯ (НомерСтудента, Секция) и СЕКЦИЯ—ПЛАТА (Секция, Плата) устраняет указанные аномалии. Нормальная форма Бойса—Кодда (НФБК) К сожалению, даже отношения в третьей нормальной форме могут иметь анома- лии. Рассмотрим отношение НАУЧНЫЙ_РУКОВОДИТЕЛЬ (рис. 4.6, а). Пусть требо- вания к этому отношению таковы. 1. Студент может иметь одну или несколько специализаций. н₽а^1ПЬ1^1Н ководителями по одной и той же специализации могут быть несколько преподавателей. по очной,Преподапатель может осуществлять научное руководство только по одной специализации. лий'' акЖе предполагать, что у преподавателей не бывает одинаковых фа
Нормальные формы от первой до пятой 187 Поскольку студенты могут специализироваться в нескольких областях, атрибут НомерСтудента не определяет атрибут Специализация. Более того, так как сту- дент может иметь несколько научных руководителей, НомерСтудента не определя- ет и атрибут ИмяПреподавателя. Таким образом, сам по себе атрибут НомерСтуден- та не может играть роль ключа. ндуоный_руководитЕЛЬ (НомцсСту, ,=нта, Специализация. ИмяПреподавателя) Ключ (кандидат): (Но ерСтудента Специализация) Функциональные зависимости: ИмяПреподавателя -> Специализация Номер Студента Специализация Имя Преподавателя 100 Математика Коши 150 Психология Юнг 200 Математика Риман 250 Математика Коши 300 Психология Перле 300 Математика Риман СТУДЕНТ—РУКОВОДИТЕЛЬ (Н_мср£туд>нт-, ИмяПреподавателя) Номер Студента Имя Преподавателя 100 Коши 150 Юнг 200 Риман 250 Коши 300 Перле 300 Риман РУКОВОДИТЕЛЬ—ДИСЦИПЛИНА (ИмяПреподавателя. Дисциплина) Имя Преподавателя Дисциплина Коши Математика Юнг Психология Риман Математика Перле Психология Рис. 4.6. Нормальная форма Бойса—Кодда: а — отношение, находящееся в ЗНФ, но не в НФБК; б — два отношения, находящиеся в НФБК Комбинация (НомерСтудента, Специализация) определяет атрибут ИмяПрепода- вателя, а комбинация (НомерСтудента, ИмяПреподавателя) определяет атрибут Спе- циализация. Следовательно, любая из этих комбинаций может быть ключом. Два или более атрибута или группы атрибутов, которые могут быть ключом, называ- ются ключами-кандидатами (candidate keys). Тот из ключей-кандидатов, кото- рый выбирается в качестве ключа, называется первичным ключом (primary key). Кроме ключей-кандидатов, есть еще одна функциональная зависимость, ко- торую следует рассмотреть: атрибут ИмяПреподавателя определяет атрибут Спе- циализация (любой из преподавателей является научным руководителем только по одной специализации; следовательно, зная имя преподавателя, мы можем определить эту специализацию). Таким образом, ИмяПреподавателя является де- терминантом. По определению, отношение НАУЧНЫЙ.РУКОВОДИТЕЛЬ находится в первой нор- мальной форме. Оно также находится во второй нормальной форме, поскольку
188 Глава 4 Реляционная модель и нормали; ни* _ , не имеет исключены* атрибутов (каждый из атрибутов яи я край пен мере одного ключа). Наконец, это о 1 ношение находится в третьей нормаль, нон форме, гак как не имеет транзитивных .зависимоегей Гем не менее, несмот- ря на все это, отношение имеет аномалии модификации Пусть студент номер 300 отчисляется из университета Если мы удалим стрму с информацией об этом студенте, мы потеряем тог факт, что научным руководи, телом на кафедре психологии является некий Перле. Эю аномалия удаления. Далее, как мы можем записать в базу тот факт, что преподаватель Кейнс является научным руководителем па кафедре экономики? Никак, пока не появится хотя бы один студент, специализирующийся па экономике. Это аномалия вставки. Ситуации, подобные только что описанной, приводят нас к определению нор- малъной формы Бойса-Кодда (Boyce-Codd normal form, ВК/NF): отношение на- ходится в НФБК, если каждый детерминант является ключом-кандидатом Отно- шение НАУЧНЫЙ.РУКОВОДИТЕЛЬ не находится в НФБК, поскольку детерминант ИмяПреподавателя не является ключом-кандидатом. Как н в других примерах, отношение НАУЧНЫЙ_РУКОВОДИТЕЛЬ можно разбить на два отношения, не имеющие аномалий. Например, отношения СТУДЕНТ—РУКОВО- ДИТЕЛЬ (НомерСтудента, ИмяПреподавателя) и РУКОВОДИТЕЛЬ—СПЕЦИАЛИЗАЦИЯ (Имя- Преподавателя, Специализация) не имеют аномалий. Отношения в НФБК не имеют аномалий, относящихся к функциональным зависимостям, и некогда казалось, что вопрос с аномалиями модификации на этом исчерпан. Однако вскоре обнаружилось, что аномалии могут быть обуслов- лены и иными причинами, нежели функциональные зависимости. Четвертая нормальная форма (4НФ) Рассмотрим отношение СТУДЕНТ на рис. 4.7, которое отображает связи между'сту- дентами, специальностями и секциями. Предположим, что студенты могут иметь несколько специализаций и заниматься в нескольких различных секциях. В таком случае единственным ключом является комбинация (НомерСтудента, Специализа- ция, Секция). Например, студентка номер 100 специализируется по музыке и бух- галтерскому учету и, кроме того, посещает секции плавания и тенниса, а студент номер 150 специализируется только по математике и занимается бегом. СТУДЕНТ (НомерСтудента. Специализация, Секция) Многозначные зависимости: НомерСтудента —> -> Специализация НомерСтудента -> -> Секция Номер Студента Специализация Секция 100 Музыка Плавание 100 Бухгалтерский учет Плавание 100 Музыка Теннис 100 Бухгалтерский учет Теннис 150 Математика Оздоровительный бег Рис. 4.7. Отношение с многозначными зависимостями
Нормальные формы от первой до пятой 189 Какова связь между атрибутами НомерСтудента и Специализация' Это не функ шюнтльная зависимость, поскольку у студента может быть несколько специаль- ностей Одному и тому же значению а трибута НомерСтудента может соответствовать много значений атрибута Специализация. Помимо того, одному и тому же значению атрибута НомерСтудента может соответствовать мною шачеиий атрибута Секция Такая зависимость атрибутов называется мпогашачиой чаншимостъю (multi- line dependency) Многозначные зависимое! и приводят к аномалиям модифи кацнп. Для начала обратите внимание на избыточное! ь данных на рис 4 7 Сту- дентке номер 100 посвящено четыре записи, в каждой из которых указана одна из ее специализаций и одна из посещаемых ею секций. Если бы те же данные хранились в меньшем количестве строк (скажем, было бы две строки — одна для музыки и плавания, а другая для бухгалтерского учета и тенниса), это дезориенти- ровало бы пользователей Получалось бы, что студентка номер 100 плавает только тогда, когда специализируется на музыке, а в теннис играет только тогда, когда специализируется на бухгалтерском учете Но такая интерпретация нелогична. Специальности и секции совершенно независимы друг от друга. Поэтому, чтобы избежать таких неверных заключений, мы храним все сочетания специальностей и секции. Допустим, что студентка номер 100 решила записаться в секцию лыж, и по- этому мы добавляем в таблицу строку [100, Музыка, Лыжи], как показано на рис. 4.8, а. В данный момент из отношения можно сделать вывод, что эта сту- дентка занимается лыжами только как музыкант, но не как бухгалтер. Чтобы данные имели согласованный характер, мы должны добавить столько строк, сколько имеется специальностей, и в каждой из них указать секцию лыж. Таким образом, мы должны добавить строку [100, Бухгалтерский учет, Лыжи], как показа- но на рис. 4 8. б. Это аномалия обновления: требуется слишком много модифика- ций, чтобы внести в данные одно простое изменение. Вообще говоря, многозначная зависимость существует когда отношение имеет минимум три атрибута, причем два из них являются многозначными, а их значе- ния зависят только от третьего атрибута. Другими словами, в отношении R (А, В, С) существует многозначная зависимость, если А многозначным образом определяет В и С, а сами В и С не зависят друг ог друга. Как мы видели из предыдущего при- мера, НомерСтудента многозначно определяет атрибуты Специализация и Секция, но сами Специализация и Секция не зависят друг от друга. Вернемся вновь к рис. 4.7. Обратите внимание на то, как обозначаются много- значные зависимости: НомерСтудента ->-> Специализация и НомерСтудента Сек- ция. Это читается следующим образом: «Атрибут НомерСтудента многозначно опре- деляет атрибут Специализация» и «Атрибут НомерСтудента многозначно определяет атрибут Секция». Данное отношение находится в НФБК (2НФ — поскольку его ключом является совокупность всех атрибутов, ЗНФ - так как отсутствуют транзитивные зависимости, и НФБК поскольку нет неключевых детерминан- тов). Однако, как мы убедились, оно имеет аномалии: если студент берет допол- нительную специализацию, мы должны добавить в отношение столько строк в скольких секциях данный студент занимается, и в каждой из этих строк указать
190 Глава 4. Реляционная модель и нормализация новую специализацию. То же самое справедливо и для случая, когда студент записывается в новую секцию. Если студент отказывается or одной из специали- заций, мы должны удалить все строки, где указана данная специализация Если студент занимается в четырех секциях, то название специализации будет содер- жаться в четырех строках, и все эти строки необходимо будет удалить студент (номугСтудачга, Слеша:еааша, Секция) Номер Студента Специализация Секция 100 Музыка Лыжи 100 Музыка Плавание 100 Бухгалтерский учет Плавание 100 Музыка Теннис 100 Бухгалтерский учет Теннис 150 Математика Оздоровительный бег а Номер Студента Специализация Секция 100 Музыка Лыжи 100 Бухгалтерский учет Лыжи 100 Музыка Плавание 100 Бухгалтерский учет Плавание 100 Музыка Теннис 100 Бухгалтерский учет Теннис 150 Математика Оздоровительный бег б Рис. 4.8. Отношение СТУДЕНТ с аномалиями вставки а — вставка одной строки; б — вставка нескольких строк Чтобы устранить эти аномалии, мы должны избавиться от многозначной за- висимости. Мы сделаем это, создав два отношения, в каждом из которых будет только один многозначный атрибут. Результирующие отношения не будут иметь аномалии. Это отношения СТУДЕНТ—СПЕЦИАЛИЗАЦИЯ (НомерСтудента, Специали- зация) и СТУДЕНТ—СЕКЦИЯ (НомерСтудента, Секция), изображенные на рис. 4.9. СТУДЕНТ—СПЕЦИАЛИЗАЦИЯ (Н. ме, С |у„ентз. Специализация) Номер Студента Специализация 100 Музыка 100 Бухгалтерский учет 150 Математика СТУДЕНТ—СЕКЦИЯ (НомерСтудента, Секция) Номер Студента Секция 100 Лыжи 100 Плавание 100 Теннис 150 Оздоровительный бег Рис. 4.9. Устранение многозначной зависимости Исходя из сделанных нами наблюдений, мы определим четвертую нормаль- ную форму (fourth normal form, 4NF) следующим образом: отношение находится в четвертой нормальной форме, если оно находится в НФБК и не имеет иного-
Доменно-ключевая нормальная форма (ДКНФ) 191 злачных зависимостей. После обсуждения доменно-ключевой нормальной фор- мы (далее в этой главе) мы вернемся к описанию многозначных зависимостей ЛО уже в другом, более интуитивном ключе. Пятая нормальная форма (5НФ) Пятая нормальная форма (fifth normal form, 5NF) связана с зависимостями, име- ющими довольно-таки неопределенный характер. Речь идет об отношениях, кото- рые можно разделить на несколько более мелких отношений, как мы это делали выше, но затем невозможно восстановить. Условия, при которых возникает эта ситуация, не имеют ясной, интуитивной интерпретации. Нам неизвестно, каковы следствия таких зависимостей; мы не знаем даже, есть ли у них какие бы то ни было практические следствия. За более подробной информацией о пятой нормаль- ной форме обращайтесь к работе Дэйта, которая цитировалась ранее в этой главе. Доменно-ключевая нормальная форма (ДКНФ) Все описанные выше нормальные формы были выделены в процессе исследова- ния аномалий у отношений, которые находились в нормальной форме более низ- кого порядка: обнаружение аномалий модификации у отношений во второй нор- мальной форме привело к определению третьей нормальной формы, и т. д. Хотя каждая нормальная форма решала часть проблем, найденных у предыдущей нор- мальной формы, никто не мог сказать, какие проблемы еще не выявлены. Каж- дый такой шаг являлся прогрессом на пути к представлению об оптимальной структуре базы данных, однако никто не мог гарантировать, что не будет обнару- жено еще каких-либо аномалий. В этом разделе мы рассмотрим нормальную форму, которая будет свободна от аномалий любого типа. Когда мы приводим отноше- ния к этой форме, мы знаем, что в этом случае даже скрытые аномалии, связан- ные с пятой нормальной формой, возникнуть не могут. В 1981 году Фагип опубликовал важную статью, в которой ввел понятие доменно-ключевой нормальной формы, пли ДКНФ (domain/key normal form, DKNF)'. Он показал, что отношение в ДКНФ не имеет аномалий модификации, и, оолее того, любое отношение, не имеющее аномалий модификации, должно находиться в ДКНФ. Это открытие положило конец введению нормальных форм, и теперь в нормальных формах более высокого порядка нет необходимости — по крайней мере, для устранения аномалий модификации. Столь же важно и то, что определение доменно-ключевой нормальной формы затрагивает только понятия домена и ключа понятия фундаментальные и близ- кие сердцу специалистов в области баз данных. Они непосредственно поддержи- ваюгся существующими СУБД (или, по крайней мере, могут поддерживаться). R. Fagin «Л Normal Form for Relational Databases That Is Based On Domains and Kevs», ACM Transactions on Database Systems, September 1981, pp. 387-415.
1Q2 глава 4. Реляционная модель и нормализация R каком-то смысле работа Фагина формализовала и обосновала я т ино п,е ХХты верил,, „итуитииио, ..о были не и состоянии 1044,0 «,„ Определение Понятие ДКНФ весьма просто: отношение находится в доменно-ключевой нор- мальной форме, если каждое ограничение, накладываемое на это отношение, я ь ляется логическим следствием определения доменов и ключей. Рассмотрим важ- ные термины, фигурирующие в этом определении: ограничение, ключ и домен. Термин ограничение (constraint) имеет в данном определении намеренно широкое толкование. Фагин определяет ограничение как любое правило регу- лирующее возможные статические значения атрибутов и достаточно точное для того, чтобы можно было установить его истинность или ложность. Примера- ми таких ограничений являются правила редактирования, ограничения связей и внутренние ограничения отношении, функциональные зависимости и много- значные зависимости. Фагин явным образом исключает отсюда ограничения, относящиеся к изменениям значений данных, и ограничения, зависящие от вре- мени. Например, правило «Зарплата продавца за текущий период не может быть меньше, чем за предыдущий период» не подпадает под определение ограниче- ния, которое дал Фагин. За исключением ограничений, зависящих от времени, определение Фагина является широким и охватывает множество случаев. Ключ (key) — это уникальный идентификатор строки, как мы его уже опреде- лили. Третий важный термин в определении ДКНФ — домен (domain). В главе 2 домен был определен как именованное множество допустимых значений атрибу- та. Доказательство Фагана говорит, что ограничения доменов соблюдены, если значения атрибутов удовлетворяют определениям соответствующих доменов. Говоря неформально, отношение находится в ДКНФ, если для выполнения всех ограничении достаточно выполнить ограничения, связанные с доменами и ключами. Более того, поскольку отношения в ДКНФ не могут иметь аномалий модификации, предотвратить возникновение этих аномалий может сама СУБД, контролируя соблюдение ограничений доменов и ключей. К сожалению, пока не известен ни один алгоритм преобразования отношения к доменно ключевой нормальной форме; неизвестно даже, какие отношения мо- оыть приведены к ДКНФ. Нахождение и создание отношений в ДКНФ яв- ляется оолее искусством, чем наукой. служит “Се ЭТ ПРИ пРактическом проектировании баз данных ДКНФ таким обпачп«1еИ СТепени полезным ориентиром. Если определять отношения следствиями ллм₽° Ы "алагаемые «а них ограничения были логическими лий мод1|фикацииНВо м КЛЮЧеН’ ™ ТЙКИе 0ТН0Щения будут свободны от анома- можно соответствую Н01их слУчаях этого удается достичь. Если же это невоз- НИХ программ, 0бра6™м™™™Х™^Ы ”ПР°'НЫ ° Ж”4' форму. У ЩИе Гри п₽имера иллюстрируют доменно-ключевую нормальную
Доменно-ключевая нормальная форма (ДКНФ) 193 Первый пример доменно-ключевой нормальной формы Рассмотрим отношение СТУДЕНТ на рис 4.10, имеющее атрибуты НомерСтудента, Курс, Общежитие и Плата. Здесь Плата - это сумма, которую студент платит за про- живание в общежитии. СТУДЕНТ (НомерСтудента, Курс, Общежитие, Плата) Ключ: НомерСтудента Ограничения: Общежитие -> Плата НомерСтудента не должен начинаться с цифры 1 Рис. 4.10. Первый пример ДКНФ НомерСтудента функционально определяет остальные три атрибута и, следо- вательно, является ключом. Допустим, требования пользователей таковы, что Общежитие -> Плата, а НомерСтудента не должен начинаться с 1. Если нам удаст- ся представить эти требования как логические следствия определения доменов и ключей, то мы сможем быть уверены, согласно теореме Фагина, что аномалий модификации вс возникнет. В данном примере это будет легко сделать. Чтобы реализовать ограничение, указывающее, что номера студентов не долж- ны начинаться с 1, мы просто включим это требование в определение домена ат- рибута НомерСтудента (рис 4.11). Соблюдение ограничения домена гарантирует, что данное требование будет выполнено. Далее нам требуется сделать функциональную зависимость Общежитие -> Плата логическим следствием ключей. Если бы атрибут Общежитие был ключевым, за- висимость Общежитие —> Плата была бы логическим следствием ключа. Поэтому встает вопрос о том, как сделать Общежитие ключом. Атрибут Общежитие не может быть ключом в отношении СТУДЕНТ, так как в одном и том же общежи- тии живет более одного студента, зато он может быть ключом своего собственно- го отношения. Таким образом, мы можем ввести отношение ОБЩЕЖИТИЕ—ПЛАТА с атрибутами Общежитие и Плата. Атрибут Общежитие является ключом этого от- ношения. Введя это новое отношение, мы можем удалить атрибут Плата из отно- шения СТУДЕНТ. Окончательные определения доменов и отношении для этого примера представлены на рис. 4.11. Этот же результат мы получили, преобразовав отношение из 2НФ в ЗНФ для удаления транзитивных зависимостей. В данном случае, однако, процесс был проще, а результат является более надежным. Процесс был проще потому, что нам не требовалось знать, что мы устраняем транзитивную зависимость. Все, что нам было нужно, — это найти действенные способы превращения всех огра- ничении в логические следствия определений доменов и ключей. Результат яв- ляется более надежным по следующей причине. При преобразовании отношения в третью нормальную форму мы знали только то, что количество аномалии в нем
194 Глава 4. Реляционна^2^2Д££!^!122£В^Д^^а^й ----------------- ..„птппой HOPM.UH.IIOH формой Приведя <»н ни. стало меньше по сравнению сся омющепия не б ,дут иметь никами» к ДКНФ, мы точно знаем, что получивши» см и. - аномалий модификации. Определения доменов. Атрибут Имя домена Значения НомерСтудента ИдСтудента 4 десятичные цифры, первая цифра не 1 Курс ГодОбучения { СГ, 'С2', ’СЗ’, ’С4', ‘АС’} Общежитие НазваниеЗдания Char(4) Плата ПлатаЗаОбучение Любая денежная сумма Определения отношений и ключей СТУДЕНТ (НомерСтудента. Курс Общежитие) ОБЩЕЖИТИЕ—ПЛАТА (Общежитие, Плата) Рис. 4.11. Определения доменов и ключей для первого примера ДКНФ Второй пример доменно-ключевой нормальной формы Теперь рассмотрим более сложный пример (рис. 4.12). Отношение ПРЕПОДАВАТЕЛЬ содержит данные о преподавателях, предметах, которые они ведут, и студентах, которыми они руководят. Атрибуты НомерСотрудника и ИмяСотрудника однозначно определяют преподавателя. НомерСтудента однозначно определяет студента, одна- ко ИмяСтудента не обязательно определяет НомерСтудента. Преподаватель может вести несколько предметов и быть руководителем у нескольких студентов, но ка- ждым студентом руководит только один преподаватель. НомерСотрудника начина- ется с единицы, а НомерСтудента не может с нее начинаться. ПРЕПОДАВАТЕЛЬ (НомерСотрудника, ИмяСотрудника, Дисциплина, НомерСтудента, ИмяСтудента) Ограничения: НомерСотрудника —» ИмяСотрудника ИмяСотрудника —> НомерСотрудника НомерСотрудника -> -> Дисциплина | НомерСтудента ИмяСотрудника -> -» Дисциплина | НомерСтудента НомерСтудента —> НомерСотрудника НомерСтудента —> ИмяСотрудника НомерСтудента —> ИмяСтудента НомерСотрудника должен начинаться с 1; НомерСтудента не должен начинаться с 1 Рис. 4.12. Второй пример ДКНФ ио Б°лее точно эти высказывания можно сформулировать в терминах функцио- нальных и многозначных зависимостей, как показано на рис. 4.12. НомерСотруД-
Доменно-ключевая нормальна» форма (ДЦИФ) 161 ника н ИмяСотрудника функционально определяют друг друга (в и. шив эквивалентны). НомерСотрудника и ИмяСотрудника многозначно определяют Дас* циплина и НомерСтудента. НомерСтудента функционально определяет НиьарСаврм* ника и ИмяСотрудника. НомерСтудента определяет ИмяСтудента В более сложных примерах, таких, как этот, ноле то рассмотреть ДКНФ • бо- лее интуитивном свете. Вспомните, что суть нормализации заключается в том, чтобы каждое отношение имело одну гему. Если взглянуть на отношение ПРЕПО- ДАВАТЕЛЬ с этой точки зрения, мы увидим в нем три темы. Первая тема т это соответствие между атрибутами НомерСотрудника и ИмяСотрудника, вторая тема - предметы, которые ведет преподаватель, а третья - идентификационный номер, имя и руководитель данного студента. На рис. 4.13 представлены три отношения, отражающие эти темы. Отношение ППС (профессорско-преподавательский состав) выражает эквивалентность атри- бутов НомерСотрудника и ИмяСотрудника. НомерСотрудника является в нем ключом, а ИмяСотрудника — альтернативным ключом, что означает, что оба атрибута уни- кальны для этого отношения. Поскольку оба они являются ключевыми, функ- циональные зависимости НомерСотрудника —> ИмяСотрудника и ИмяСотрудника -» НомерСотрудника представляют собой логические следствия ключей. Определения доменов: Атрибут Имя домена Значения НомерСотрудника Ид Сотрудников 4 десятичные цифры, первая цифра не 1 ИмяСотрудника ИменаЛюдей Char(50) Дисциплина НазванияДисциплин Char(10); значения {список допустимых названий дисциплин} НомерСтудента ИдСтудентов 4 десятичные цифры, первая цифра не 1 ИмяСтудента ИменаЛюдей Char(50) Определения отношений и ключей: ППС (НомерСотрудника. ИмяСотрудника) Ключ (кандидат): ИмяСотрудника ПОДГОТОВКА (ИмяСотрудника, Дисциплина) СТУДЕНТ (ELwvr Студента. ИмяСтудента, ИмяСотрудника) Рис. 4.13. Определение доменов и ключей для второго примера ДКНФ Отношение ПОДГОТОВКА отражает соответствие между преподавателями и пред метами; в нем указаны предметы, которые может вести каждый из преподавателей Ключом является комбинация (ИмяСотрудника, Предмет). Оба атрибута являются необходимыми для ключа, потому что один преподаватель может вести несколь- ко предметов, а один и тот же предмет может вестись несколькими преподавать ями. Наконец, в отношении СТУДЕНТ для каждого номера студента указано имя
196 Глава 4, Реляционная модель и норм..ли ww - „ .ни Ччметые, что каждое из ото «-Иий имеет этого студента 11111ражаюг все о.раничения. фигурируй .... ‘ л'леш,е подГ0Т06КА ,,ттеми ш«и7'ч«- ,га,° «шчпып зав..спм«пИ Расемагрппая ..стертую кормах «ую ф^, "ы ЛИРУЖ..,™, ™ Для того w>« yen»..™ ................. зависимое™, «об- ход,“о извести м..отоз1Ю.шые атрибут... в ра.ип« отношения Испольная, нами подход заключается а том. чтобы разбит,, отношение с несколькими гема. . на несколько отношений, каждое ш> которых имеет едиистмшую «му Тем самым мы устранили многозначную зависимость. Итак, оба подхода при (ели нас к одинаковому решению. Третий пример доменно-ключевой нормальной формы В следующем примере рассматривается ситуация, которая не охватывается ни одной из нормальных форм, но часто возникает на практике. Это ситуация, когда отношение имеет ограничение на значения данных в строке, которое невозможно описать ни функциональной, ни многозначной зависимостью. Рассмотрим ограничения, имеющиеся в отношении СТУДЕНТ—РУКОВОДИТЕЛЬ на рис. 4.14. Это отношение содержит информацию о студенте и его руководителе. Атрибут НомерСтудента определяет атрибуты ИмяСтудента, НомерСотрудника, Имя- Сотрудника и СотрудникАспирантуры, поэтому он является ключом. Атрибуты Но- мерСотрудника и ИмяСотрудника однозначно определяют члена профессорско-пре- подавательского состава и взаимно эквивалентны, как и в предыдущем примере. И НомерСотрудника, и ИмяСотрудника определяют атрибут СотрудникАспирантуры. Наконец, новым типом ограничения является то, что руководителями аспиран- тов могут быть только сотрудники аспирантуры. СТУДЕНТ-РУКОВОДИТЕЛЬ (НомерСтудента, ИмяСтудента, НомерСотрудника, СотрудникАспирантуры) * Ключ: НомерСтудента Ограничения: НомерСотрудника -> ИмяСотрудника ИмяСотрудника —» НомерСотрудника НомерСотрудника и ИмяСотрудника -» СотрудникАспипантуоы НомерСотКика начинаете бЫТЬ руководителями аспирантов НомерСтудента не должен начинаться с 1 НомерСтудента для аспиранта начинается с 9 СотрудникАспирантуры =П для сотрудников аспирантуры, ____________L0 для остальных сотрудников СотрудникАспирантуры =Г U Рис. 4.14. Третий пример ДКНФ
Доменно-ключевая нормальная форма (ДКНФ) 197 Ограничения доменов заключаются в том, что НомерСтудента не должен начи- наться с 1, для аспирантов НомерСтудента должен начинаться с 9 НомерСотрудника должен начинаться с 1, а атрибут СотрудникАспирантуры должен быть равен 1 для сотрудников аспирантуры и 0 для всех остальных сотрудников. При таком опре- делении доменов т ребование, чтобы аспирантами руководили только сотрудни- ки аспирантуры, может быть представлено как ограничение на значения строки. В частности, если атрибут НомерСтудента начинается с 9, то атрибут СотрудникАспи- рантуры должен быть равен 1. Чтобы привести это отношение к ДКНФ, мы поступим так же, как в предыду- щем примере. Каковы основные темы отношения СТУДЕНТ—РУКОВОДИТЕЛЬ? Одна из тем — это профессорско-преподавательский состав; к ней относятся атрибуты НомерСотрудника, ИмяСотрудника и СотрудникАспирантуры. Вынесем эти атрибуты в отношение ППС. Поскольку атрибуты НомерСотрудника и ИмяСотрудника опреде- ляют атрибут СотрудникАспирантуры, любой из этих атрибутов может быть клю- чом, и это отношение находится в ДКНФ (рис. 4.15). Определения доменов: Атрибут Имя домена Значения НомерСотрудника ИдСотрудников 4 десятичные цифры, первая цифра не 1 ИмяСотрудника ИменаЛюдей Char(5O) СотрудникАспирантуры СтатусСотрудника- Аспирантуры Значения {0, 1} НомерАспиранта Идентификаторы- Аспирантов 4 десятичные цифры, первая цифра 9 НомерСтудента Идентификаторы- Студентов 4 десятичные цифры, первая цифра не 1 и не 9 ИмяСтудента ИменаЛюдей Char(50) ИмяСотрудника- Аспирантуры ИменаЛюдей Значения {ППС.ИмяСотрудника, где СотрудникАспирантуры = 1} Определения отношений и ключей- ППС рудник J, ИмяСотрудника, СотрудникАспирантуры) Ключ-кандидат: ИмяСотрудника РУКОВОДИТЕЛЬ—АСПИРАНТ (djwec Аспирант т. ИмяСтудента, ИмяСотрудникаАспирантуры) РУКОВОДИТЕЛЬ—СТУДЕНТ н.;мс,.Студунт.х ИмяСтудента, ИмяСотрудника) Рис. 4.15. Определение доменов и ключей для третьего примера Теперь рассмотрим данные, относящиеся к студентам и их руководителям. На первый взгляд может показаться, что здесь имеется только одна тема, а именно руководство, однако из требования о том, чтобы аспирантами руководили толь- ко сотрудники аспирантуры, следует иное. На самом деле здесь есть две темы- ру- ководство аспирантами и руководство студентами. Соответственно, на рис 4 15 мы имеем два отношения: РУКОВОДИТЕЛЬ-АСПИРАНТ, содержащее информацию об аспирантах, и РУКОВОДИТЕЛЬ-СТУДЕНТ, содержащее информацию о
J98 Глава4 Реляционная модель и нормализация г- гт„ап₽прния доменов. НомерАспиранта начинается с 9; Посмотрим, каковы_6W™ эТо ИмяСотрудника из строки отношения ППС с атри ИмяСотрудникаАспирантур j. накоНец, НомерСтудента ие должен нами- наться с 1 4 15 поэтому данные отношения находятся деления ключей и доменов на рис. в ДКНФ и не имеют аномалий модификации. В качестве подведения итога обсуждения нормальных форм в табл 4.4 пере- числены все нормальные формы и даны их определяющие характеристики. Таблица 4.4. Нормальные формы Форма Определяющая характеристика 1НФ 2НФ ЗНФ НФБК 4НФ 5НФ ДКНФ Любое отношение Каждый из неключевых атрибутов зависит от всего ключа целиком Нет транзитивных зависимостей Каждый детерминант является ключом-кандидатом Отсутствуют многозначные зависимости Не описывается здесь Все ограничения на отношение являются логическими следствиями определений доменов и ключей Синтез отношений В предыдущем разделе мы подходили к проектированию реляционных схем с ана- литических позиций. Вопрос, задававшийся нами, был таков: пусть у нас имеется некоторое отношение. В хорошей ли форме оно находится? Имеет ли оно анома- лии модификации? В данном разделе мы подойдем к проектированию реляцион- уктур, исходя из синтетической перспективы. Вопрос в этом случае зву- чит так. если у нас имеется набор атрибутов с определенными функциональными зависимостями, какие отношения следует из них формировать? видов ПеРВЬ1Х’ °™етим- что два атрибута (скажем, А и В) могут иметь связь трех 1. 2. 3. 2т атпХ °ПреДеЛЯТЬ ДРУГ д1’Уга: А -> В и В -> А. В этом случае А и В име- ют атрибутивную связь «один к одному». А и В имеют^ятп^1 определять ДРУГОЙ: А -> В, но не В -> А. В этом случае В имеют атрибутивную связь «многие к одному». мучае°А?В т1е1отНКЦИлНаЛЬН0 ИС Связаны: А не -> В и В не -> А. В этом случае А и В имеют атрибутивную связь «многие ко многим». Атрибутивная связь «один к одному» Если А определяет В, а В определяет а ному» (one-to-one relationshin'i r г ' еНИЯ атРноУтов имеют связь «один к од- —fоп₽ммя"в’то А и в у . между тем справедливо и другое утвер-
Синтез отношений 199 ждение: если В определяет А, го между В и А должна быть связь «многие к одно- му» Чтобы оба утверждения были справедливы одновременно, связь между А и В должна в действительности иметь вид «один к одному» (что является частным случаем связи «многие к одному»), как и связь между В и А. Поэтому в данном случае наличествует связь «один к одному». Этот случай иллюстрируется атрибутами НомерСотрудника и ИмяСотрудника в предыдущем разделе, посвященном доменно-ключевой нормальной форме. Каждый из этих атрибутов однозначно определяет сотрудника факультета. Сле- довательно, каждому значению атрибута НомерСотрудника соответствует ровно одно значение атрибута ИмяСотрудника, и наоборот. Относительно примера с атрибутами НомерСотрудника и ИмяСотрудника можно высказать три эквивалентных утверждения. + Если два атрибута функционально определяют друг друга, то между их значениями имеется связь «один к одному». 4- Если два атрибута однозначно определяют одну и ту же вещь (сущность или объект), то между их значениями имеется связь «один к одному». 4 Если два атрибута имеют связь «один к одному», то они функционально определяют друг друга. При создании базы данных с атрибутами, имеющими связь «один к одному», эти два атрибута должны появляться вместе по крайней мере в одном отноше- нии. Другие атрибуты, которые функционально определяются данными атрибу- тами (атрибут, который функционально определяется одним из них, функцио- нально определяется и другим), могут также находиться в этом отношении. Рассмотрим отношение ППС (НомерСотрудника, ИмяСотрудника, СотрудникАспи- рантуры) из третьего примера в предыдущем разделе. НомерСотрудника и ИмяСо- трудника функционально определяют друг друга. Атрибут СотрудникАспирантуры также может появиться в отношении, поскольку он определяется атрибутами НомерСотрудника и ИмяСотрудника. Атрибуты, которые не определяются функцио- нально данными атрибутами, не могут появляться с ними в одном отношении. Рассмотрим отношения ППС и ПОДГОТОВКА из примера № 2, в котором и Номер- Сотрудника, и ИмяСотрудника присутствуют в отношении ППС, по Предмет (из отно- шения ПОДГОТОВКА) там появиться не может. Атрибут Предмет может иметь различные значения для сотрудника факультета, полому Предмет не зависит от атрибутов НомерСотрудника или ИмяСотрудника. Если бы мы добавили атрибут Предмет в отношение ППС, ключом этого отношения обязательно должно было бы быть сочетание (НомерСотрудника, Предмет) либо (ИмяСотрудника, Предмет). В этом случае, однако, отношение ППС не было бы в ДКНФ, потому что зависимости ме- жду атрибутами НомерСотрудника и ИмяСотрудника не были бы логическими след- ствиями ни одного из возможных ключей. Эти утверждения собраны в первом столбце табл. 4.5, а правила определения писей приведены во врезке. Если А и В имеют связь 1:1, они могут находиться п одном отношении R. А определяет В, а В определяет А. Ключом отношения мо- ст быть либо А, либо В. Новый атрибут С может быть добавлен в отношение R, ели один из атрибутов А и В функционально определяет С
200 Глава 4. Реляционная модель и нормализации Таблица 4.5. Три типа связей атрибутов Тип связи между атрибутами Один к одному Многие к одному Определение отношения R(A,B) < д у D С —> D Зависимости я о В-> A D-»C Ключ Либо А. либо В С Правило добавления Либо А, либо В -> С С -> Е атрибутов Многие ко многим T(E,F) E->F F-> Е (E.F) (E.F) -> G • Буквы, использованные в определениях этих отношений, соответствуют тем, которые использу- ются во врезке. ПРАВИЛА ПОСТРОЕНИЯ ОТНОШЕНИЙ “ Связь «один к одному» ♦ Атрибуты, имеющие связь «один к одному», должны фигурировать вместе по крайней мере в одном отношении. Пусть отношение носит имя R, а его атрибуты — А и В ♦ Либо А, либо В должен быть ключом отношения R. ♦ Если некоторый атрибут функционально определяется атрибутом А или В, он может быть добавлен в отношение R. ♦ Атрибут, не определяемый функционально атрибутами А или В, не может быть до- бавлен в отношение R ♦ Атрибуты А и В должны находиться, вместе в отношении R и более ни в каком другом отношении. ♦ Для представления пары (А, В) в отношениях, отличных от R, должен последователь- но использоваться один из атрибутов, А или В. Связь «многие к одному» ♦ Атрибуты, имеющие связь «многие к одному», могут находиться вместе в одном от- ношении. Пускай в отношении S атрибут С определяет атрибут D. ♦ Атрибут С должен быть ключом отношения S. ♦ Если некоторый атрибут определяется атрибутом С, он может быть добавлен в отно- шение S. ♦ Атрибут, не определяемый функционально атрибутом С, не может быть добавлен в отношение S Связь «многие ко многим» Атрибуты, имеющие связь «многие ко многим», могут сосуществовать в одном отно- шении. Пускай в отношении Т имеются два таких атрибута, Е и F. * Ключом отношения Т должна быть комбинация (Е, F). * S ™РТЫЙ 8ТРИбУ^ определяется сочетанием атрибутов (Е, F), он может быть добавлен в отношение Т. ' Атрибут, не определяемый функционально сочетанием атрибутов (Е, F), не может быть добавлен в отношение Т. 1 ' !итЛИЧто6ЛмяеНИе Н0В0Г° 0ТРИбУТа G раСширяет ключ отношения до (Е, F, G), это зна- ношени ю Тпибпс^пГ ИЗТНИЛаСЬ' ЛИб° ЗТРИ6УТ G логически не принадлежит от- нявшейся тит ДУеТ ВЫ РаТЬ другое имя для отношения в соответствии с поме- пиьшсИСЯ ТСМОИ.
Синтез отношений 201 Атрибуты, имеющие связь «один к одному», должны присутствовать вместе по меньшей мере в одном отношении, чтобы они могли быть эквивалентными (например, НомерСотрудника, равный 198, соответствует преподавателю Харту) В общем случае, однако, нежелательно, чтобы эти атрибуты появлялись вместе более чем в одном отношении, поскольку это приведет к ненужному дублирова- нию данных. Часто один из таких атрибутов или оба они появляются в других отношениях. В примере № 2 атрибут ИмяСотрудника появляется и в отношении ПОДГОТОВКА, и в отношении СТУДЕНТ. Можно было бы поместить ИмяСотрудника в отношение ПОДГОТОВКА, а НомерСотрудника — в отношение СТУДЕНТ, но это, во- обще говоря, порочная практика: когда атрибуты спарены подобным образом, из них следует выбрать один, который будет представлять эту пару во всех других отношениях. Во втором примере для этой цели выбран атрибут ИмяСотрудника. Атрибутивная связь «многие к одному» Если атрибут А определяет В, но В не определяет А, то между ними имеется связь «многие к одному» (many-to-one relationship). В отношении РУКОВОДИТЕЛЬ иэ при- мера № 2 НомерСтудента определяет НомерСотрудника. Отдельно взятый преподава- тель может быть руководителем у многих студентов, однако каждым студентом ру- ководит только один преподаватель. Поэтому здесь имеется связь «многие к одному». Чтобы отношение находилось в ДКНФ, все ограничения должны быть след- ствиями ключей, и поэтому каждый детерминант должен быть ключом. Если ат- рибуты А, В и С находятся в одном отношении и А определяет В, то атрибут А должен быть ключом (имея в виду, что он определяет также и С). Если же атри- бут С определяется сочетанием (А, В), тогда сочетание (А, В) должно быть клю- чом. В последнем случае никакой другой функциональной зависимости (напри- мер, А > В) не допускается. Применить эти высказывания к проектированию баз данных можно следующим образом: если в создаваемом отношении А определяет В, то добавлять в это отно- шение можно только те атрибуты, которые определяются атрибутом А. Допус- тим, например, что вы поместили в отношение под названием СТУДЕНТ атрибуты НомерСтудента и Общежитие. В это отношение вы можете добавлять любые другие атрибуты, которые определяются атрибутом НомерСтудента, например, ИмяСтуден- та. Но если атрибут Плата определяется атрибутом Общежитие, его нельзя доба- вить в данное отношение. Атрибут Плата может быть добавлен только в том слу- чае, если НомерСтудента > Плата. Эти правила сведены в среднем столбце табл 4.5. Если С и D имеют связь N:l, они могут находиться вместе в отношении S. С будет определять D, но D не будет определять С. Ключом отношения S будет атрибут С. Другой атрибут, Е, может быть добавлен в отношение S, только если С определяет Е. Атрибутивная связь «многие ко многим» Если А не определяет В, а В не определяет А, то между значениями этих атрибу- тов имеется связь «многие ко многим» (many-to-many relationship). В примере -1 атрибуты ИмяСотрудника и Предмет имеют связь «многие ко многим» Один
202 4. Реляционная модель и нормализации .^пп шм-лмего», а один И тот же предмет ведет преподаватель может веегп М! « МИ(Я им> а|рибута (<| ся многими преподавателями с • ОГ1ИИ|К.11ИЯ ПОДГОТОВКА из приме пыть ключами отношения. l iaupHMt р, к. п-1 № 2 являегся комбинация (ИмяСотрудника. Предмет) построен»'’ orno’iieiuiil. У '1ЮЮЛ“° «! *» то,, можпо^ап™ »Л»'«У™- ...I*1""»...“""° И““О" т Т ”юча Атрибут КолнчествоЧасоа фупкпжишлыю =.»»« "Т от каждого из атрибу то» в сочетании (Ин,Со,рудника. Предмет) и поэтому может быт,, лобаилен . отио- шише. Атрибут Должность в данное отооше.'Ие добапить нельзя. потому то зависит только от атрибута ИмяСотрудника, по не от атрибута Предмет Если тре- Суется хранить атрибут Должность в базе данных, его следует добавить в отноше- ние, содержащее информацию о профессорско-преподавательском составе, а ие О подготовке. Эти правила сведены в правый столбец табл. 4.5. Если атрибуты Е и г имеют связь M:N. то Е не определяет F, a F не определяет Е. Оба эти атрибута можно по- местить в отношение Т, и в этом случае ключом отношения Т будет комбинация (Е, F). Новый атрибут G может быть добавлен в отношение Т, если он определяет- ся обоими атрибутами из сочетания (Е, F). Атрибут G нельзя добавить в отноше- ние Т, если он определяется только одним из атрибутов в комбинации (Е, F). Рассмотрим аналогичный пример. Предположим, мы хотим добавить в отноше- ние ПОДГОТОВКА атрибут НомерАудитории. Определяется ли НомерАудитории клю- чом отношения ПОДГОТОВКА — комбинацией (ИмяСотрудника, Предмет)? Скорее всего, нет, поскольку преподаватель может вести один и тот же предмет в различ- ных аудиториях. Сочетание (ИмяСотрудника, Предмет) и атрибут НомерАудитории имеют связь M:N. Раз это так, можно применить правила, приведенные в табл. 4.5, но здесь рать Е будет играть сочетание (ИмяСотрудника, Предмет), а роль F — атрибут НомерАуди- тории Теперь мы можем построить новое отношение Т с атрибутами ИмяСотруд- ника, Предмет и НомерАудитории. Ключом этого отношения будет комбинация (ИмяСотрудника, Предмет, НомерАудитории). В этой ситуации получается, что мы создали новое отношение с новой темой. Рассмотрим отношение Т, содержащее сведения об именах преподавателей, предметах и номерах аудиторий. Темой это- го отношения больше не является ПОДГОТОВКА; скорее, эту тему можно было бы сформулировать так: КТО-ЧТО-И-ГДЕ-ПРЕПОДАЕТ. Изменение темы может быть как уместным, так и неуместным. Если Номер- удитории является значимым атрибутом, тема действительно должна быть из- менена. В этом случае отношение ПОДГОТОВКА не подходит, и более уместной является тема КТО-ЧТО-И-ГДЕ-ПРЕПОДАЕТ ПОПГПТПККД1 СТ°Р°ны’ в зависимости от требований пользователей, отношение к нТ" 1ЫТ" "Рпгод™“ » ™ ’"« в каком „по есть. В типом случае. помесХь ?п»»г ю Же Д°Л“е" в базе данных, его следует естить в друюе отношение - например, СЕКЦИЯ—НОМЕР ПРЕДМЕТ—СЕКЦИЯ или что-нибудь наподооие этого.
Синтез отношений 203 Многозначные зависимости: часть вторая Изложенные выше соображения, касающиеся атрибутивной связи «многие ко многим» могут сделать концепцию многозначных зависимостей более простой для понимания. Проблема с отношением СТУДЕНТ (НомерСтудента, Специализация. Секция) на рис. 4.7 состоит в том, что в нем имеется две различных связи вида «многие ко многим»: одна между атрибутами НомерСтудента и Специализация, а дру- гая - между атрибутами НомерСтудента и Секция. Ясно, что специализации сту- дента не имеют никакого отношения к секциям, в которых он занимается. Однако если обе связи присутствуют в одном отношении, возникает впечатление, что между этими атрибутами существует какая-то взаимосвязь. Атрибуты Специализация и Секция независимы, и никакой проблемы не воз- никло бы, если бы студент мог специализироваться только в одной области и за- ниматься только в одной секции. Тогда НомерСтудента функционально опреде- лял бы атрибуты Специализация и Секция, и отношение находилось бы в ДКНФ. В этом случае связь каждого из этих атрибутов с атрибутом НомерСтудента имела бы вид «многие к одному». Другой способ представить себе возникающее затруднение состоит в исследо- вании ключа (НомерСтудента, Специализация, Секция). Поскольку в отношении СТУДЕНТ имеются связи вида «многие ко многим», ключ должен содержать в себе каждый из атрибутов. Теперь спросим себя: а какую тему представляет данный ключ? Мы можем сказать, что это комбинация специальности студента и посе- щаемых им секций. Но такая комбинация не одна, их множество. Одна строка этого отношения описывает только часть комбинации, и чтобы получить всю картину, нам нужны все строки, содержащие информацию о конкретном студен- те. Вообще говоря, строка отношения должна содержать все данные, описы- вающие отдельный экземпляр темы данного отношения. Например, строка от- ношения ПОКУПАТЕЛЬ должна содержать все нужные нам данные о конкретном покупателе. Рассмотрим отношение ПОДГОТОВКА из примера № 2 в разделе, посвящен- ном доменно-ключевой нормальной форме. Ключом этого отношения является комбинация (ИмяСотрудника, Предмет). Тема состоит в том, что конкретный пре- подаватель имеет подготовку, достаточную для ведения определенного предмета. Нам нужна только одна строка этого отношения, чтобы получить всю требуемую ин<]юрмацию о комбинации данного профессора и данного предмета (в отноше- ние MOiyr входить такие атрибуты, как КоличествоЧасов, СреднийБаллКурса и т. д.). Глядя на другие строки, мы не получим никакой дополнительной инфор на эту тему. Как вы знаете, решение проблемы многозначных зависимостей заключается в том, чтобы разбить исходное отношение на два новых, каждое из которых будет иметь только одну тему. В отношении СТУДЕНТ—СПЕЦИАЛИЗАЦИЯ пред- ставлены комбинации студентов и специализаций. Все, что мы знаем о каждой из таких комбинаций, содержится в одной строке, и мы не получим какой-либо дополнительной информации о данной комбинации, исследуя другие строки.
204 Глава 4. Реляционная модель и нормализация Ненормализованные структуры В оасемопяиых нами выше методах дормажзаиии аномалии устранились за сч^огаХ исключалось дублирование каких-либо других данных, кроме кла,- чй Обычно к этому в следует стремиться, однако бывают ситуации, в которых предпочтительными являются ненормализованные структуры. В частности, речь ™ о случаях, когда нормализованная схема является неестественной, неудоб- ной или приводит к неприемлемому снижению производительности. Нормализованная схема неестественна Рассмотрим отношение КЛИЕНТ (НомерКлиента, ИмяКлиента, Город, Штат, Индекс), где ключом является НомерКлиента. Это отношение не находится в ДКНФ, по- скольку в нем имеется функциональная зависимость Индекс —> (Город, Штат), ко- торая не следует из ключа — атрибута НомерКлиента. Следовательно, мы имеем ограничение, не являющееся следствием определения ключей. Данное отношение может быть преобразовано в /два отношения следующего вада: КЛИЕНТ (НомерКлиента, ИмяКлиента, Индекс), где ключом является НомерКли- ента, и ИНДЕКСЫ (Индекс, Город, Штат), где ключом является Индекс Эти два отно- шения находятся в доменно-ключевой нормальной форме, но они, скорее всего, не представляют собой более удачного решения по сравнению с исходной таб- лицей. Ненормализованная таблица может оказаться лучше, поскольку ее будет легче обрабатывать, а неудобства, связанные с дублированием данных о городе и штате, не столь существенны. Нормализация неудобна В качестве второго примера рассмотрим отношение КОЛЛЕДЖ (НазваниеКолледжа, Декан, ЗаместительДекана), предположив, что колледж имеет одного декана и от одного до трех заместителей декана. Ключом таблицы в этом случае является сочетание (НазваниеКолледжа, ЗаместительДекана). Эта таблица не находится в до- менно-ключевой нормальной форме, так как ограничение НазваниеКолледжа -> Декан не является логическим следствием ключа таблицы. nPMAu'TJ11011116 1ЕЕ)ЛЛЕ^Ж можно нормализовать, разбив его на два отношения: ч звание олледжа, Декан) и ЗАМДЕКАНА (НазваниеКолледжа, ЗаместительДе; им I днако -ерь, когда приложению базы данных нужно будет получить стпо^<К^ЛЛеДЖепеМ^ пРидется прочитать минимум две, а возможно, и все четы- лей лекянч 1^НЬАХ ^;пВЛаЛЬТернаТИВЫ можно поместить всех трех заместнте- Потучившаяг13 ЛАЦУ ЛЛЕ^Ж; выделив для каждого индивидуальный атрибут. ДекУн За Т пЛИЦа " бЫ СледУЮ1дий вид: КОЛЛЕДЖ! (Назв Декан, ЗаместительДекана!, ЗаместительДеканаг, ЗаместительДеканаЗ! ционадьад Т К°ЛЛЕДЖ1 иах0Д1'тся в ДКНФ, поскольку все его атрибуты функ- ZX чгХ "Г “ЛЮЧа НазваниеКодд™- Однако здесь что^о потеряно. , по именно мы потеряли, предположим, что мы хотим
Ненормализованные структуры 2OS узнать названия колледжей, в которых есть заместитель декана по имени Мэри Абернати. Для этого нам придется искать данное имя в каждом из трех столбцов ЗаместительДекана. Наш запрос будет выглядеть примерно следующим образом: SELECT НазваниеКолледжа FROM КОЛЛЕДЖ! WHERE ЗаместительДекана! = 'Мэри Абернати' OR ЗаместительДекана2 = 'Мэри Абернати OR ЗаместительДеканаЗ = 'Мэри Абернати' Используя нормализованный вариант с таблицей ЗАМДЕКАНА, нам пришлось бы написать только SELECT НазваниеКолледжа FROM ЗАМДЕКАНА WHERE ЗаместительДекана = 'Мэри Абернати' В этом примере даны три возможных решения. В первом из них используется ненормализованная структура и дублируются данные о декане. Второй вариант нормализован, ио для получения всех данных о колледже требуется обрабо- тать от двух до четырех строк. Третий вариант также нормализован, но неудобен в обработке. Какой вариант лучший? Это зависит от требований, нагрузки, размера базы данных и т. д. Если немногие колледжи имеют более одного заместителя декана, возможно, приемлемым будет первый вариант. Если любой колледж может иметь более трех заместителей, последний вариант нереален. Кроме того, он вы- глядит неудачным и с эстетической точки зрения: один и тот же атрибут пред- ставляют три столбца, а используется из них, как правило, только один. Суть рассмотренного примера в том, что иногда следует принимать во внима- ние и другие критерии, помимо нормализации. Нормализация может привести к низкой производительности Представьте себе компанию, занимающуюся рассылкой товаров по почте. База данных этой компании содержит таблицу ТОВАР, находящуюся в ДКНФ и имею- щую следующий вид: ТОВАР (КодТзвара. Наименование, Цвет, Описание, Фото, КоличествоНаСкладе, Зака- занноеКоличество, Цена) Эта таблица служит источником данных для ежемесячно издаваемого катало- га и используется для обработки заказов. Атрибут Описание представляет собой Длинное текстовое поле, в котором описываются возможности и преимущества товара. Его длина может составлять более 1000 байт. Атрибут Фото — это изобра- жение в формате JPEG размером до 256 Кбайт. Если речь идет о создании ката- лога, атрибуты такой величины не представляют проблемы, поскольку таблица обрабатывается только один раз и последовательно.
206 Глава 4, Реляционная модель и нормалиэац „ , ,т, Ш пошее заказы, обращается к згой .. ты- Однако приложение, обР < ’ ‘ 1|1() 11|Ю|.ппОд»гельность здесь выходит ка сячн раз и в ^Учаипом nq * б(„кс заказо|, атрибуты Описание и Фотоне первый план. Дотстнм, I К|ер1И;1ИК используемой СУЬД может используются. В зависим Ч f столбцов значительно замедлит оказаться, что присутствие эгих двух оолыиих с м"1ут гить создать ГГтаблЯ1 • которая будет содержать копию данных, необходимых ДЛЯ К примеру они могут создать таблицу под названием ЗАКАЗ ТОВАРА Наименование, Цвет, КоличествоНаСкладе, ЗаказанноеКоличество, Цена), которая иудет использоваться только приложением, обрабатывающим з ы Обе таблицы- нормализованы, поэтому вы можете сказать троблем; ключается не в нормализации. Но целью нормализации является уменьшение дублирования данных для предотвращения аномалий и возможных проблем с це- лостностью данных. Здесь же данные сознательно дублируются, в результате чего для записи одного факта требуется несколько обновлений. Это похоже на аномалию вставки, пусть даже вставка осуществляется в две различные таблицы. В этом случае проектировщики создают потенциальный источник серьезных проблем с целостностью данных. Им придется разработать процедуры как про- граммного, так и ручного контроля, чтобы обеспечить согласованное обновление данных. Прежде чем воплощать это решение, необходимо убедиться, что повы- шение производительности окупит расходы, связанные с дополнительным кон- тролем, и риск возникновения проблем с целостностью данных. Еще один случай, когда имеет смысл дублировать данные, — это создание от- четов и поддержка принятия решений. Примеры такого дублирования вы увиди- те в главе 15 при обсуждении OLAP и схемы «звезда». Резюме Реляционная модель является на сегодняшний день промышленным стандартом. Впервые она была предложена Э. Ф Коддом в 1970 году. Поначалу ее воспри- нимали как слишком «теоретическую», но уже в 80-х годах благодаря таким прод^ктам’ как DB2 и Oracle, она успешно использовалась в организациях для обработки больших объемов транзакций. Отношение это двухмерная таблица, обладающая качествами, перечисленные МИ во врезке «Характеристики отношений». В мире баз данных вообще и в этой ниге в lacrnocTn термин таблица используется как синоним термина отноше- онной^мпеСТВ^еи Т^И На °')а теРминов’ вторыми обозначаются понятия реляци- ГкоТтеХТп всего?^одьзуются термины таблица, строка и столбец, ио (йХгитнУР ЛЦИОННч°И °бработкн данных иногда можно встретить термины Й," “ ”“е- Т“Р™>™ обозначают те же самые кон- 2“ ™‘т"сшете' Иногда употребляется сме- гня. трого говоря, отношение не может иметь одинаковых
Резюме 207 строк; на деле же иногда этим требованием пренебрегают, поскольку устранение ублируюшихся строк может быть слишком долгим процессом. Ключом называется один или несколько столбцов отношения, идентифициру- ющих строку. Уникальный ключ указывает на одну-единственную строку; неуии- кальиый ключ может указывать на несколько строк. Композитный ключ — это ключ, состоящий из двух или более атрибутов. Каждое отношение имеет один первичный ключ, который должен быть уникальным. Кроме того, отношение мо- жет иметь и другие уникальные ключи, которые называются ключами-кандида- тами. Первичный ключ представляет таблицу в ее связях, и во многих СУБД хранение таблиц основывается на значениях первичного ключа. Для обеспече- ния быстрого доступа по значению первичного ключа обычно строятся индексы. Функциональная зависимость имеет место, когда значение одного атрибута (или множества атрибутов) определяет значение другого атрибута (или множе- ства атрибутов). Атрибут с левой стороны функциональной зависимости на- зывается детерминантом. Можно сказать, что единственным предназначением отношений является хранение экземпляров функциональных зависимостей. Пер- вичный ключ (а также ключи-кандидаты) можно еще определить как атрибут, функционально определяющий все остальные атрибуты отношения. Некоторые отношениях в результате обновления данных страдают от нежела- тельных последствий, называемых аномалиями модификации. Аномалия удале- ния имеет место, когда удаление одной строки из отношения вызывает потерю информации о двух или более сущностях Аномалия вставки возникает, когда реляционная структура вынуждает нас одновременно добавлять информацию о двух сущностях. Аномалии могут быть устранены путем разбиения исходного отношения па два или более новых. Существует много типов аномалий модификации. Отношения можно класси- фицировать по типам аномалий, которые ими ликвидируются. Типы, на которые подразделяются отношения в рамках этой классификации, называются нормаль- ными формами. По определению, каждое отношение находится в первой нормальной форме. Отношение находится во второй нормальной форме, если каждый из его неклю- ченых атрибутов зависит от всего ключа. Отношение находится в третьей нор- мальной форме, если оно находится во второй нормальной форме и не имеет транзитивных зависимостей. Отношение находится в нормальной форме Бойса- Ко (да, если каждый его детерминант является ключом-кандидатом. Отношение находится в четвертой нормальной форме, если оно находится в нормальной <|юрмс Бойса-Кодда и не имеет многозначных зависимостей. Определение пятой нормальной формы не имеет интуитивной интерпретации, и поэтому мы его не приводили Отношение находится в доменно-ключевой нормальной форме, если каждое ограничение, накладываемое на это отношение, является логическим следствием определения доменов и ключей. Под ограничением здесь понимается любое условие, определяющее возможные статические значения атрибутов, истинность которого может быть проверена. Домен — это именованное множество возмож- ных значений атрибута.
208 Глава 4. Реляционная модель и нормализация Отношения можно строить с помощью нормализации, представляющей со- бой процесс анализа отношений, а также синтетическим путем, рассматривая связи между атрибутами. Если два атрибута функционально определяют друг дпуга между ними имеется связь вида «одни к одному*. Если один из двух атри- бутов функционально определяет второй, но не наоборот, между этими атрибу- тами имеется связь «многие к одному». Если ни один из двух атрибутов не опре- деляет другой, между этими атрибутами имеется связь «многие ко многим». Эти факты, перечисленные во врезке «Правила построения отношений», можно ис- пользовать при создании отношений. В некоторых случаях нормализация нежелательна. Всякий раз, когда исходная таблица разбивается на две или более новых, возникает необходимость в дополни- тельной обработке при последующем их объединении. Кроме того, необходимо контролировать соблюдение ограничений ссылочной целостности. Если расходы на дополнительную обработку двух таблиц и обеспечение ссылочной целостно- сти превышают выгоду от устранения аномалий модификации, нормализация не рекомендуется. Вдобавок в некоторых случаях создание повторяющихся столб- цов предпочтительнее обычных способов нормализации, а в других ситуациях для повышения производительности вводится преднамеренная избыт 'Чность. Вопросы группы I 1. Какие ограничения должны быть наложены на таблицу, чтобы она могла считаться отношением? 2. Определите следующие термины: отношение, кортеж, атрибут, файл, за- пись, таблица, строка, столбец. 3. Дайте определение термина функциональная зависимость. Приведите при- мер двух атриоутов, имеющих функциональную зависимость, и двух атри- бутов, не имеющих функциональной зависимости. Если атриоут НомерСтудента функционально определяет атрибут Секция, означает ли о, что значение атрибута НомерСтудента может быть только одно? Обоснуйте свой ответ. 5. 6. 7. 8. 9. 10. Данте определение термина детерминант. той летепчп тРИМеР отношен»я с функциональной зависимостью, в кото- рой детерминант состоит из двух „ли более атрибутов. Дайте определение термина ключ. детерминантом °МожУДеНТа является КЛ1°чом отношения, является ли он в отношении более одного pS*™06 ЗНаЧеНИе ?того появиться торый дан в тексте.* УДаЛенПЯ? Приведите пример, отличный от того, КО- рый дан в тексте”* ВСТаВКП? Приведите пример, отличный от того, кото-
Вопросы группы I 209 И Объясните, как соотносятся между собой первая, вторая, третья нормаль- ная формы, нормальная форма Бойса-Кодда, четвертая, пятая и доменно- ключевая нормальные формы. 12 Дайте определение термина вторая нормальная форма. Приведите пример отношения, которое находится в первой нормальной форме, но не нахо дится во второй нормальной форме. Преобразуйте это отношение в отно- шения, находящиеся во второй нормальной форме. 13. Дайте определение термина третья нормальная форма. Приведите при- мер отношения, которое находится во второй нормальной форме, но не на- ходится в третьей нормальной форме. Преобразуйте это отношение в от- ношения, находящиеся в третьей нормальной форме. 14. Дайте определение термина нормальная форма Бойса—Кодда. Приведите пример отношения, которое находится в ЗНФ, но не находится в НФБК Преобразуйте это отношение в отношения, находящиеся в НФБК. 15. Дайте определение термина многозначная зависимость. Приведите пример. 16. Почему многозначные зависимости не являются проблемой в отношениях, имеющих только два атрибута? 17 Данте определение термина четвертая нормальная форма. Приведите при- мер отношения, которое находится в НФБК, но не находится в 4НФ. Пре- образуйте это отношение в отношения, находящиеся в 4НФ. 18. Дайте определение термина доменно-ключевая нормальная форма. В чем состоит важность этой формы? 19. Преобразуйте следующее отношение к ДКНФ. Сделайте и сформулируйте соответствующие предположения о функциональных зависимостях и до- менах. ОБОРУДОВАНИЕ (Производитель, Модель, ДатаПриобретения, ИмяПокупателя, Те- лефонПокупателя, АдресЗавода, Город, Штат, Индекс) 20. Преобразуйте следующее отношение в ДКНФ. Сделайте и сформули- руйте соответствующие предположения о функциональных зависимостях и доменах. СЧЕТ (Номер, ИмяПокупателя, НомерПокупателя, АдресПокупателя, КодТовара, ЦенаТовара, КоличествоТовара, НомерПродавца, ИмяПродавца, Промежуточный- Итог, Налог, ВсегоКОплате) 21. Снова ответьте на вопрос 20, но теперь добавьте атрибут НалоговыйСтатус- Покупателя (0, если покупатель не освобожден от налога, и 1, если освобож- ден). Добавьте также ограничение, что налог не должен включаться в счет, если НалоговыйСтатусПокупателя равен 1. 22. Приведите пример (отличный от того, который дан в тексте) ситуации, в которой, как вы считаете, нормализацию производить не стоило бы. Изо- бразите отношения и обоснуйте свое решение. 23. Укажите две ситуации, в которых проектировщики базы данных могут преднамеренно прибегнуть к дублированию данных, В чем заключается риск, связанный с подобными решениями?
?10 главаД Рв»иио,Иа»модельидам.лиМии« Вопросы группы II 24. Рассмотрим следующее отношение. Таблица 4.6. Отношение ПРОЕКТ ЗарплатаСотрудника КодПроекта 100А 100А 1ООВ 200А 200В 200С 200С 200D ИмяСотрудника Джонс Смит Смит Джонс Джонс Паркс Смит Паркс $64 000 $51 000 $51 000 $64 000 $64 000 $28 000 $51 000 $28 000 । । I, ,ц|1Я, ПРОЕКТ (НазваниеПроекта, ИмяСотрудника, ЗарплатаСотрудника) Здесь НазваниеПроекта - это название рабочего проекта, ИмяСотрудника - имя сотрудника, участвующего в данном проекте, а ЗарплатаСотрудника — заработная плата данного сотрудника. Если предположить, что представленные здесь данные выявляют все имею- щиеся функциональные зависимости и ограничения, какое из следующих утверждений будет верным? 1) НазваниеПроекта -> ИмяСотрудника 2) НазваниеПроекта —> ЗарплатаСотрудника 3) (НазваниеПроекта, ИмяСотрудника) —> ЗарплатаСотрудника 4) ИмяСотрудника -> ЗарплатаСотрудника 5) ЗарплатаСотрудника -> НазваниеПроекта 6) ЗарплатаСотрудника -> (НазваниеПроекта, ИмяСотрудника) Ответьте на следующие вопросы. 7) Что является ключом отношения ПРОЕКТ? ) Все ли неключевые атрибуты (если таковые есть) зависят от всего клю- ча целиком? 9) В какой нормальной форме находится отношение ПРОЕКТ? 10) Опишите две аномалии модификации, характерные для отношения ПРОЕКТ. 11) Является ли атрибут НазваниеПроекта детерминантом? ) Является ли атрибут ИмяСотрудника детерминантом? 3 Является ли детерминантом сочетание (НазваниеПроекта, ИмяСотрудника)? 4 Является ли детерминантом ЗарплатаСотрудника? } какую?’" ЛИ ЭТ° ОТ9ОШенпе транзитивную зависимость? Если да. то 6) Переделайте это отношение так, чтобы устранить аномалии модификации-
Вопросы группы И 211 25. Рассмотрим следующее отношение: Таблица 4.7. Отношение ТРУДОЗАТРАТЫ ИмяСотрудника КодПроекта КодЗадачи Телефон ВсегоЧасов Дональд 100А В-1 12345 12 Дональд 100А Р-1 12345 12 Дональд 200В В-1 12345 12 Дональд 200В Р-1 12345 12 Памела 100А С-1 67890 26 Памела 200А С-1 67890 26 Памела 200D С-1 67890 26 ТРУДОЗАТРАТЫ (ИмяСотрудника, КодПроекта, КодЗадачи, Телефон, ВсегоЧасов) Здесь КодЗадачи — это стандартный код задачи, Телефон — номер телефона сотрудника, а ВсегоЧасов — количество часов, отработанных сотрудником в рамках данного проекта. Если предположить, что представленные здесь данные выявляют все име- ющиеся функциональные зависимости и ограничения, какое из следующих утверждений будет верным? I) ИмяСотрудника -> НазваниеПроекта 2) ИмяСотрудника —>—> НазваниеПроекта 3) ИмяСотрудника —> НазваниеЗадачи 4) ИмяСотрудника ->-> НазваниеЗадачи 5) ИмяСотрудника -> Телефон 6) ИмяСотрудника —> ВсегоЧасов 7) (ИмяСотрудника, НазваниеПроекта) —> ВсегоЧасов 8) (ИмяСотрудника, Телефон) —> НазваниеЗадачи 9) НазваниеПроекта -> НазваниеЗадачи 10) НазваниеЗадачи —> НазваниеПроекта Ответьте па следующие вопросы. И) Перечислите все детерминанты. 12) Имеет ли данное отношение проблему «неполного ключа»? Если да, то в чем она заключается? 13) Содержит ли данное отношение многозначную зависимость? Если да, то какие атрибуты не связаны между собой? 14) Опишите аномалию удаления, которая имеется в этом отношении 15) Сколько тем содержит данное отношение? 16) Переделайте отношение так. чтобы устранить аномалии модификации С ко 1ько отношении у вас получилось? Сколько тем содержит каждое из новых отношений?
212 Глава 4. Реляционная модел^нормал^иия ним/*» лит*деления отношении» доменов и ключей 26. Рассмотрим приведенные ниже опред Определения доменов: Тип данных Атрибут ИмяСотрудника Имена CHAR(20) DEC(5) CHAR(IO) НомерТелефона Телефоны НазваниеОборудования Оборудование Местоположение Места CHAR(7) Стоимость Деньги CURRENCY Дата Время Даты YYMMDD Времена HHMM, где 00 < НН < 23, 00 < ММ < 59 Отношения, ключи и ограничения: СОТРУДНИК (ИмяСотрудника, НомерТелефона) Ключ: ИмяСотрудника Ограничения: ИмяСотрудника —> НомерТелефона ОБОРУДОВАНИЕ (ИмяСотрудника, НомерТелефона) Ключ: НазваниеОборудования Ограничения: НазваниеОборудования -> Местоположение, НазваниеОбору- дования -> Стоимость СЕАНС (Дата, Время, НазваниеОборудования, ИмяСотрудника) Ключ: (Дата, Время, НазваниеОборудования) Ограничения: (Дата, Время, НазваниеОборудования) -> ИмяСотрудника 1) Модифицируйте определения так, чтобы добавить следующее ограни- чение: сотрудник не может записаться более чем на один сеанс работы с оборудованием. 2) Определим в качестве ночного времени часы между 21.00 и 05.00. До- бавьте атрибут ТипСотрудника, значение которого равно 1, если сотруд- ник работает в ночное время. Измените определения таким образом, чтобы ввести условие, что только сотрудники, работающие ночью, могут записываться на ночные сеансы. Вопросы к проекту FiredUp Фирма FiredUp наняла команду проектировщиков, разработавших для базы дан- ных фирмь! приведенные ниже отношения (вообще-то эту команду следовало бы у ол1 ть. . аза данных должна содержать информацию о проданных горелках, выполненном ремонте и клиентах. Чтобы ознакомиться с потребностями фирмы, обратитесь к проектам в конце глав 1-3. Для каждого из представленных далее
Вопросы к проекту FiredUp 213 отношений укажите ключи-кандидаты, функциональные зависимости и многознач- ные зависимости (если таковые присутствуют). Если ответ не очевиден, приведи- те обоснование этого. В какой нормальной форме находится каждое из отноше- ний, если иметь в виду указанные вами ключи и другие элементы? Преобразуйте каждое из отношений в два или более новых отношения, находящихся в доменно- ключевой нормальной форме. Укажите первичный ключ каждой таблицы, клю- чи-кандидаты и внешние ключи, а также сформулируйте ограничения ссылочной целостности, если они имеются. Отвечая на эти вопросы, исходите из следующих предположений. ♦ Тип и версия горелки определяют емкость бака. ♦ Горелка может ремонтироваться много раз, но не более одного раза в день. • f- На каждый произведенный ремонт выписывается отдельный счет. 4- Горелка может быть зарегистрирована на различных пользователей, но не одновременно. ♦ Горелка состоит из многих деталей, и каждая деталь может использо- ваться во многих горелках. Таким образом, фирма FiredUp ведет записи о различных типах деталей (например, клапан форсунки'), но не об от- дельных деталях (клапан форсунки номер 41734, изготовленный 12 декаб- ря 2001 года). Ниже следует список отношений. 1. ПРОДУКТ! (СерийныйНомер, Тип, НомерВерсии, ЕмкостьБака, ДатаИзготовления, ИнициалыИнспектора) 2. ПРОДУКТ2 (СерийныйНомер, Тип, ЕмкостьБака, ДатаРемонта, НомерСчетаЗаРемонт, СтоимостьРемонта) 3. РЕМОНТ! (НомерСчетаЗаРемонт, ДатаРемонта, СтоимостьРемонта, ИмяВыполня- вшегоРемонт, ТелефонВыполнявшегоРемонт) 4. РЕМ0НТ2 (НомерСчетаЗаРемонт, ДатаРемонта, СтоимостьРемонта, ИмяВыполня- вшегоРемонт, ТелефонВыполнявшегоРемонт, СерийныйНомер, Тип, ЕмкостьБака) 5. РЕМОНТЗ (ДатаРемонта, СтоимостьРемонта, СерийныйНомер, ДатаИзготовления) 6. Г0РЕЛКА1 (СерийныйНомер, НомерСчетаЗаРемонт, НомерДетали) 7. Г0РЕЛКА2 (СерийныйНомер, НомерСчетаЗаРемонт, РегистрационныйНомерВла- дельца) Предположим, что нужно записывать владельца горелки, даже если она никогда не ремонтировалась. Исходя из сделанных предположений, приведенных выше отношений и содер- ^ихся в них атрибутов, а также из ваших знаний о малом бизнесе, постройте ^*я фирмы FiredUp набор отношений в доменно-ключевой нормальной форме, кажите первичные ключи и внешние ключи, а также сформулируйте ограпнче- НИя ссылочной целостности.
214 Глава 4. Реляционная модель и нормализация Вопросы к проекту Twigs Tree Саманта наняла команду проектировщиков, разработавших приведенную ниже реляционную схему для учета клиентов, работ, продаж стружки и прочих дан- ных. Потребности Саманты описаны в вопросах к проекту Twigs Tree, приведен- ных в конце глав 1-3. Для каждого из перечисленных здесь отношений укажите ключи-кандидаты, функциональные зависимости и многозначные зависимости (если таковые имеются). Обоснуйте ваш выбор, если он не очевиден Исходя из этих данных, скажите, в какой нормальной форме находится каждое из отноше- ний. Преобразуйте каждое отношение в одно или несколько новых отношений, находящихся в доменно-ключевой нормальной форме. Укажите первичный ключ каждой таблицы, ключи-кандидаты, внешние ключи. Сформулируйте ограниче- ния ссылочной целостности, если таковые имеются. Отвечая на эти вопросы, ис- ходите из следующих предположений. 4- Клиент может заказать несколько работ, но не более одной в день. 4- Саманта выписывает один счет для всех работ, выполненных для конкрет- ного клиента, но иногда клиенты оплачивают счет поэтапно. 4- По конкретному виду деревьев могут выполняться различные виды работ и этот вид может быть подвержен различным болезням. 4 Клиент владеет только одним участком. 4 Клиенты могут переезжать, но их деревья остаются на прежнем месте. Тете- фонные номера клиентов при переезде могут и не меняться. В любом слу- чае Саманта хочет продолжать вести учет каждого клиента. 4 Для одного и того же клиента может выполняться множество работ, и он может неоднократно приобретать стружку. 1) КЛИЕНТ1 (Имя, Телефон, Дом, Улица, Город, Штат, Индекс, Дата, ЗаказаннаяРабота) 2) КЛИЕНТ? (Имя, Телефон, Дом, Улица, Город, Штат, Индекс, Дата, ЗаказаннаяРа- бота, НомерСчета, СуммаКОплате, ДатаПлатежа, УплаченнаяСумма) 3) ДЕРЕВО (Клиент, Дом, Улица, Город, Штат, Индекс, МестоположениеНаУчастке, Вид, ПриблВозраст, ДатаВыпРабот, ОписаниеРабот) 4) ВИД (НазваниеВида, Болезнь, ТипРабот) 5) ПОВТОРЯЮЩАЯСЯ_РАБОТА (ИмяКлиента, Телефон, ОписаниеРаботы, Периодич- ность, ДатаПоследнейРаботы) 6) ЗАКАЗ_НА_ПОСТАВКУ_СТРУЖКИ (ИмяКлиента, Телефон, ДатаЗаказа, ДатаДоставки)
Глава 5 Проектирование баз данных В этой главе описывается преобразование модели «сущность—связь» в реляци- онную схему базы данных. В качестве входной информации — модель данных и другие системные требования. Суть процесса трансформации такова: сущности преобразуются в таблицы, определяются ключи, представляются связи, и форму- лируются ограничения ссылочной целостности. На выходе мы получаем реляци- онную схему, состоящую из отношений, ключей, ограничений ссылочной целост- ности и процедур, контролирующих их соблюдение. Процесс проектирования базы данных Па рис. 5.1 изображены составляющие процесса проектирования базы данных. Исходной точкой для этого процесса являются модель данных и другие систем- ные требования. Во всех случаях, кроме самых простейших, структурная схема создается с помощью какого-нибудь программного средства для моделирования данных, например, ERWin пли Visio. Готовая схема существует в виде файла. Дополни тельные требования, такие как деловой регламент и ограничения ссы- лочной целостности, документируются вручную и отдельно. Рис. 5.1. Составляющие процесса проектирования базы данных Первым шагом в построении структурной схемы базы данных является пре образование сущностей и атрибутов в таблицы и столбцы.
216 Глава 5. Проектирование баз данных Преобразование сущностей и атрибутов в таблицы и столбцы Чтобы преобразовать модель сущность необходимо представ идентификатор сущности становится ся столбцами этой таблицы. ПоЗДХнИЕ (рис. 5 2, а) нреоб- первичным ключом повои та j. (пис 5 2 б). Идентификатор сущности ЗДАНИЕ - ат- пя ча/ртся в отношение 3 ДАНИ t ^рис. • , ) —, эплииг риб^гг НазваниеЗдания - становится первичным ключом таблицы ЗДА И ЗДАНИЕ НазваниеЗдания Дом Улица Город Штат Индекс Тип ИмяМенеджера ЗДАНИЕ НазваниеЗдания: NOT NULL Дом: NULL Улица: NOT NULL Город: NULL Штат: NULL Индекс: NULL Тип: NULL ИмяМенеджера: NULL б НазванивЗдания Дом Улица Город Штат Индекс Тип ИмяМенеджера в Рис. 5.2. Преобразование сущности в таблицу: а — сущность ЗДАНИЕ; б — таблица ЗДАНИЕ; в — альтернативный способ изображения таблицы Диаграммы на рис. 5.2 были построены с помощью программы ERWin. Обра- тите внимание на символ ключа рядом со столбцом НазваниеЗдания: он говорит о том, что столбец НазваниеЗдания является первичным ключом таблицы ЗДАНИЕ. К сожалению, сущности на диаграмме «сущность-связь» и таблицы на струк- турной схеме базы данных представляются весьма похожими графическими сим- волами. Чтобы отличать их друг от друга, в этой книге прямоугольники сущностей изображаются с тенью, а прямоугольники таблиц — без тени. Иногда разработ- чики изображают таблицы так, как показано на рис. 5.2, в. В этом случае атрибут, являющийся первичным ключом, подчеркивается. Одним из важнейших свойств атрибута является его обязательность или не- обязательность. По мнению некоторых, это свойст во атрибута должно быть опре-
Процесс проектирования базы дкныя 217 ПР пенс в модели данных. При таком подходе решение о том, является ли атрибут обязательным, принимается на стадии моделирования данных Друпосчитают что данное решение следует отложить до этана проектирования В любомслучае это необходимо сделать до того, как будет построена структурная схема. Все пер- вичные ключи являются обязательными. Внешние ключи могут (но не должны) быть обязательными, как вы увидите далее. Обязательность или нгаба ите шкх ч> прочих атрибутов определяется, исходя из системных требований. На рис. 5.2 напротив каждого атрибута указано NULL или NOT NULL NULL чает что атрибут не является обязательным, a NOT NULL — что атрибут является обязательным. В данном примере по системным требованиям проектировщики определили, что только атрибуты НазваниеЗдания и Город являются обязательны- ми На рис. 5.2, в обязательные атрибуты выделены жирным шрифтом Выбор первичного ключа Выбор первичного ключа является важным этапом. Большинство СУБД строят индексы по столбцам первичного ключа. Это позволяет использовать значения первичного ключа для организации физического хранения таблиц, а также упро- щает поиск и сортировку по ним. Кроме того, как вы увидите далее, путем копи- рования первичных ключей таблиц в другие таблицы представляются связи меж- ду сущностями. По этим причинам идеальный первичный ключ должен быть коротким (чтобы он не занимал много места и его можно было бы быстро обра- батывать) и редко меняться (поскольку он может помещаться во множество различных отношений, и все их необходимо будет обновить при изменении зна- чения ключа). Например, идеальным первичным ключом может служить 32-бит- ный целочисленный код детали. Как говорилось в главе 2, некоторые таблицы могут иметь более одного иден- тификатора. В этом случае необходимо выбрать тот из них, который наилучшим образом подходит на роль первичного ключа. Например, на рис. 5.3 показана табли- ца ОТДЕЛ, имеющая идентификатор НазваниеОтдела и два ключа-кандидата — атри- бут БюджетныйКод и сочетание {Здание, Комната}. В терминах модели IDEF1X клю- чи-кандидаты называются алыперчативными ключами (alternate keys). Запись AKn.m означает, что атрибут входит в состав и-го альтернативного ключа и явля- ется в нем m-м по счету. Так, атрибут Здание входит в состав второго альтерна- тивного ключа и является первым по счету атрибутом в этой ключевой rpvnne. ОТДЕЛ НазваниеОтдела БюджетныйКод (АК1.1) Здание (АК2.1) Комната (АК2.2) Рис. 5.3. Таблица с альтернативными ключами ®n!!aHCnW1 проектирования команда должна проанализировать каждую таб- У ее первичный ключ. Если имеются альтернативные идентификаторы, их
218 Глава 5. Проектирование баз данных необходимо сравнить и выбрать наиболее подходящий на ро.п, перьичиоиз кл« ча. Если сущность не имеет идентификатора, следует выбрать один из атрибутов в качестве такового или определить суррогатный ключ, как будет описано далее. Если исходить из перечисленных выше критериев (краткости, числового ти- па и редкого изменения), наплучшим кандидатом на роль первичного ключа на рис. 5.3 представляется атрибут БюджетныйКод. На это, правда, можно возразить что более удачным выбором будет атрибут НазваниеОтдела, так как он является более естественным с точки зрения пользователей. По слову «Бухгалтерия» лю- бой сотрудник сразу же поймет, о чем идет речь, а вот увидев бюджетный код 10445, немногие смогут догадаться, что имеется в виду бухгалтерия. Поэтому, ес- ли названия отделов достаточно коротки, в качестве первичного ключа можно также использовать атрибут НазваниеОтдела. ДЕРЕВО ч Д°м Ч Улица Ч Город Ч Штат Ч Индекс Ч Местоположение Вид Возраст ДЕРЕВО Ч Дом Ч Улица Ч Город Ч Штат Ч Индекс Ч Местоположение Вид Возраст а ________РАБОТА_______ ' Ч дом (FK) Ч Улица (FK) ________. Ч Город (FK) Ч Штат (FK) Ч Индекс (FK) Ч Местоположение (FK) Ч Дата ^Описание б ДЕРЕВО в Рис. 5.4. Потребность в суррогатных ключах: а — таблица со слишком большим первичным ключом; б — дальнейшее разрастание ключа при помещении его в другую таблицу; в — вариант с. использованием суррогатных ключей
Процесс проектирования базы данных 219 Но рассмотрим теперь отношение ДЕРЕВО, показанное на рис. 5.4, а. ую таблицу может использовать фирма, занимающаяся стрижкой или опрыскива- нием теревьев. Первичным ключом этой таблицы является сочетание {Дом, Ули Город Штат, Индекс, Местоположение}, где атрибут Местоположение указывает местоположение дерева на участке. Этот ключ слишком длинный, поэтому его будет трудно индексировать. Кроме того, посмотрим, что получится, если это от- ношение будет выступать в роли родителя в связи. Рассмотрим идентификационно-зависимую таблицу РАБОТА, показанную на рис 5.4, б. По определению идентифицирующей связи, первичный ключ по- томка содержит в себе первичный ключ родителя. В данном случае это означает, что в таблицу РАБОТА будет помещен непомерно длинный ключ таблицы ДЕРЕВО. Теперь мы имеем два проблематичных ключа: один в таблице ДЕРЕВО, другой в таблице РАБОТА. В таких ситуациях проектировщики часто используют сурро- гатные ключи. Суррогатные ключи Суррогатный ключ (surrogate key) — это предоставляемый СУБД уникальный идентификатор, используемый в качестве первичного ключа отношения. Значе- ния суррогат ши о к дюча не имеют смысла для пользователей, поэтому в формах и отчетах они обычно опускаются. СУБД не допускает изменения значения сурро- гатною ключа. В каждой СУБД суррогатные ключи определяются по-своему. На рис. 5.5 изо- бражен процесс определения суррогатного ключа в SQL Server. В поле Identity Seed (Начальное значение) задается начальное значение суррогатного ключа. Это значение присваивается первой проке, вставленной в таблицу' TREE. В поле Identity Increment (Приращение) задается число, которое будет прибавляться к текущему значению суррогатно ключа для получения следующего значения. В примере ня рис. 5.5 первой строке таблицы будет присвоено значение сурро- гатного ключа TreelD, равное 100, второй строке — 110, и так далее. Как происхо- дит определение суррогатных ключей в СУБД Oracle, мы [>асскажем в главе 10. Суррогатные ключи — это короткие числа, которые никогда не меняются. Таким образом, они являются идеальными первичными ключами. К тому же они не создают большой дополнительной нагрузки при использовании в качестве внешних ключей Сравните реляционные схемы на рис. 5.4, б и 5.4, в. Использо- вание суррогатных ключей потенциально экономит сотни байтов дискового про- странства на каждую строку отношения РАБОТА Тем нс менее, у суррогатных ключей имеются два важных недостатка. Во-пер- «Ых. внешние ключи, основанные на суррогатных ключах, не имеют смысла Для пользователей Чтобы понять, почему это может быть проблемой, представь- себе таблицу СОТРУДНИК, содержащую внешний ключ ИдОтдела1, который ответствует суррогатному ключу ИдОтдел в таблице ОТДЕЛ. Значение атрибута м^~"У**ИИС,1а ялючей будут иметь нил ИдХ. тле .Ид. - это сокращение от сло- Х ~ ,у,,1"'‘сти которой принадлежит данный суррогатный ключ, п поди — Примеч перге. г
220 Глава 5. Проектирование баз данных--------.------------------------ ИдОтдела, равное 1150, ничего не скажет пользователям Чтобы узнать отдела, необхо щмо найти в базе данных строку отношения ОТДЕЛ, । юпороЦ рнбут ИдОтдела ранен 1150. Рис. 5.5. Определение суррогатного ключа в SQL Server Сравните это с ситуацией, когда в качестве первичного ключа в отношении ОТДЕЛ и внешнего ключа в отношении СОТРУДНИК используется атрибут Название- Отдела. Если название отдела — это все, что нужно знать пользователю об отделе, где работает сотрудник, то больше обращений к базе данных не потребуется. Со вторым недостатком суррогатных ключей приходиться сталкиваться в слу- чаях, когда информация распределена по нескольким базам данных. Пусты на- пример, у компании имеется три базы данных по продажам, в каждой из которых содержатся сведения об определенной линии продуктов. В каждой из этих баз данных имеется таблица под названием ЗАКАЗ с суррогатным ключом ИдЗаказа. СУ БД присваивает столбцу ИдЗаказа уникальные значения в пределах одной базы данных. Эти значения, однако, не являются уникальными в рамках всех трех баз данных. Таким образом, возможна ситуация, когда две строки в таблице ЗАКАЗ двух различных баз данных будут иметь одно и то же значение атрибута ИдЗаказа Эю не является проблемой до тех пор, пока не возникает необходимость отъединить базы данных. При объединении баз данных, чтобы избежать воз- никновения строк с одинаковыми значениями суррогатного ключа, значения атрибута I/ Заказа необходимо будет изменить. По если меняются значения । (рвичною ключа, то, возможно, потребуется изменить и значения внешних
Представление связей 221 -тцочей В результате получится путаница или, по крайней мере, отребу я ^шая работа по предотвращению этой путаницы. Разумеется, можно обеспечить уникальность значении суррогата! между различными базами данных, задавая для них различные начальные значе- ния Но этот процесс требует тщательного управления и соблюдения соответ- ствующих процедур, и вероятность появления дубликатов все равно Последнее замечание. Некоторые проектировщики баз данных из соображе- ний последовательности стоят на той позиции, что если одна таблица имеет суррогатный ключ, то и все остальные таблицы в базе данных также должны иметь суррогатные ключи. По мнению других, этой политике не хватает гибко- сти: в конце концов, есть данные, могущие служить хорошими ключами (напри- мер, КодПродукта), и если такие данные имеются, то следует использовать их, а не суррогатные ключи. Представление связей После того как для каждой сущности было создано отношение и для каждого от- ношения выбран первичный ключ, следующим шагом является представление связей между сущностями. В реляционной модели все связи представляются путем помещения первичного ключа одной таблицы в другую таблицу. Как уже говори- лось, во второй таблице такой ключ называется внешним ключом (foreign key). Принципы представления связей Конкретный способ представления связи зависит от ее типа. Далее мы обсудим представление каждого из рассмотренных нами типов связей, но прежде необхо- димо понять три принципа, справедливых по отношению ко всем типам связей: поддержание ссылочной целостности, определение альтернативных процедур ее обеспечения и реализация ограничений минимальной кардинальности. Рассмот- рим каждый из этих принципов. Стандартные правила поддержания ссылочной целостности Вс кий раз, когда мы создаем внешний ключ, мы тем самым вводим новое огра- ничение ссылочной целостности. Допустим, мы хотим представить связь между сущностями СОТРУДНИК и ОТДЕЛ. Пусть отдел может иметь множество сотрудни- ков. но любой сотрудник может работать только в одном отделе. Как вы узнаете Птлг'п' такая СБЯЗЬ вида 1:N пРедставляется путем помещения ключа отношения ДЕЛ в отношение СОТРУДНИК. Предположим, что ключом отношения ОТДЕЛ яв- я атрибут НазваниеОтдела; соответственно, мы помещаем его как внешний ключ в отношение СОТРУДНИК. Теперь у нас есть следующее ограничение ссылоч- ной целостности. Значение атрибута СОТРУДНИК.НазваниеОтдела должно существовать среди значений атрибута ОТДЕЛ.НазваниеОтдела.
222 Глава 5.11роектирование без данных При создании связи мы можем процнструкгиронаю СУБД, чтобы Она иГ«зняи- (п.-п С-шс этою ограничения. (В следующей главе вы узнаето кам ЭТО ется с Помощью SQI.) Если сделаю ток, к> каждый раз. прежде чем добавь «еду» стоокх в отношение СОТРУДНИК. СУБД будет проверяю имейся ли «ютвете^ ющее значение атрибута НазваниеОтдела в отношении ОТДЕЛ. Если нет, в добавде- нин строки будет • казано. Аналогичным образом, прежде чем обновить значение столбца СОТРУДНИК-НазваниеОтдела, СУБД будет проверяю, присутствует ли новое значение среди значений атрибута НазваниеОтдела в отношении ОТДЕЛ. Если нет, СУБД не разрешит обновление. Удаление строки в дочерней таблице ие затраги- вает данное ограничение, поэтому его соблюдение в этом случае не проверяется. В связи родитель-потомок, если меняется значение первичного ключа роди- тельской строки, ограничение ссылочной целостности будет нарушено для всех дочерних строк. В связи с этим по умолчанию СУБД не разрешает обновление первичного ключа в строке, имеющей потомков. Так, например, если мы захотим поменять название отдела «Бухгалтерия» на «Бухгалтерский учет», то СУБД не разрешит нам это сделать, если в бухгалтерии числятся какие-то сотрудники. Подобным же образом при удалении родительской строки значение внешнего ключа всех ее дочерних строк будет нарушать ограничение ссылочной целостно- сти. Поэтому строка не может быть удалена, если у нее имеются потомки. Чтобы удалить родительскую строку, необходимо прежде удалить все дочерние строки. Вставка новой родительской строки не затрагивает ограничение ссылочной цело- стности, поэтому его соблюдение не проверяется. Стандартные правила поддер- жания ссылочной целостности сведены в таблицу на рис. 5.6. Действие на родительской твблице Вставка новой строки Всегда разрешена Обновление первичного ключа Запрещено, если имеются дочерние строки Удаление строки Запрещено, если имеются дочерние строки Действие на дочерней таблице Вставка новой строки Запрещена, если значение внешнего ключа в новой строке не соответствует ни одному значению первичного ключа в родительской таблице Обновление внешнего ключа Запрещено, если обновленное значение внешнего ключа не соответствует ни одному значению первичного ключа в родительской таблице Удаление существующей строки ’—- туу- - — г— правила поддержания ссылочной целостности
Представление связей 223 Альтернативные процедуры обеспечения ссылочной целостности Ппя некоторых баз данных описанные ранее стандартные процедуры поддержания точной целостности являются слишком жесткими. Например, приложение мо- жет иметь политику, в соответствии с которой для дочерних строк при необходимо- сти создаются родительские строки. В примере с отношениями ОТДЕЛ и СОТРУДНИК, если в отношение СОТРУДНИК вставляется строка, содержащая название несуще- ствующего отдела, в отношении ОТДЕЛ также создается строка с таким названием. Такая политика, если она существует, заменяет собой заданные по умолчанию правила поддержания ссылочной целостности, и сформулировать ее необходимо на стадии проектирования базы данных. Позже, на стадии реализации, ее принци- пы будут запрограммированы в виде триггеров (об этом вы узнаете из главы 7). Такие нестандартные правила определяются в процедурах обеспечения ссылоч- ной целостности (referential integrity actions). Для каждой связи имеется шесть возможных действий — три над потомком и три над родителем. Это вставка, об- новление в удаление потомка, а также вставка, обновление и удаление родителя. Вводя новую связь, необходимо всегда думать о том, какие действия над ней мо- гут производиться и какие процедуры потребуются для обеспечения ссылочной целостности в каждом из случаев. Две такие процедуры особенно распространены. Они затрагивают обновление п удаление на родительской стороне связи. Что касается обновлении, по умолча- нию значение первичного ключа строки не может быть обновлено, если у этой строки имеются потомки. Но есть и другая возможность — автоматически изме- нять значение внешнего ключа во всех дочерних строках, связанных с данной. Например, когда в отношении ОТДЕЛ название отдела «Бухгалтерия» меняется на «Бухгалтерский учет», можно соответствующим образом изменить значение атрибута НазваниеОтдела во всех дочерних строках отношения СОТРУДНИК. Таким образом связь между строками будет сохранена, и ограничения ссылочной це- лое! пости также будут соблюдены. Такая политика носит название каскадного обновления (cascading updates). Если нам нужно такое поведение, мы должны определить его на стадии проектирования как процедуру обеспечения ссылочной целостности при обновлении. Аналогичным образом, вместо того чтобы запрещать удаление строк, имею- щих потомков, СУБД может автоматически удалять все дочерние строки. Эта процедура также обеспечивает соблюдение ограничений ссылочной целостно- сти. Она носит название каскадного удаления (cascade deletions). Это поведение, если оно желательно, также необходимо предусмотреть на стадии проектирова- ния как процедуру обеспечения ссылочной целостности при удалении. Реализация ограничений минимальной кардинальности Третий важный принцип затрагивает различия между способами реализации огра- ern^v,,Й ы,ой кардинальности для дочерних и родительских строк. Если коХп^’ССТ обязательного Родителя, мы должны объявить обязательным толь- клГч "W«°ro ключа. В этом случае СУБД не допустит, чтобы внешний имел пустое значение, поэтому данная строка всегда будет иметь родителя
224 Глава 5. Проектирование баз данных Если же оояаательиым является потомок, то удобно! ибск и*пгп» для строки гарантированное наличие потомка не существует В ом случае мм стадии проектирования необходимо определить процедуры обеспечения сеидов ной целостности для этого ограничения» а па стадии ре; изации воплотить агги процедуры в виде триггеров. Рассмотрим процедуры, требуемые на дочерней стороне связи. Если минимиыюе кардинальное число на стороне потомка равно 1, это значит, что у родительской строки должен быть как минимум одни потомок. Следовательно, последняя дочери няя строка в связи не может быть удалена. В нашем примере, когда любому отделу в отношении ОТДЕЛ должен соответствовать по крайней мере один сотрудник в отношении СОТРУДНИК, мы не можем допустить удаления строки из отношения СОТРУДНИК, если она содержит запись о единственном сотруднике какого-то отдела. Аналогичным образом, мы не можем разрешить обновление столбца СОТРУДНИК. НазваниеОтдела. если этот сотрудник является единственным в данном отделе. Теперь рассмотрим ситуацию с обязательным потомком с точки зрения роди- теля. Добавляя нову ю родительскую строку, мы обязаны назначить ей потомка. Это можно сделать, создав новую дочернюю строку или назначив в качестве та- ковой уже существующую строку. К сожалению, в СУБД отсутствуют возможности для реализации этих гра- ничений. Поэтому команда разработчиков должна документировать их виде процедур обеспечения ссылочной целостности при обновлении и удалении по- томка и при вставке родителя. Таким образом, всякий раз, когда вам встречается связь с обязательным потомком, имейте в виду, что вам необходимо будет опре- делить соответствующие процедуры обеспечения ссылочной целостности. Познакомившись с этими основными принципами, можно приступить к рас- смотрению способов представления различных видов связей. В табл. 5.1 перечис- лены типы связей и приведены соответствующие термины расширенной модели «сущность—связь» и модели IDEF1X. В следующих разделах мы рассмотрим по очереди все типы связей. Таблица 5.1. Типы связей Тип связи в расширенной модели «сущность- связь» Тип связи в модель IDEF1X Примечания Идентификационно- зависимая Идентифицирующая связь принадлежности 1:1, 1:N типа «ИМЕЕТ» N:M типа «ИМЕЕТ» Неидентифицирующая В IDEF1X в связях 1:1 обязательно связь принадлежности Неспецифическая должен быть родитель и потомок Надтип/подтип Категориальная Категории внутри кластера являются взаимоисключающими. В модели «сущность—связь» такого рода ограничение отсутствует Слабая, но не идентификационно- зависимая Отсутствует Реализуется с помощью процедур обеспечения ссылочной целостное»*
Представлени» связей 220 Представление идентификационно- зависимых связей Для идентификационно-зависимых связей (называемых идентифицирующими связями принадлежности в модели IDEF1X) требуется только поместить ключ родительского отношения в качестве нового столбца в отношение-потомок. По определению, для идентификационно-зависимых связей этот столбец становится частью первичного ключа потомка. Так, например, столбец НазваниеЗдания, яв- ляющийся ключом отношения ЗДАНИЕ (рис. 5.7, «), помещается в отношение КВАРТИРА (рис. 5.7, б). Первичным ключом отношения КВАРТИРА становится соче- тание {НазваниеЗдания, НомерКвартиры}. Разумеется, если первичный ключ роди- теля является композитным, все элементы этого композитного ключа будут по- мещены в дочернее отношение, как это было с отношением ДЕРЕВО (см. рис. 5.4). ЗДАНИЕ НазваниеЗдания КВАРТИРА Дом Улица Город Штат Индекс Тип ИмяМенеджера НомерКвартиры ЧислоСпален Площадь АренднаяПлата ЗДАНИЕ НазваниеЗдания: NOT NULL КВАРТИРА Дом: NULL Улица: NOT NULL Город: NULL Штаг NULL Индекс: NULL Тип: NULL ИмяМенеджера: NULL НомерКвартиры: NOT NULL Ч НазваниеЗдания: NOT NULL (FK) ЧислоСпален: NULL Площадь: NULL АренднаяПлата: NOT NULL а б ЗДАНИЕ ^НазваниеЗдания: NOT NULL Дом: NULL Улица: NOT NULL Город; NULL Штат; NULL D:R U:C Индекс: NULL Тип: NULL ИмяМенеджера: NULL ____________КВАРТИРА___________ НомерКвартиры NOT NULL “ НазваниеЗдания: NOT NULL (FK) ЧислоСпален: NULL Площадь: NULL АренднаяПлата: NOT NULL Рис. 5.7. Представление Идентификационно-зависимых свяшй- > идентификационно-зависимой связи; б - релХн^ «е^- процедуры обеспечения ссылочной целостности
226 Глава 5. Проектирование баз данных Столбец НазваниеЗдания в Для —ключа- Таким образом, Назван^ , и часть первичного ключа отношения КВАРТИРА Но в роли первичного ключа этот столбец выступает только в отношении ЗДАНИЕ Процедуры обеспечения ссылочной целостности Поместив внешний ключ в отношение-потомок, на следующем шаге необходимо определить, какие процедуры понадобятся для реализации ограничении ссылоч- ной целостности при всевозможных действиях над связью. Как отмечалось выше, это могут быть какие-то нестандартные процедуры, заменяющие собой заданные по умолчанию правила поддержания ссылочной целостности, либо процедуры, направленные на то, чтобы гарантировать наличие обязательного потомка. Что касается первого, то по определению идентификационно-зависимой связи, мы имеем следующее ограничение ссылочной целостности. Значение атрибута КВАРТИРА.НазваниеЗдания должно существовать среди значений атрибута ЗДАНИЕ.НазваниеЗдания Теперь подумаем: нужно ли нам вводить какие-то процедуры, подменяющие стандартные правила поддержания ссылочной целостности для данного ограни- чения? Со стороны потомка используемое по умолчанию поведение нас устраи- вает. В самом деле, нам нужно запретить вставку новой строки в отношение КВАРТИРА, если значение атрибута НазваниеЗдания в ней не соответствует ни од- ному из существующих значений атрибута ЗДАНИЕ.НазваниеЗдания, и при тех же обстоятельствах запретить обновление. А вот с родительской стороны лучше было бы, по-видимому, разрешить кас- кадные обновления. Если по той или иной причине название здания должно из- мениться, нет смысла запрещать это изменение: лучше просто распространить его на всех потомков На рис. 5.7, в показано, как такие процедуры обозначаются в ERWin. «U:C» означает «Update:Cascade» («Обновление:Каскадное»). Таким образом, согласно этой схеме, значение атрибута НазваниеЗдания может быть изменено, и эти изме- нения будут распространяться на все квартиры в соответствующем здании. <D:R>> со стороны сущности ЗДАНИЕ означает «DeleteRestrict» («Удаление: Ограничить»), Эта запись означает, что будет запрещено удаление зданий, для которых имеются записи о квартирах. Поскольку такое поведение имеет место по умолчанию, нет необходимости задавать его явным образом. На данной схеме оно указано только для того, чтобы подчеркнуть, что каскадное удаление произ- водиться не будет. Соображения по поводу каскадного удаления в идентификационно-зависимых связях Каскадное обновление не представляет больших трудностей- дочерние строки просто обновляются синхронно с родительскими. Другое дело каскадное удале-
Представление । е« мА 227 ie особенно если у потомков имеются связи с другими таблицами Здесь мм приведем соображения, которыми следует руководствоваться при принятии ре- шения о том, разрешать ли каскадное удаление. Общее правило таково: если идентификационно-зависимая сущность пред ставляет многозначные атрибуты, например, несколько телефонных номеров, как на рис. 5.8, а, в использовании каскадного удаления есть смысл. В конце кон- цов, было бы довольно странно, если бы нельзя было удалить запись о сотрудни- ке только потому, что у него несколько телефонных номеров. Соответствующие процедуры обеспечения ссылочной целостности показаны на рис. 5 8, 6. СОТРУДНИК ТЕЛЕФОН ТЕЛЕФОН СОТРУДНИК б Рис. 5.8. Оправданное каскадное удаление и обновление: а — пример с многозначным атрибутом; б — реляционная схема с каскадным удалением и обновлением Если же идентификационно-зависимая сущность представляет собой не- что иное, чем просто многозначный атрибут, то прежде чем принимать решение об использовании каскадных удалений!, необходимо тщательно проанализировать все требования. Рассмотрим, например, отношение НАЗНАЧЕНИЕ на рис. 5.9, а. Если удаляется информация о сотруднике, является ли это поводом для уда- ления данных о его назначениях? Аналогично, если удаляется проект, следует ли из этого, что нужно удалить все назначения этого проекта? Можно привес- ти множество аргументов в пользу обоих вариантов ответа, и единственный способ разрешить этот спор — проанализировать требования или спросить поль- зователей. Согласно рис. 5.9, б, было принято следующее решение: удаление проекта мо- жет инициировать каскадное удаление строк в таблице НАЗНАЧЕНИЕ, а удаление сотрудника — нет. Обоснование заключается в том, что если удаляется проект, то сделанные в его рамках назначения теряют смысл, а если удаляется сотруд- ник, его назначения должны быть переданы кому-то другому Таким образом, приложение, перед тем как удалить данные о сотруднике, сначала переназначит его работу другому сотруднику, создав для того новые назначения, и удалит •азначения первого сотрудника.
228 Глава 5. проектирование баз данных б Рис. 5.09. Различные решения относительно каскадного удаления и обновления: а — пример с двумя связями; б — со стороны таблицы СОТРУДНИК каскадное удаление не предусматривается Представление идентификационно-зависимых связей с использованием суррогатных ключей Если родитель в идентификационно-зависимой связи имеет в качестве первичного ключа суррогатный ключ, а у потомка роль ключа выполняют данные, описанное выше правило будет превосходно работать. Нужно просто использовать в качест- ве первичного ключа суррогатный ключ родителя. Вернемся к случаю с отноше- ниями ЗДАНИЕ и КВАРТИРА. Пусть первичным ключом таблицы ЗДАНИЕ является столоец ИдЗдания, представляющий собой суррогатный ключ, а локальным иден- тификатором отношения КВАРТИРА является НомерКвартиры. В этом случае пер- вичным ключом отношения КВАРТИРА будет группа {ИдЗдания, НомерКвартиры} со следующим ограничением ссылочной целостности. Значение атрибута КВАРТИРА.ИдЗдания должно существовать среди значе- ний атрибута ЗДАНИЕ.ИдЗдания.
Представление связей 229 Хотя эта стратегия работает, она не приводит нас к наилучшей схеме. Сочета- ние {ИдЗдания, НомерКвартиры} являет собой смесь суррогатного ключа с даниы- и пе будет иметь смысла для пользователей. Поэтому использование столбца НомерКвартиры как элемента ключа не дает преимуществ. Лучше, чтобы первич- ным ключом таблицы КВАРТИРА был настоящий суррогатный ключ с названием вроде ИдКвартиры. В этом случае ИдЗдания также нужно будет поместить в качестве внешнего ключа в таблицу КВАРТИРА, но теперь он уже не будет составлять часть первич- ного ключа этой таблицы. В итоге отношения будут иметь следующий вид. ЗДАНИЕ (ИдЗдания, НазваниеЗдания, Улица,... прочие неключевые атрибуты). КВАРТИРА (ИдКвартиры, ИдЗдания, НомерКвартиры,... прочие неключевые ат- рибуты). Ограничение ссылочной целостности сохранит прежний вид: Значение атрибута КВАРТИРА.ИдЗдания должно существовать среди значе- ний атрибута ЗДАНИЕ.ИдЗдания. Первичные ключи подчеркнуты, а внешний ключ выделен курсивом. Такая ситуация возникает всегда, когда родитель в идентификационно-зави- симой связи имеет суррогатный ключ. Поэтому можно сделать следующее обоб- щение: если родитель в идентификационно-зависимой связи имеет суррогатный ключ, потомок также должен иметь суррогатный ключ. При этом обратите внимание, что использование суррогатного ключа в дочер- ней таблице меняет тип связи. Таблица КВАРТИРА с суррогатным ключом ИдКвар- тиры из предыдущего примера уже не является идентификационно-зависимой, поскольку у нее есть свой собственный ключ. Это не преимущество или недо- статок: следует просто иметь в виду, что при таком использовании суррогатных ключей идентификационно-зависимая связь превращается в неидентифициру- ющую связь вида 1:N. Представление связей принадлежности вида 1:1 и 1:N Согласно расширенной модели «сущность—связь», есть три вида связей принадлеж- ности, или связей типа «ИМЕЕТ»: 1:1,1:N и N:M. В этом разделе мы рассмотрим представление первых двух из них. Связи принадлежности вида N:M будут обсу- ждаться в следующем разделе. Как вы помните из материала главы 2 и табл. 5.1, в модели IDEF1X связи принадлежности вида 1:1 и 1:N называются неидентифи- инрующими связями принадлежности, а связи вида N:M - неспецифическими связями. Таким образом, в терминах модели IDEF1X, мы сейчас будем рассмат- ривать представление неидентифицирующих связей принадлежности. Представление связей «один к одному» связьТ/’10 пок“аиа спязь 1;1 в символике расширенной модели «сущность- . на рис. 5.11, ди рис. 5.12, «-та же связь в символике модели IDEF1X
230 Глава 5. Проектирование баз данных Все эти рисунки моделируют ситуацию, когда каждый автомобиль должен быть закреплен за каким-то одним сотрудником, а произвольно взятый сотрудник мо- жет не иметь служебного автомобиля пли иметь только один автомобиль СОТРУДНИК НомерСотрудника ИмяСотрудника Телефон АВТОМОБИЛЬ НомерЛицензии СерийныйНомер Цвет Производитель Модель + Рис. 5.10. Диаграмма расширенной модели «сущность связь» для связи вида 1.1 Чтобы представить связь вида 1:1, нужно поместить ключ одной таблицы в другую. У нас есть выбор: либо поместить ключ отношения СОТРУДНИК в отно- шение АВТОМОБИЛЬ, либо поместить ключ отношения АВТОМОБИЛЬ в отношение СОТРУДНИК. В принципе, бывают ситуации, когда один из вариантов выигрывает в производительности, но для представления связи вида 1:1 обе альтернативы равноценны. Поскольку связь имеет вид 1:1, только одна строка отношения-потомка может иметь заданное значение внешнего ключа. Например, если таблица АВТОМОБИЛЬ имеет внешний ключ НомерСотрудника, конкретное значение атрибута НомерСо- трудника может появиться в этом отношении только один раз. Поэтому столбец НомерСотрудника в отношении АВТОМОБИЛЬ должен быть объявлен уникальным (UNIQUE). Точно так же, если отношение СОТРУДНИК имеет внешний ключ Номер- Лицензии, конкретный номер лицензии может фигурировать только в одной стро- ке отношения СОТРУДНИК. Соответственно, столбец НомерЛицензии должен быть объявлен уникальным в отношении СОТРУДНИК. Вариант с таблицей СОТРУДНИК в качестве родителя Модель IDEF1X навязывает определенную структуру для представления связей вида 1:1. Вспомните, что, согласно стандарту IDEF1X, каждая связь принадлеж- ности имеет сущность-родителя и сущность-потомка. В случае связей 1:1 это на- вязанный выбор, так как любая из сущностей может считаться и родителем, и по- томком. На рис. 5.11 показан вариант модели данных и структурной схемы базы данных, в котором в качестве родителя выбрана сущность СОТРУДНИК, а в качестве потомка — сущность АВТОМОБИЛЬ. Обратный случай представлен на рис. 5.13. Ключ родительской сущности всегда помещается в сущность-потомок. Так, на рис. 5.11, б мы помещаем атрибут НомерСотрудника в сущность АВТОМОБИЛЬ. Поскольку мы имеем дело со связью вида 1:1, атрибут НомерСотрудника должен быть определен как уникальный. При использовании программы ERWin единст- венный способ указать, что столбец является уникальным, — определить его как альтернативный ключ. Это было сделано на рис. 5.11, б. Соответственно, интер- претируя данный рисунок, следует понимать, что относительно атрибута Номер- Сотрудника подразумевается лишь его уникальность. С семантической точки зре- ния он не является альтернативным ключом отношения АВТОМОБИЛЬ.
Представление связей 231 СОТРУДНИК НомерСотрудника АВТОМОБИЛЬ ИмяСотрудника Телефон НомерЛицензии СерийныйНомер Цвет Производитель Модель СОТРУДНИК НомерСотрудника АВТОМОБИЛЬ ИмяСотрудника Телефон НомерЛицензии СерийныйНомер Цвет Производитель Модель НомерСотрудника (FK) (АК1.1) б СОТРУДНИК АВТОМОБИЛЬ е Рис. 5.11. Связь вида 1:1 с сущностью СОТРУДНИК, рассматриваемой в качестве родителя: а — модель IDEF1X; б — реляционная схема; в — процедуры обеспечения ссылочной целостности Создавая внешний ключ, мы тем самым порождаем ограничение ссылочной целостности. Для рис. 5.11, б это ограничение имеет следующий вид. Значение атрибута АВТОМОБИЛЬ.НомерСотрудника должно существовать сре- ди значений атрибута СОТРУДНИК.НомерСотрудника. Всякий раз, когда мы сталкиваемся с подобным ограничением, мы должны рассмотреть процедуры обеспечения ссылочной целостности. Как показано на рис. 5.11, в, со стороны таблицы СОТРУДНИК мы ограничиваем удаление и разре- шаем каскадное обновление. При вставке строки никаких процедур выполнять не требуется, поскольку сотрудник не обязан иметь автомобиль. Нового сотрудника можно добавить в базу данных, не задаваясь вопросом, есть ли у него автомобиль. Со стороны таблицы АВТОМОБИЛЬ мы можем удалять и переназначать строки без всяких ограничений, поскольку, как уже говорилось выше, сотрудник не обя- зан иметь автомобиль. Поэтому для таблицы АВТОМОБИЛЬ не определено ника- ких процедур обеспечения ссылочной целостности при удалении или обнов- лении. Однако минимальное кардинальное число связи со стороны сущности ОТРУДНИК равно 1, то есть автомобиль обязан быть закрепленным за каким-то сотрудником. Следовательно, атрибут АВТОМОБИЛЬ.НомерСотрудника не может
232 Глава 5. Проектирование баз данных иметь пустое значение. Чтобы выполнить ли требование, опреде. лить процедуру, которая при добавлении строки в таблицу АВТОМОБИЛЬ будет назначать данный автомобиль некоторому сотруднику. На данном этане не обя- зательно документально фиксировать это правило: достаточно просто указать, что такое правило необходимо. Вариант с таблицей АВТОМОБИЛЬ в качестве родителя На рис. 5.12 показан вариант модели данных и структурной схемы базы данных, в котором в качестве родителя выбрана сущность АВТОМОБИЛЬ, а в качестве по- томка - сущность СОТРУДНИК. Здесь внешний ключ - атрибут НомерЛицензии - помещается в сущность СОТРУДНИК. Поскольку сотрудник не обязан иметь авто- мобиль, атрибут СОТРУДНИК.НомерЛицензии может иметь пустое значение, как показывает рис. 5.12, б. Заметьте также, что атрибут СОТРУДНИК.НомерЛицензии показан на диаграмме как альтернативный ключ. Как и в предыдущем варианте, это было сделано потому, что связь имеет вид 1:1, и нам нужна гарантия, что кон- кретный номер лицензии сможет появиться в таблице СОТРУДНИК лишь едино- жды. Определив его как альтернативный ключ, мы можем быть уверены, что его значения будут уникальными. СОТРУДНИК НомерСотрудника ИмяСотрудника Телефон АВТОМОБИЛЬ НомерЛицензии СерийныйНомер с Цвет Производитель Модель __________СОТРУДНИК___________ НомерСотрудника: NOT NULL ИмяСотрудника: NULL Телефон: NULL •" НомерЛицензии: NULL (FK) (АК1.1) 1 АВТОМОБИЛЬ Ч НомерЛицензии: NOT NULL СерийныйНомер: NULL Цвет: NULL Производитель: NULL Модель: NULL _________СОТРУДНИК____________ НомерСотрудника: NOT NULL ИмяСотрудника: NULL U:R Телефон: NULL *" НомерЛицензии: NULL (FK) (AK1.1) 1 ________АВТОМОБИЛЬ PScT ^НомерЛицензии: NOT NULL U:C ---------------------------- ----с СерийныйНомер: NULL Цвет: NULL Производитель: NULL Модель: NULL Рис. 5.12. Связь вида 1:1 e ..1 с сущностью АВТОМОБИЛЬ, рассматриваемой в качестве родителя: а — модель IDEF1X; б — реляционная схема: в — процедуры обеспечения ссылочной целостности
Представление связей 233 Ограничение ссылочной целостности для данного варианта выглядит сле- дующим образом: Значение атрибута СОТРУДНИК.НомерЛицензии должно существовать среди значений атрибута АВТОМОБИЛЬ.НомерЛицензии. Процедуры обеспечения ссылочной целостности для данной связи показаны на рис. 5.12, в. Здесь процедуры имеют более сложный вид, чем в предыдущем случае (см. рис. 5.11, в), поскольку сущность АВТОМОБИЛЬ имеет обязательного потомка. Как отмечалось выше, единственный способ реализовать такое огра- ничение — определить соответствующие процедуры обеспечения ссылочной целостности. Начнем со стороны сущности АВТОМОБИЛЬ. Когда из базы данных удаляется запись об автомобиле, внешнему ключу НомерЛицензии присваивается пустое значение, поскольку модель данных не требует, чтобы сотрудник обязательно имел автомобиль. Эта процедура обозначается на диаграмме как SN (set to null). Таким образом, если удалить строку из таблицы АВТОМОБИЛЬ, сотрудник потеря- ет автомобиль, но никакие ограничения нарушены не будут. Когда в базу данных добавляется новый автомобиль, он по умолчанию при- сваивается определенному сотруднику. Данная процедура обозначается на схеме как SD (set default). Это необходимо, поскольку модель данных требует, чтобы каждый автомобиль был закреплен за каким-то сотрудником. Наконец, если ме- няется значение столбца НомерЛицензии в таблице АВТОМОБИЛЬ, мы должны вы- полнить каскадное обновление одноименного столбца в таблице СОТРУДНИК. Это позволяет присваивать автомобилям новые номера лицензий, не нарушая огра- ничения ссылочной целостности и сохраняя существующие связи. Удаление строк со стороны таблицы СОТРУДНИК ограничено. Если за некото- рым сотрудником закреплен автомобиль, нельзя просто стереть запись об этом сотруднике из базы данных. Предварительно нужно удалить автомобиль или за- крепить его за другим сотрудником. Когда в таблицу СОТРУДНИК добавляется но- вая строка, внешнему ключу НомерЛицензии присваивается пустое значение. Это можно сделать потому, что сотрудник не обязан иметь автомобиль. Наконец, обновление столбца НомерЛицензии также ограничено. В данном случае «ограничено» не означает, что этот столбец вообще не может быть изменен. Если столбец имеет пустое значение, его можно изменить на действительный но- мер лицензии. Однако как только столбцу присваивается непустое значение, он становится недоступным для изменения, пока данный автомобиль не будет Удален из базы или назначен другому сотруднику. Эти правила необходимо до- кументально зафиксировать в схеме базы данных. Еще раз вдумчиво сравните схемы на рис. 5.11 и 5.12. Убедитесь, что вам понятно, почему столбец АВТОМОБИЛЬ.НомерЛицензии на рис. 5.11, б не может иметь пустое значение, в то время как столбец СОТРУДНИК.НомерЛицензии на Рис. 5.12, б — может. Уясните себе различия в процедурах обеспечения ссылоч- ной Целостности для рассмотренных двух схем. Если вы понимаете эти схемы значит, вы уже значительно продвинулись на пути к овладению навыками про- ектирования баз данных.
234 Глава 5. Проектирование баз данных Представление связей «один ко многим» Связи «один ко многим» представляются аналогично связям «один к одному» Однако теперь выбор родителя в связи уже не является произвольным Родите- лем всегда является та сущность, которая находится на одиночной стороне связи «один ко многим». На рис 5 13, а изображены три сущности с двумя связями 1N Здесь идет речь об отделах, сотрудниках и мебели. Отдел может вовсе не иметь мебели, а мо- жет иметь несколько предметов мебели; при этом каждый предмет мебели должен числиться ровно за одним отделом. Кроме того, в отделе может работать один или несколько сотрудников, а отдельно взятый сотрудник может (но не обязан) принадлежать к определенному отделу. ОТДЕЛ НазваниеОтдела БюджетныйКод НомерОфиса ПРЕДМЕТ_МЕБЕЛИ СерийныйНомер Тип Размер Материал ДатаПриобретения СОТРУДНИК НомерСотрудника ИмяСотрудника ДатаНайма ОТДЕЛ D:R U:C Ч НазваниеОтдела- NOT NULL LSD: ----- ПРЕДМЕТ-МЕБЕЛИ ЧСерийныйНомер: NOT NULL БюджетныйКод: NOT NULL НомерОфиса- NULL D:SN l:SD U:C D:R ; U:R ;P СОТРУДНИК Тип: NULL Размер: NULL Материал: NULL ДатаПриобретения NOT NULL (FK) Ч НомерСотрудника: NOT NULL ИмяСотрудника: NOT NULL ДатаНайма; NULL ДатаПриобретения NULL (FK) 6 Рис. 5.13. Два примера связи вида I N: a — модель IRpfiy- л модель lutbix, б — реляционная схема отношения?от^1^^СГпотомокМТак° 2Г ПерВИЧИЫЙ ключ родительского лицу СОТРУЛНИИ „ * droT же столбец мы помещаем в т 5- Ицу СОТРУДНИК. Обратите внимание, что в отношении ПРЕДМЕТ_МЕБЕЛИ столбец
Представление Своей 235 НазваниеОтдела помечен как обязательный (NOT NULL), поскольку каждый предмет мебели должен числиться за каким-го отделом. С другой стороны, в отношении СОТРУДНИК этот столбец является необязательным, так как сотрудник может и не принадлежать к какому-либо отделу. Рассмотрим теперь процедуры обеспечения ссылочной целостности Начнем со связи между таблицами ПРЕДМЕТ_МЕБЕЛИ и ОТДЕЛ. Вставка строк в таблицу ОТДЕЛ не требует никаких специальных процедур, поскольку отдел не обязан иметь мебель. Другое дело удаление: если за отделом числится какая-то мебель, запись о нем нельзя удалить из базы данных, поскольку, как говорилось выше, каждый предмет мебели должен принадлежать какому-то отделу. Наконец, когда меняется значение столбца НазваниеОтдела в таблице ОТДЕЛ, нужно распространить это изме- нение на одноименный столбец в таблице ПРЕДМЕТ_МЕБЕЛИ, произведя каскадное обновление. Когда новая строка вставляется в таблицу ПРЕДМЕТ_МЕБЕЛИ, соответствующий предмет мебели по умолчанию присваивается некоторому отделу, что обозначе- но на схеме правилом SD. Это необходимо, поскольку всякий предмет мебели должен числиться за каким-то отделом. В роли отдела по умолчанию, на который записывается вся вновь поступающая мебель, может выступать, например, склад. При обновлении и удалении строк в таблице ПРЕДМЕТ_МЕБЕЛИ никаких специ- альных действий предпринимать не нужно, поскольку отделы не обязаны иметь мебель. Перейдем теперь к рассмотрению второй связи на рис. 5.13,6. Здесь процедуры обеспечения ссылочной целостности более сложны, так как в этой связи имеется обязательный потомок. Начнем с родительской стороны связи. При удалении строки из таблицы ОТДЕЛ внешнему ключу СОТРУДНИК.НазваниеОтдела присваива- ется пустое значение. Это сделать можно, поскольку сотрудники не обязаны принадлежать к какому-либо отделу. При добавлении новой строки в таблицу ОТДЕЛ эту строку необходимо связать с одной из строк таблицы СОТРУДНИК, так как в любом отделе должен быть по меньшей мере один сотрудник*. Здесь про- цедура состоит в том, что во вновь созданный отдел по умолчанию записывается некоторый сотрудник. Для обработки этой ситуации необходимо написать триггер. Наконец, когда меняется значение столбца НазваниеОтдела в таблице ОТДЕЛ, нуж- но распространить это изменение на одноименный столбец в таблице СОТРУДНИК, произведя каскадное обновление. 1 еперь подойдем к этой связи с точки зрения таблицы СОТРУДНИК. При встав- ке строк в эту таблицу ничего предпринимать не требуется, поскольку сотрудни- ки не обязаны принадлежать к какому-либо отделу. Удаление строк из таблицы СОТРУДНИК ограничено: если строка содержит запись о последнем сотруднике ка- ко1 о-то отдела, в удалении этой строки следует отказать. В противном случае удаление разрешается. Это правило реализуется с помощью триггеров. Обновление столбца СОТРУДНИК.НазваниеОтдела ограничено по той же самом при- чине, что и удаление строк из таблицы СОТРУДНИК. Если данный сотрудник явля- ется последним в своем отделе, изменить название отдела для него будет нельзя. 1 вошпл ~ СИТуа,,ия- когда в базе дан"ых найдется ни одного сотрудника, к >т | бы ж отдм7^ГИл.Г„аКОМУ ТО °ТДеЛУ' Пос“у «"РУЛ""* "с может принадлежать более мем к одному у. ачевидио, что в этом случае во вставке строки следует отказать. - Примем перев.
236 Глава 5. Проектирование баз данные Представление связей вида N:M Кяк ™ vxe знаете из главы 2, связи вида N.M по-разному интерпретируются рас- ширенной моделью «сущность-связь» и моделью IDEF1X. В частности, моде ь IDEF1X называет связи вида N.M неспецифическими, склоняясь к той точке зрения что в действительности таких связей не существует. Согласно IDEF1X наличие связи N:M указывает только на то, что какая-то сущность была упущена из виду. В данном разделе мы рассмотрим это различие в интерпретациях более подробно. „ Прежде всего уясним себе суть проблемы. Предположим, у нас есть связь ви- да N M между сущностями АВТОР и КНИГА. Данная связь имеет вид N:M, посколь- ку один автор может написать множество книг, а книга может иметь множество авторов. Эта ситуация иллюстрируется данными на рис. 5.14, а. Линиями обо- значаются связи между экземплярами сущностей. Например, первый автор, по фамилии Джонс, написал книги с номерами 150 и 410. Если мы попытаемся использовать для представления этой связи ту же стра- тегию, что и для связей вида 1:N, мы столкнемся с трудностями. Диаграмма на рис. 5.14, б иллюстрирует попытку представить связь между сущностями АВТОР и КНИГА, поместив ключ отношения АВТОР в отношение КНИГА. Загвоздка состоит в том, что если автор у книги не один, то идентификатор второго автора помес- тить будет уже некуда. Например, во вторую строку таблицы КНИГА следовало бы поместить идентификаторы авторов Джонса и By, но для идентификатора By места уже нет, поскольку, согласно определению отношения, в каждой ячейке может быть только одно значение. Решение этой проблемы состоит в том, чтобы создать третью таблицу, назы- ваемую таблицей пересечения (intersection table), которая будет представлять связь конкретной книги с конкретным автором. На рис. 5.14, в показана таблица пересечения для данных, изображенных на рис. 5.14, а. Эта таблица содержит первичные ключи двух таблиц, имеющих связь N:M. На рис. 5.15, а показано представление связи N:M в модели IDEF1X, а на рис. 5.15, б - таблица пересече- ния (обозначенная здесь как АВТОР_Х_КНИГА). Таблицы пересечения всегда состоят из ключей двух таблиц, которые они свя- зывают. оэтому они всегда являются идентификационно-зависимыми и всегда имеют две идентификационно-зависимые связи, подобные тем, что показаны на ’ ' ’ ' Роме того' создание таблицы пересечения порождает два ограниче- ния ссылочной целостности. В случае рис. 5.15, б эти ограничения таковы. знаХТетр^ ДОЛЖНО сУ^ствовать среди ний^^ибута^НИГА.КВМ?^ Д°ЛЖН° сУ,цествовать среди значе- cTop°ot™eаНИе’ минимальн°5 кардинальное число связи со связи стпоки табпи гда Равпо • ак^ в любой идентификационно-зависимой будет смысла пересечения обязаны иметь родителей, иначе в них не
Представление семей 237 Таблица АВТОР Таблица КНИГА ИдАвтора Имя Прочие данные... ISBN Название Прочие данные , 10 Джонс 100 А 20 Смит 150 Б 30 By 300 В 40 Грин 410 Г Таблица АВТОР а Таблица КНИГА ИдАвтора Имя Прочие данные... ISBN Название Прочие данные... ИдАвтора 10 Джонс 100 А 20 20 Смит 150 Б 10? 30 By 300 В 40 Грин 410 Г Таблица АВТОР б Таблица КНИГА ИдАвтора Имя Прочие данные... ISBN Название Прочие данные... 10 Джонс 100 А 20 Смит 150 Б 30 By 300 В 40 Грин 410 Г Таблица пересечения ИдАвтора ISBN 10 150 10 410 20 100 30 150 30 410 40 300 е Рис. 6.14. Представление связей вида N:M: а — поимео связи иипа м м к реляционная схема; а - вариант с использованием таб^цы neof ем
238 Глава 5. Проектирование баз данных КНИГА а б Рис. 5.15. Пример связи вида N:M: а — неспецифическая связь; б — схема с использованием таблицы пересечения Рассмотрим теперь минимальное кардинальное число связи со стороны таб- лицы пересечения. Если для того, чтобы появиться в базе данных, автор дол- жен написать книгу, минимальное кардинальное число связи между таблицами АВТОР и АВТОР_Х_КНИГА со стороны последней должно равняться 1. Если книга должна иметь автора, то минимальное кардинальное число связи между табли- цами КНИГА и АВТОР_Х_КНИГА со стороны последней должно также равняться 1. На рис. 5.15, б индекс Р показывает, что книга должна иметь по меньшей мере одного автора, но автор не обязан иметь книгу. Процедуры обеспечения ссылочной целостности, показанные на рис. 5.15, б, элементарны. Рассмотрим сначала связь между таблицами АВТОР и АВТОР_Х_ КНИГА. Вставка строк в таблицу АВТОР не требует какой-либо специальной обра- ботки, а удаление строк и обновление столбца ИдАвтора должны инициировать соответственно каскадное удаление и каскадное обновление в таблице пересече- ния. Таблица пересечения не имеет ограничений на вставку, обновление и удале- ние строк, помимо стандартных правил обеспечения ссылочной целостности. Что касается связи между таблицами КНИГА и АВТОР_Х_КНИГА, то здесь тре- буются более сложные процедуры, поскольку КНИГА имеет обязательного по- томка. Во-первых, при удалении строк из таблицы КНИГА и обновлении столбца КНИГА.ISBN должны инициироваться соответственно каскадное удаление и кас- кадное обновление в таблице пересечения. Вставка строк в таблицу КНИГА огра- ничена, поскольку книга должна иметь по крайней мере одного автора. Чтобы
Представления связей 2Э9 гарантировать выполнение этого ограничения, необходимо написать соответ- ствующий трш гер. Вставка строк в таблицу пересечения в связи с таблицей КНИГА регулируется стандартными правилами обеспечения ссылочной целостности. Обновление и уда- ление ограничено, так как у книги должен быть по крайней мере один автор Таким образом, строка в таблице пересечения, представляющая единственного автора книги, не может быть обновлена или удалена. Итак, если у вас имеется связь вида N:M, преобразуйте ее в две идентифика- ционно-зависимые связи, создав таблицу пересечения. При этом появятся два ограничения ссылочной целостности. Как и во всех идентификационно-зависи- мых связях, потомок должен иметь обязательного родителя, поэтому минималь- ное кардинальное число с родительской стороны связи всегда равно единице. Минимальное кардинальное число со стороны потомка может равняться нулю, единице или более, в зависимости от системных требований. В соответствии с опи- санными ранее принципами необходимо определить процедуры обеспечения ссы- лочной целостности. Связи N:M, указывающие на недостающие сущности Как указывалось в главе 2, модель IDEF1X смотрит на связи вида N:M с подозре- нием. Согласно этой модели, насущная потребность в связи N:M указывает на не- достающую сущность. Рассмотрим, например, связь вида N:M между сущностя- ми АГЕНТ н ЗАКАЗ па рис. 5.16, а. В основе данной схемы лежит предположение, что ответственными за заказ могут быть один пли несколько торговых агентов. Эта модель подходит для команд, занимающихся крупными сделками, — напри- мер, продажей самолетов пли крупногабаритного медицинского оборудования. Таким образом, один агент может быть источником множества заказов, а один за- каз может быть заслугой нескольких агентов. Сущность ЗАКАЗ имеет атрибут ВсегоКомиссионных. Наличие этого атрибута подсказывает нам вопрос: как будут делиться комиссионные? Этот вопрос, в свою очередь, приводит пас к модели, изображенной на рис. 5.16, б. Обратите внимание, что это именно модель данных, а не реляционная схема. Здесь введена сущ- ность ДОЛЯ_АГЕНТА, являющаяся идентификационно-зависимой как от сущно- ciii АГЕНТ, так н от сущности ЗАКАЗ. Атрибут ДОЛЯ_АГЕНТА.ПроцентКомиссионных представляет процент, который получает конкретный агент от конкретной сдел- ки. Реляционная структура для этой модели изображена на рис. 5.16, в. 1 сверь сравните рис. 5.15, б и рис. 5.16, в. Единственное различие между ни- ми (ос 1онт в том, что сущность ДОЛЯ-АГЕНТА имеет неключевой атрибут, а сущ- ность АВТОР_Х_КНИГА - нет. В остальных отношениях эти структуры идентичны. Поэтому средства проектирования, базирующиеся на модели IDEF1X, побуждают разработчика избавляться от связей вида N:M путем создания промежуточных идентификационно-зависимых сущностей. Вот и причина, по которой в IDEF1X связи вида N M называются «неспецифнческими»: имеется в виду, что они еще не преобразованы в две идентификационно-зависимые связи.
240 Глава 5. Проектирование баз данных АГЕНТ ЗАКАЗ а АГЕНТ ЗАКАЗ ДОЛЯ.АГЕНТА ПроцентКомиссионных АГЕНТ ЗАКАЗ Рис. 5.16. Связь вида N'M б — модель, включающая в с недостающей сущностью: а — неспецифическая связь; недостающую сущность; а — схема без использования таблицы пересечения Если, как в случае с сущностями АВТОР и КНИГА, не существует такого неклю- чевого атрибута, который могла бы нести в себе промежуточная сущность, то сторонники модели IDEF1X скажут: «Нет проблем! Просто введите промежуточ- ную сущность, являющуюся идентификационно-зависимой от сущностей АВТОР и КНИГА и не имеющую неключевых атрибутов».. Как видите, по сути это эквива- лентно созданию таблицы пересечения, поэтому решение здесь точно такое же,
Представление связей 241 как и в расширенной модели «сущность-связь», только сформулировано други- ми словами. , Итак, модель IDEF1X смотрит на связи вида N:M скептически и предлагает разработчику задаться вопросом, не пропущена ли в схеме некая связующая сущ- ность Если да, то такая сущность будет идентификационно-зависимой от обоих своих родителей. Если нет, такую сущность следует ввести, пусть даже она не будет иметь неключевых атрибутов. Какой бы модели вы ни придерживались — расширенной модели «сущность связь» или модели IDEF1X, — в конечном счете решение все равно будет одним и тем же. Можно утверждать, что связи вида N:M существуют, и представлять их как таковые в модели данных, а на этапе проектирования создавать таблицы пересечения. Можно, напротив, утверждать, что таких связей не бывает, и для каждой из этих ги- потетических связей искать пропущенную сущность, а если таковой не обнаружится, принудительно вводить промежуточную сущность, являющуюся идентификацион- но-зависимой от обоих родителей. Вне зависимости от того, какую позицию вы вы- берете, в конце концов вы придете к одному и тому же набору отношения и связей. Некоторые считают, что подход IDEF1X лучше, поскольку он заставляет раз- работчика еще раз подумать о возможном наличии связующей сущности. По мнению других, хороший разработчик сделает это и так, без всякого принужде- ния. Решите сами, какая точка зрения представляется вам более верной. Представление подтипов и категориальных связей Прежде чем мы начнем обсуждать представление подтипов и категорий, полезно будет освежить в памяти материал главы 2, посвященный этим разновидностям сущностей. Подтипы и надтипы в расширенной модели «сущность—связь» пред- ставляют собой более общие понятия, чем порождающие и категориальные сущ- ности в модели IDEF1X. Поэтому если вы знаете, как представляются порож- дающие и категориальные сущности, то изучение представления более простых вещей, таких как подтипы и надтипы в расширенной модели «сущность—связь», не составит для вас труда. Соответственно, в этом разделе мы сосредоточимся главным образом на понятиях модели IDEF1X. Подтипы, надтипы, порождающие сущности и сущности-категории Как говорилось в главе 2, подтипы — это сущности, являющиеся разновидностями ЛОМА?1*1 другой СУЩНОС™> называемой надтипом. Например, общему понятию dlicu* *1ЕЕ—ЖИВОТНОЕ могут отвечать такие разновидности, как АКВАРИУМНАЯ vmS’ К0ШКА- Здесь Д°мАШНЕЕ_ЖИВОТНОЕ - это надтип, а АКВАРИ- УМНАЯ_РЫБКА, СОБАКА и КОШКА - подтипы. МоД<щь_IDEF1X развивает эту идею, вводя понятие категориального кластера Сущность rowSi? ЧаСТЬ ДНарраммЬ1 модели IDEF1X- разработанной в главе 2. ои^ СОТРУДНИК является порождающей сущностью и имеет два катего- а кластера. В одном из них находятся сущности МЕНЕДЖЕР и ПЕРСОНАЛ а в другом - ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ.ПИСАТЕЛЬ. "^СОНАЛ,
242 Глава 5. Проектирование баз данных МЕНЕДЖЕР ПЕРСОНАЛ КодУровня ПочасоваяСтавка ПоследняяПремия ДниОтпуска СОТРУДНИК ТабельныйНомер Имя Телефон КодДолжности ПРОГРАММИСТ ТЕСТЕР ТЕХНИЧЕСКИЙЛИСАТЕЛЬ Титул ЯзыкПрограммирования ОперационнаяСистема ОпытРаботы ОпытРаботы Язык СОТРУДНИК ^ТабельныйНомер Имя Телефон КодДолжности МЕНЕДЖЕР ПЕРСОНАЛ ПРОГРАММИСТ ТЕСТЕР ТЕХНИЧЕСКИЙJlMQATETIb ЧТабельный- Номер (FK) ЧТабельный- Номер (FK) КодУровня ПоследняяПремия ПочасоваяСтавка ДниОтпуска «ЧТабельный- Номер (FK) ЧТабельный- Номер (FK) ЧТабельный- Номер (FK) Титул ЯзыкПрограммирования ОперационнаяСистема ОпытРаботы ОпытРаботы Язык СОТРУДНИК Рис. 5.17. Представление категорий а - модель с двумя категориальными кластерами, б - внешние ключи в таблицах, представляющих категории; в - процедуры обеспечения ссылочной целостности
Представление свяжи 243 В терминах расширенной модели «сущность—связь» СОТРУДНИК является над- типом, а МЕНЕДЖЕР, ПЕРСОНАЛ, ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ_ПИСАТЕЛЬ подтипами. Но модель 1DEF1X вводит не только понятие категориального кла- ло и ограничение, что сущности, принадлежащие к одному категориальному кластеру, являются взаимоисключающими. Так, например, сотрудник может отно- ситься либо к менеджерам, либо к персоналу, но не к тем и другим одновременно В IDEF1X категориальные кластеры могут быть полными или неполными. Полный категориальный кластер содержит все возможные типы сущностей для данного кластера. В неполном категориальном кластере отсутствует по меньшей мере один из возможных типов, то есть имеется вероятность, что порождающая сущность не будет принадлежать ни к одному из перечисленных типов. Согласно рис. 5.17, а, кластер МЕНЕДЖЕР/ПЕРСОНАЛ является неполным (обо- значается одиночной линией под кружком, символизирующим кластер), то есть некоторые сотрудники не относятся ни к менеджерам, ни к персоналу. Это могут быть, например, те, кто работает на неполную ставку. Второй кластер является полным (обозначается двойной линией под кружком, символизирующим кластер). Следовательно, сотрудник должен быть либо программистом, либо тестером, ли- бо техническим писателем. Наконец, некоторые кластеры имеют дискриминатор — атрибут порождающей сущности, определяющий, к какой категории относится порождающая сущность. На рис. 5.17 атрибут КодДолжности позволяет определить, кем является сотруд- ник — программистом, тестером или техническим писателем. Модель не говорит нам, как для этого следует интерпретировать значения атрибута КодДолжности; она просто указывает, что такое различение возможно. Представление сущностей-категорий Зная все вышесказанное, нетрудно понять, как должны представляться сущно- сти-категории в модели данных. Каждую категорию следует представить в виде таблицы, первичный ключ которой будет совпадать с первичным ключом порож- дающей сущности. Таким образом, первичный ключ категории будет одновре- менно и внешним ключом. Следует также ввести ограничения ссылочной целост- ности, гарантирующие, что значения ключей таблиц, представляющих сущности- категории, присутствуют среди значений ключа порождающей сущности. На рис. 5.17, б показана реляционная схема для модели данных на рис. 5.17, а. В ней ТабельныйНомер, первичный ключ таблицы СОТРУДНИК, помещен в качестве первичного ключа в каждую из таблиц, представляющих сущности-категории. 06- ратите внимание, что атрибут ТабельныйНомер помещен в сегмент первичного ключа лиц, представляющих категории, и при этом еще помечен как внешний ключ. Для этой схемы будут иметь место следующие ограничения ссылочной цело- стности. Значение атрибута МЕНЕДЖЕР.ТабельныйНомер должно существовать среди значений атрибута СОТРУДНИК.ТабельныйНомер. Значение атрибута ПЕРСОНАЛ.ТабельныйНомер должно существовать среди значений атрибута СОТРУДНИК.ТабельныйНомер. Значение атрибута ПРОГРАММИСТ.ТабельныйНомер должно существовать сре- ди значений атрибута СОТРУДНИК.ТабельныйНомер.
244 Глава 5. Проектирование баз данных Значение атрибута ТЕСТЕР.ТабельныйНомер должно существовать среди зна- чений атрибута СОТРУДНИК.ТабельныйНомер. Значение атрибута ТЕХНИЧЕСКИЙ_ПИСАТЕЛЬ.ТабельныйНомер должно суще- ствовать среди значений атрибута СОТРУДНИК.ТабельныйНомер Для представления подтипов используется аналогичная стратегия. Процедуры обеспечения ссылочной целостности На рис. 5.17, в указаны процедуры обеспечения ссылочной целостности для каждой из категориальных связей. Во всех случаях обновление и удаление строк в таблице СОТРУДНИК должны инициировать соответственно каскадное обновление и удале- ние в дочерних таблицах. Это имеет смысл, поскольку если меняется табельный номер сотрудника, данное изменение должно распространиться и на все катего- рии этого сотрудника. Аналогичным образом, если сотрудник удаляется из базы данных, все категории этого сотрудника должны быть также удалены. Вставка строк в таблицы, представляющие сущности-категории, всегда огра- ничена. Поскольку категории внутри одного кластера являются взаимоисклю- чающими, во вставке строки следует отказать, если порождающая сущность уже представлена одной из категорий данного кластера. Это означает, например, что прежде чем вставить строку в таблицу МЕНЕДЖЕР, нужно сначала убедиться, что о соответствующем сотруднике нет записи в таблице ПЕРСОНАЛ. Если такая за- пись имеется, то чтобы вставить строку в таблицу МЕНЕДЖЕР, нужно будет спер- ва удалить строку из таблицы ПЕРСОНАЛ. Согласно рис. 5.17, в, обновление категориальных кластеров также ограничено. На самом деле значение атрибута ТабельныйНомер в таблице, представляющей категорию, меняться вообще не должно. Иначе может получиться, например, что запись, относившаяся к сотруднику по фамилии Джонс, вдруг стала принадле- жать Смиту. Это неразумно, и такое обновление следует запретить. Наконец, удаление строк из таблиц ПРОГРАММИСТ, ТЕСТЕР и ТЕХНИЧЕСКИЙ. ПИСАТЕЛЬ также ограничено. Это обусловлено тем, что кластер, к которому отно- сятся эти категории, является полным, и, следовательно, сотрудник обязан при- надлежать к одному из этих трех типов. Удаление строки может быть разрешено только в случае одновременной вставки строки в таблицу другой категории - например, когда сотрудник из тестера становится программистом. Наконец, по- <™r2vniJMiz>ni к^астеР является полным, при добавлении новой строки в табли- УтгхмиЛгчый ±?ДИМО вставить строку в одну из таблиц ПРОГРАММИСТ, ТЕСТЕР ТЕХНИЧЕСКИИ.ПИСАТЕЛЬ. Это не указано на рис. 5.17, б, но это необходимо. Представление слабых, но не идентификационно-зависимых сущностей Расширенная модель «сущность-связь» допускает существование слабых сущ- ностей, не являющихся идентификационно-зависимыми. Такие сущности логи-
Предст в связей 24S чески зависят от существования в базе данных некоторой другой сущности. Поимером может служить сущность ПОДЧИНЕННЫЙ, хранящая данные о под- чиненных сотрудника. В этом случае сущность СОТРУДНИК имеет с сущностью ПОДЧИНЕННЫЙ связь вида 1:N, и строка в таблице ПОДЧИНЕННЫЙ может существо- вать, только будучи связанной с какой-то строкой в таблице СОТРУДНИК. Такого рода связи представляются точно так же, как и любые связи вида 1:N, но требуют определенных процедур обеспечения ссылочной целостности. Рассмот- рим реляционную схему на рис. 5.18. Здесь внешний ключ таблицы СОТРУДНИК — ТабельныйНомер - помещен в таблицу ПОДЧИНЕННЫЙ, что породило следующее ограничение ссылочной целостности. Значение атрибута ПОДЧИНЕННЫЙ.ТабельныйНомер должно существовать среди значений атрибута СОТРУДНИК.ТабельныйНомер. СОТРУДНИК ПОДЧИНЕННЫЙ \ НомерСотрудника: NOT NULL D:C U:C «^ТабельныйНомер: NOT NULL ИмяСотрудника: NOT NULL ДатаНайма: NULL НазваниеОтдела: NULL (FK) Имя: NULL ДатаРотедения: NULL Связь: NULL НомерСотрудника: NOT NULL (FK) Рис. 5.18. Слабые сущности, не являющиеся идентификационно-зависимыми Поскольку для существования подчиненного логически необходимо наличие сотрудника, который являлся бы его начальником, удаление и обновление строк в таблице СОТРУДНИК должно вызывать соответственно каскадное удаление и об- новление в таблице ПОДЧИНЕННЫЙ. Фактически эти две процедуры являются обя- зательными для родителей таких слабых сущностей. Кроме того, эти сущности всегда имеют обязательный (NOT NULL) внешний ключ. Ввиду сформулированно- го выше ограничения ссылочной целостности, вставка строк и обновление значе- ния внешнего ключа будут ограничены только существующими сотрудниками, поэтому никаких дополнительных процедур обеспечения ссылочной целостно- сти в данном случае не требуется. В остальном, как уже отмечалось, представление такого рода связей ничем не отличается от представления любых других связей вида 1:N. Примеры связей в rnTZ ?аЗДеЛе будут РассМотРены три примера, которые обсуждались ранее о *Лс1ВС Z. г Вложенные идентификационно-зависимые связи счетом (см19п“с1О3К73аДа R°f Да"НЫХ ДЛЯ ТреТЬеГ° Прнмера с Циничным
246 Глава 5. Проектирование баз данных.......—---------------------- , .„«.ши сущностями, связанными лру< с другом как ро идентификационно-зависимыми сущ дитель и потомок. ГОСТИНИЧНЫЙ СЧЕТ I НомерСчета СЛОЖНАЯ СТРОКА РАСХОДОВ ДатаНачисления КатегорияРасходов ____ ВсегоПоКатегории ПОДСТРОКА_РАСХОДОВ ( ""Ч Подкатегория ' Сумма датаПоселения ИмяКлиента Итого ПОДСТРОКА РАСХОДОВ Ч ДатаНачисления Ч КатегорияРасходов ” Ч НомерСчета Ч Подкатегория (Сумма б Рис. 5.19. Вложенные идентификационно-зависимые сущности: а — модель данных; б — реляционная схема Чтобы представить каждую из этих идентификационно-зависимых связей, мы помещаем ключ родителя в потомка. Этот ключ будет одновременно и внешним ключом, и частью первичного ключа потомка. Ключ таблицы, представляющей вложенную идентификационно-зависимую сущность, будет содержать ключ ее ро- дителя, который, в свою очередь, будет содержать ключ прародителя (рис. 5.19,б). Обратите внимание, что как удаление, так и обновление родителей должно рас- пространяться на потомков, что и свойственно идентификационно-зависимым связям. Тот же процесс будет иметь место и при более глубокой вложенности идентификационно-зависимых сущностей. Принимая во внимание размер ключей вложенных таблиц, ясно, что схему можно было бы улучшить, используя суррогатные ключи. Несколько связей между одними и теми же двумя сущностями На рис. 5.20, а изображена модель данных для второго примера со студентами и общежитиями (см. рис. 3.9, б). Здесь между сущностями ОБЩЕЖИТИЕ и СТУДЕНТ имеются две связи, одна из которых описывает проживание студента в общежи- тии (связь _Проживание_), а другая — работу студента в качестве ассистента по общежитию (связь _ДолжностьАссистента_). При этом студент может проживать в одном общежитии, а работать ассистентом в другом. Каждая из этих связей представляется своим собственным внешним ключом, как показано на рис. 5.20, б. Внешним ключом в связи _Проживание_ является атрибут ОбщежитиеПроживания. а в связи _ДолжностьАссистента_ - атрибут РаботаАссистентом.
Представление связей 247 общежитие НазваниеОбщежития >- Телефон _Проживание_ _ДолжностьАссистента_ СТУДЕНТ 1 НомерСтудента р ИмяСтудента Специализация Руководитель Курс Школа ПредыдущийКолледж МестныйАдрес МестныйТелефон а ОБЩЕЖИТИЕ D:SN D:R LSD l:SN U:C _ДолжностьАссистента U:R О . „ 1 -Проживание.-, D:SN D:Rp l:SD l:SN U:C U:R СТУДЕНТ «(НазваниеОбщежития НомерСтудента ИмяСтудента Специализация Руководитель Курс Школа ПредыдущийКолледж МестныйАдрес МестныйТелефон ОбщежитиеГдеПроживает (FK) ОбщежитиеГдеАссистирует (FK) б Рис. 5.20. Две связи между двумя сущностями: а — модель данных; б — реляционная схема Обозначенные на диаграмме процедуры обеспечения ссылочной целостности типичны для связей с обязательным потомком. Специфика заключается лишь в том, что связь _ДолжностьАссистента_ имеет вид 1:1, а связь _Проживание_ — 1:N, поэтому процедуры для этих связей будут несколько различаться. Например, в первой связи удаление строки из таблицы СТУДЕНТ не допускается ни при ка- ких условиях, а во второй связи могут быть удалены все дочерние строки, кроме последней. Реляционная схема для базы данных университета Highline На рис. 5.21, а показан окончательный вид модели данных университета Highline, о котором шла речь в главе 3 (рис. 3.23). Реляционная схема, изображенная на рис. 5.21, б, является результатом непосредственного применения принципов проектирования, описанных в этой главе. Как таблица КАФЕДРА, так и таблица СТУДЕНТ имеют несколько внешних клю- чей. В таблице КАФЕДРА внешний ключ НазваниеКолледжа указывает на таблицу КОЛЛЕДЖ, а внешний ключ {ИмяПреподавателя, ФамилияПреподавателя} указывает на таблицу ПРЕПОДАВАТЕЛЬ. Этот последний ключ относится к связи _3аведова- ние- и должен быть помечен как АК1.1 (не показано на рисунке).
248 Глава 5. Проектирование баз данных КОЛЛЕДЖ НазваниеКолледжа ИмяДекана ФамилияДекана Телефон Корпус Комната_________ КАФЕДРА НазваниеКафедры Телефон ЧислоСтудентоа Корпус Комната СТУДЕНТ L НомерСтудента Обращение ИмяСтудента ФамилияСтудента ДомАдрДом ДомАдрУлица ДомАдрГород ДомАдрШтат ДомАдрИндекс Телефон_________ ПРЕПОДАВАТЕЛЬ а _3ааедование_ КОЛЛЕДЖ КАФЕДРА ПРЕПОДАВАТЕЛЬ -Специализация ___________СТУДЕНТ i ___________НомерСтудента_______ Обращение ИмяСтудента ФамилияСтудента ДомАдрДом ДомАдрУлица ДомАдрГород ДомАдрШтат ДомАдрИндекс Телефон НазваниеПрофильнойКафедры (FK) НазваниеКафедрыРуководителя (FK) ИмяПреподавателя (FK) ФамилияПреподавателя (FK) ’^НазваниеКафедры ИмяПреподавателя ^ФамилияПреподавателя Звание ^Условия ————— ___________J _Руководство_ б Рис. 5.21. База данных университета Highline: а - модель данных; о — реляционная схема
Особые ситуации 24% В таблице СТУДЕНТ атрибут НазваниеПрофильнойКафедры является внешним ключом для связи „Специализация.. Атрибут НазваниеКафедрыРуководителя явля- ется частью ключа таблицы ДОЛЖНОСТЬ, с помощью которой представляется связь „Руководство.. Кроме него, в этот внешний ключ входят атрибуты ИмяПре- подавателя и ФамилияПреподавателя. Процедуры обеспечения ссылочной целостности для данной схемы также являются результатом непосредственного применения идей, изложенных в этой главе Особые ситуации В завершение этой главы мы рассмотрим три особые ситуации: рекурсивные связи, тернарные связи с бинарными ограничениями и неоднозначность пустых значений. Представление рекурсивных связей Рекурсивная связь (recursive relationship) — это связь между сущностями одного и того же класса. Рекурсивные связи не имеют фундаментальных отличий от дру- гих связей принадлежности и могут быть представлены с помощью тех же самых приемов. Как и прочие связи принадлежности, рекурсивные связи могут быть трех видов: 1:1, 1:N и N:M. На рис. 5.22 приведены примеры каждой из разновид- ностей рекурсивных связей. ЧЕЛОВЕК ИмяЧеловека КЛИЕНТ НомерКлиента -----—------- ! ВРАЧ .Лечение. „Спонсорство. .ПриводКлиента. Рис. В.22. Примеры рекурсивных связей Рассмотрим сначала связь „Спонсорство, на рис. 5.22. Это связь вида 1:1, при которой один человек может спонсировать другого, и у любого человека может быть максимум один спонсор. Данные для этого примера приведены на рис. 5.23, а. Для представления рекурсивной связи вида 1:1 применяется подход, почти идентичный тому, который использовался для обычных связей вида 1:1: можно поместить ключ спонсируемого лица в строку спонсора, а можно поместить ключ спонсора в строку спонсируемого лица. На рис. 5.23, б показан первый вариант, а на рис. 5.23, в — второй. Оба варианта работают, поэтому выбор опре- деляется соображениями производительности. Поскольку связь имеет вид 1.1, внешний ключ должен быть определен как уникальный. Данный способ идентичен тому, который применялся для нерекурсивных свя- вида 1:1, за тем исключением, что родительская и дочерняя строки находятся
250 Глава 5. Проектирование баз данных в одном и том же отношении. Можно представить себе данный процесс следу, ютим образом: вообразим, что связь сущесшует между двумя разными отноше- ниями, определим, что является ключом, и объединим два отношения в одно. Человек Джонс Смит Миртл Пайне а Отношение ЧЕЛОВЕК1 Человек СпонсируемоеЛицо Джонс Смит Смит Паркс Паркс null Миртл Пайне Пайне null Ограничение ссылочной целостности: Значение атрибута СпонсируемоеЛицо должно существовать среди значений атрибута Человек б Отношение ЧЕЛ0ВЕК2 Человек Спонсор Джонс null Смит Джонс Паркс Смит Миртл null Пайне Миртл Ограничение ссылочной целостности: Значение атрибута Спонсор должно существовать среди значений атрибута Человек в ™<прйм'сХ™ХЗлХт?’“Гр“сЛ<5 24 рекурсивных связей вида 1:N, рас- заны на рис. 5.24, а. В таблице КЛИЕНТ Л' 5'24’ Данные для этого пРимера пока‘ водящего клиентов (она играет по/ "3 СТР°К представляет человека, при- представляют приведенных клиенте родительскои строки), а другие строки представления этой связи как и лля ni°H“ Играют роль Дочерних строк). Для ’ для всех связей вида 1:N, мы помещаем ключ
Особые ситуации 2S1 родителя в отношение-потомок. На рис. 5.24, б мы помещаем идентификатор человека, приводящего клиентов, в строки всех приведенных им клиентов Рассмотрим теперь рекурсивные связи M:N. Связь _Лечение_ на рис. 5 25 описывает ситуацию, в которой врачи лечат друг друга. Данные для этого при- мера приведены на рис. 5.25, а. Как и для других связей N.M, нам необходимо создать таблицу пересечения, в которой будут показаны связанные между собой пары строк. В первом столбце находится имя того, кто лечит, а во втором — имя того, кто лечится. Эта структура изображена на рис. 5.25, б. Клиент номер Привел следующих клиентов 100 200,400 300 500 400 600,700 а НомерКлиента ДанныеКлиента КемПриведен 100 null 200 100 300 null 400 100 500 300 600 400 700 ... 400 Ограничение ссылочной целостности: Значение атрибута КемПриведен должно существовать среди значений атрибута НомерКлиента б Рис. 5.24. Пример рекурсивной связи вида 1 :N: а — данные для связи _ПриводКлиента_; б — представление связи с помощью отношения Таким образом, рекурсивные связи представляются точно так же, как и дру- гие типы связей. Однако строки таблиц могут при этом играть две различные ро- ли. Одни являются родительскими, другие — дочерними. Если ключ является ссылкой на родителя, а строка не имеет родителя, его значение будет пустым. Если ключ является ссылкой на потомка, а строка не имеет потомка, его значе- ние также будет пустым. Представление тернарных связей и связей высших порядков Для представления тернарных связей (ternary relationships) используются те же методы, но зачастую эти связи порождают особые ограничения, которые необ- ходимо документально зафиксировать в виде положений делового регламента.
252 Глава 5- Проектированиебазданных Рассмотрим, например, сущности ЗАКАЗ, КЛИЕНТ и АПНТ Н большинстве г*Учвев мы можем относиться к этой тернарной сияли как к двум бинарным □жвыщикусгуг □«Шлегели услуг Джонс Смит Паркс Смит Абернати Франклин Абернати Джонс Франклин Отношение ВРАЧ Имя Прочиа атрибуты Джонс Паркс Смит Абернати О'Лири Франклин ... Отношение ЛЕЧЕНИЕ_ПРСЧ Врач Пациент Джонс Смит Паркс Смит Смит Абернати Абернати Джонс Паркс Франклин Франклин Абернати Джонс Абернати Ограничения ссылочной целостности: Значение атрибута Врач в отношении ЛЕЧЕНИЕ_ПРСЧ должно существовать среди значений атрибута Имя а отношении ВРАЧ Значение атрибута Пациент в отношении ЛЕЧЕНИЕ_ПРСЧ должно существовать среди значений атрибута Имя а отношении ВРАЧ б Рис. 5.25. Пример рекурсивной связи вида M-.N: а — данные для связи _Лечение_: б — представление связи с помощью отношений Допустим, что заказ всегда делается одним клиентом, но один и тот же ент может делать много заказов. Следовательно, бинарная связь между сушно* стями ЗАКАЗ и КЛИЕНТ имеет вид N:l. Аналогичным образом, предположим, что заказ может выполняться только одним агентом, но один и тот же агент мо*сТ
Особые ситуации 253 выполнять много заказов. Исходя из этого, бинарная связь между сущностями ЗАКАЗ и АГЕНТ также имеет вид N:l. Обе эти связи могут быть представлены с использованием подходов, описан- ных в этой главе. Первую связь мы представим, поместив ключ отношения КЛИЕНТ в отношение ЗАКАЗ, а вторую — поместив туда же ключ отношения АГЕНТ. Таким образом, мы построили тернарную связь между сущностями ЗАКАЗ, КЛИЕНТ и АГЕНТ в виде двух самостоятельных бинарных связей. Допустим теперь, что имеется правило, согласно которому конкретный поку- патель может размещать заказы только у одного агента. В этом случае тернарная связь ЗАКАЗ:КЛИЕНТ:АГЕНТ ограничивается дополнительной бинарной связью ви- да N:1 между сущностями КЛИЕНТ и АГЕНТ. Чтобы представить данное ограниче- ние, нам необходимо поместить ключ отношения СЛУЖАЩИЙ в отношение АГЕНТ Получившиеся три отношения будут выглядеть следующим образом. ЗАКАЗ (НомерЗаказа, неключевые атрибуты, НомерКлиента, НомерАгента) КЛИЕНТ (НомерКлиента, неключевые атрибуты, НомерАгента) АГЕНТ (НомерАгента. неключевые атрибуты) Таблица АГЕНТ НомерАгента Прочие неключевые данные 10 20 30 Таблица КЛИЕНТ НомерКлиента Прочие неключевые данные НомерАгента 1000 10 2000 20 3000 30 Бинарное ограничение «ДОЛЖНО БЫТЬ» Таблица ЗАКАЗ НомерЗаказа Прочие неключевые данные НомерАгента НомерКлиента 100 10 1000 200 20 2000 300 10 1000 400 30 3000 500 2000 Здесь разрешено только значение 20 Рис. 5.26. Пример бинарного ограничения на тернарную связь «ДОЛЖНО БЫТЬ»
254 Глава 5- Проектирование баз данных Ограничение, в соответствии с которым заказы для конкретного клиента мо жет выполнять только определенный aiein, означает, что и отношении ЗАКАЗ допускаются только определенные сочетания значений атрибутов Но-ерКвиемтл н НомерАгента. К сожалению, нет способа выразить но ограничение в терминах реляционной модели. Тем не менее, его необходимо документально зафикедрр. вать в проекте, а реализация его должна обеспечиваться [риги-рами или при- кладнымп программами (.рис. 5.26). Таблица ЛЕКАРСТВО Hwi Лекарства Прочие неключеаыа данные 10 20 30 45 70 90 Таблица АЛЛЕРГИЯ НомерКлиента НомерЛекарства Прочие неключевые данные 1000 10 1000 20 2000 20 2000 45 3000 30 3000 45 3000 70 Бинарное ограничение «НЕ ДОЛЖНО БЫТЬ» Таблица РЕЦЕПТ НомерРрцепта Прочие неключевые данные НомерЛекарства НомерКлиента 100 45 1000 200 10 2000 300 70 1000 400 20 3000 500 2000 Здесь не могут появиться значения 20 или 45 5 27. Пример бинарного ограничения на тернарную связь «НЕ ДОЛЖНО БЫТЬ»
Особые ситуации 265 Кроме того, существуют такие типы бинарных ограничений как «НЕ ДОЛЖНО БЫТЬ» и «ДОЛЖНО ВКЛЮЧАТЬ». Ограничение «НЕ ДОЛЖНО БЫТЬ» — это бинарная связь, указывающая комбинации, которые недопустимы в тернар ной связи. Например, на тернарную связь РЕЦЕПТ:ЛЕКАРСТВО:КЛИЕНТ может быть наложено ограничение в виде таблицы АЛЛЕРГИЯ, где указаны лекарства, кото- рые покупателю не разрешается принимать (рис. 5.27). Таблица РЕМОНТ Нсми?Рамонта Прочие неключевые данные 10 20 30 45 Таблица РАБОТА НсмеоРа’ т> Прочие неключевые данные НомерРемонта 1001 10 1002 10 1003 10 2001 20 2002 20 3001 30 4001 40 Бинарное ограничение «ДОЛЖНО ВКЛЮЧАТЬ» Таблица АВТОМОБИЛЬ—РЕМОНТ НймавСнатя НомерРемонта НомерКлиента Прочие неключевые данные 100 10 1001 200 10 1002 300 10 1003 400 20 2001 500 20 Здесь должно появиться 2002 —х Рис. 5.28. Пример бинарного ограничения на тернарную связь «ДОЛЖНО ВКЛЮЧАТЬ' Ограничение «ДОЛЖНО ВКЛЮЧАТЬ» — это бинарная связь, указываю- щая все комбинации, которые должны присутствовать в тернарной связи. Рас- смотрим, например, связь АВТОМОБИЛЬ:РЕМОНТ:РАБОТА. Пускай ремонт включает в себя определенное количество работ, каждая из которых должна быть вы- полнена, чтобы ремонт был успешным В этом случае, если выполняется ремонт
256 Глава 5. Проектирование_баз данных АВТОМОБИЛЬ—РЕМОНТ должны фигурировать все автомобиля, то в отношен. и А та (рис. 5.28). работы, выполняемые Р< ограиичений, описанных здесь, не может Нп одни из трез '“„иной модели. Вее связи должны релиз», быть представлен в теРм J ' связей. Однако ограничения должны быть документ^н^зафиксировань! в схеме базы данных и реализованы в триггерах пли прикладных программах. Пустые значения Атрибут имеет пустое значение (null value), если ему не было присвоено никакое значение Проблема с пустыми значениями состоит в том, что они допускают множество толкований. Пустое значение может означать, что: а) значение атрибута неизвестно; б) атрибут в данном случае неприменим; в) значение атрибута не опре- делено. Рассмотрим, например, атрибут ДатаСмерти в отношении КЛИЕНТ. Что озна- чает пустое значение этого атрибута? Возможно, пользователи не знают, жив клиент или нет; возможно, клиент является корпоративным, и данный атрибут к нему неприменим; наконец, возможно, что клиент является физическим лицом, и он жив. Есть несколько способов устранения этой неоднозначности. Первый способ заключается в том, чтобы не допускать появления пустых значений. Определите атрибут как обязательный. Это работает отлично, если в представлении пользо- вателей атрибут действительно является обязательным. Однако пользователей может раздражать необходимость указывать, например, значение атрибута Люби- мыйЦветПокупателя, если этот атрибут не представляет важности для их работы. В главе 3 мы узнали способ избежать появления пустых значений там, где атри- бут является неприменимым, — введение подтипов. Введение сущностей ПАЦИЕНТ- МУЖЧИНА и ПАЦИЕНТ-ЖЕНЩИНА в качестве подтипов сущности ПАЦИЕНТ избавит пациента мужского пола от необходимости указывать количество беременно- стей, а пациентов женского пола — от вопросов о состоянии предстательной же- лезы, например. Однако это решение является дорогим — в том смысле, что оно 1 pe6yei введения двух новых таблиц, и чтобы получить данные обо всех пациен- тах, понадобится соединять эти таблицы. Еще одно решение заключается в том, чтобы присваивать каждому атрибуту начальное значение, которое интерпретировалось бы как неопределенное. Напри- прпои^КСТт-В0М^ атри^УтУ может быть присвоено начальное значение «(не опре- тю чгпХ пИ В Некот°Р°й ситуации данный атрибут не будет иметь смысла, будет более присвоить емУ значение «(неприменимо)». Данный подход кюр,,анты выбора для текстов! TY ' а а 2’ к сожалению, это решение годится только нетекстовыми атоиб™т*мВ’ а пр°^лема с числовыми, логическими и другими делируя эти атпибуты И 0Стается- Разумеется, можно выйти из положения, мо- xXof: "«»» <•«« з»™»™» ственную nDone-rvnv n₽ в Этом слУчае вам придется писать coo в—га»з»™руег. ЧРТО и таблицу 6у^ преобразовывать эти данные к соответ™ ТаКЖе придется программным путем над ними арифметические операции У ™ПУ’ ПреЖДе WM проИЗВОД
Резюме 257 Иногда лучшее решение —- не делать ничего с пустыми значениями. Если пользователи могут смириться с неоднозначностью или если решение требует больше затрат, чем приносит выгоды, просто зафиксируйте факт существования проблемы. Обратитесь также к следующей главе, где вы найдете более подроб- ную информацию о последствиях, вызываемых наличием пустых значений при выполнении операций соединения. Резюме Модель данных и другие системные требования являются исходной точкой для создания реляционной схемы базы данных. Каждая сущность в модели преобра- зуется в отношение. Атрибуты сущности становятся столбцами таблицы. Иден- тификатор сущности становится первичным ключом. При проектировании таб- лиц необходимо указывать, могут ли атрибуты иметь пустые значения. Идеальный первичный ключ является коротким, имеет числовой тип и редко меняет свое значение. Если атрибут, выбранный изначально в качестве первич- ного ключа, не обладает этими характеристиками, следует выбрать на эту роль один из альтернативных ключей. Если это невозможно, нужно использовать сур- рогатный ключ. Суррогатный ключ — это предоставляемый системой уникальный идентифи- катор, используемый в качестве первичного ключа отношения. В разных СУБД суррогатные ключи определяются по-разному. В SQL Server суррогатный ключ определяется начальным значением (identity seed) и приращением (increment) — числом, которое нужно прибавить к текущему значению суррогатного ключа, чтобы получить следующее значение. Суррогатные ключи обладают двумя важными недостатками. Во-первых, они не имеют смысла для пользователей. Если первичный ключ, роль которого играют данные (например, НазваниеОтдела), может сообщить пользователю некоторую информацию, суррогатный ключ такой информации в себе не несет. Во-вторых, значения суррогатного ключа могут оказаться неуникальными при объединении информации из нескольких баз данных. Результатом этого может быть необхо- димость изменения значений суррогатного ключа и внешних ключей. Из соображений последовательности некоторые проектировщики баз данных считают, что если одна таблица в базе данных имеет суррогатный ключ, то и все остальные таблицы также должны иметь суррогатные ключи. По мнению дру- гих, суррогатные ключи следует использовать только в том случае, если ие име- ется данных, подходящих на роль первичного ключа. Связи представляются путем помещения первичного ключа одной таблицы в другую таблицу. Во второй таблице этот ключ получает название внешнего ключа Как конкретно это делается, зависит от типа связи. Во всех случаях, одна- ко, создание внешнего ключа порождает ограничение ссылочной целостности. Стандартные правила подддержания ссылочной целостности сведены в таб- лицу на рис 56 Обновление первичного ключа и удаление строки в родитель- ской таблице запрещаются, если строка имеет потомков Вставка строки и обнов- ление первичного ключа в дочерней таблице запрещаются, если новое значение внешнего ключа отсутствует среди значений первичного ключа родителя.
258 Глава 5. Проектирование баз данных Вюгето этих craw....« пр»№ можно оорелел.т. другие ..|Ю.«-лурм <Л« „ечсо я ccnwoi ^лоспкхти. Дне 1»« "Р'« ьр»"™ные иром-дуры "то XX обновленце .. «радиол уда« С..И.К »>’”««» "I™ ой,ош,И1н„ “ УМяХХс ' обязательоме потомки нредсганляютея по рм . му “ХаХпя обязательного родителя достаточно объяннп. обязатель- ым ШОТ NULL) внешний ключ дочерней таблицы. Представить обязательного потомка можно, только определи» соответствующие процедуры обеспечения ссылочной целостности при обновлении и удалении строк в дочерней таблице и при вставке строк в родительскую таблицу. Для представления идентификационно-зависимых связей (называемых в мо- дели IDEF1X идентифицирующими связями принадлежности) первичный ключ родителя помещается в отношение-потомок, становясь в нем одновременно внеш- ним ключом и частью первичного ключа. Родитель в такой связи является обя- зательным, поэтому внешний ключ определяется как обязательный. Кроме того, для потомка может быть разрешено каскадное обновление и удаление. Для представления связей принадлежности вида 1:1 и 1:N (называемых не- идентифицирующими связями принадлежности в модели IDEF1X) первичный ключ одной таблицы помещается в другую в качестве внешнего ключа, только в данном случае он уже не входит в первичный ключ второй таблицы. В случае связи 1:1 можно взять любую из таблиц и поместить ее первичный ключ в другую таблицу. Внешний ключ в связи вида 1:1 должен быть объявлен уникальным. Стандарт IDEF1X принуждает назначить одну из двух таблиц, имеющих связь вида 1:1, родителем, а другую — потомком, и поместить первичный ключ родителя в отношение-потомок. Внешний ключ не должен иметь пустое значение, если сис- темные требования указывают, что родитель является обязательным. Если обя- зательным является потомок, необходимо определить соответствующие проце- дуры обеспечения ссылочной целостности. Для представления связей вида 1:N первичный ключ родительской таблицы помещается в дочернюю таблицу. Если из системных требований следует обяза- тельность родителя, внешний ключ не должен иметь пустое значение. Если обя- зательным является потомок, необходимо определить соответствующие проце- дуры обеспечения ссылочной целостности. свя^ЛЯслч71пп-1аВЛеПИЯ связе” вида N:M в расширенной модели «сущность— чения ЭтатабСЯ ТРеТЬЯ’ ’Промежуточная таблица, называемая таблицей Пересе- и ямяХм ХтоЛОдаРЖ1" "ер“нчт" м,»чи дау* таблиц, имеющих связь N:M, “ '«“'1"*"™“»™отааВ.,с,<мой от обеих этих таблиц. зываются в ней К связям ВИДа N:M с подозрением; эти связи на- ся как указание вци(^ическими- Наличие такого рода связей рассматривает- этотак, недостающая cv*° В М°ДеЛИ данных упущена какая-то сущность. Когда от сущностей, имеющих XT Ь ЯВЛЯется обычно идентификационно-зависимой ей модели IDEF1X лаж. отет”ческую связь N:M. В соответствии с философи- атрибутов, неспецифичесюло11 промежуточная сущность не имеет неключевых идентифицирующих связиприХтежтоТт^ ВНкобХОЛИМ° Пре°бра30ВатЬ В философии вы придерживаетесь- ? жности- в конечном счете неважно, каков ляционной схеме ДерЖИВаетесь- так иначе, вы придете к одной и той же ре-
Резюме У таблицы пересечения (или, что эквивалентно, у промежу i очной идешифи кацНопно-зависимой сущности) оба родителя всегда являкпся обязательными поэтому внешние ключи не должны иметь пустых значений Минимальные кар дпнальные числа связей со стороны таблицы пересечения определяются из сие темных требований. Процедуры обеспечения ссылочной целостности при опера- циях над родительскими таблицами — эго, как правило, каскадное обновление и удаление в таблице пересечения. Прочие процедуры определяются, исходя из системных требований. Подтипы (в расширенной модели «сущность—связь») и категории (в модели IDEF1X) представляются путем помещения первичного ключа сущности-надти- па, или порождающей сущности, в сущность-подтип, или сущность-категорию Единственная разница в подходах между расширенной моделью «сущность- связь» и моделью IDEF1X заключается в том, что в последней имеются кате- гориальные кластеры, устанавливающие ограничения на сущности-категории. В частности, сущности-категории, принадлежащие к одному категориальному кластеру, являются взаимоисключающими, и для каждого полного категориаль- ного кластера порождающая сущность обязана принадлежать к одной и только одной из категорий, входящих в этот кластер. Эти ограничения реализуются по- средством соответствующих процедур обеспечения ссылочной целостности. Расширенная модель «сущность—связь» допускает существование слабых сущностей, не являющихся идентификационно-зависимыми. Такие сущности моделируются с помощью связей принадлежности вида 1:1 или 1:N. Единствен- ное отличие состоит в том, что необходимо определить процедуры обеспечения ссылочной целостности, дабы гарантировать, что при удалении родителя слабая сущность также будет удалена. Кроме того, необходимо установить правило умолчания, по которому слабым сущностям будет назначаться родитель. Рекурсивные связи — это связи, в которых участвуют сущности одного и того же класса. Есть три типа рекурсивных связей: 1:1, 1:N и N:M. Эти типы представ- ляются так же, как и в случае нерекурсивных связей. Для связей 1:1 и 1:N мы по- мещаем внешний ключ в отношение, которое представляет сущность. Для пред- ставления рекурсивных связей N:M мы создаем отношение пересечения. Тернарные связи и связи высших порядков могут быть представлены в виде комбинаций бинарных связей. Однако в этом случае все бинарные ограничения, налагаемые на тернарную связь, также должны быть представлены в проекте базы Данных. Поскольку такие ограничения невозможно реализовать в реляционной структуре, их необходимо документально фиксировать как положения делового регламента. Имеется три типа таких ограничений: «ДОЛЖНО БЫТЬ», «НЕ ДОЛЖНО БЫТЬ» и «ДОЛЖНО ВКЛЮЧАТЬ». Атрибут имеет пустое значение, если ему не было присвоено никакое значе- ние. Пустым значениям свойственна неоднозначность. Они допускают три воз- можные интерпретации: значение атрибута неизвестно, атрибут в данном случае неприменим или значение атрибута не определено. Предотвратить появление пустых значений можно, используя подтипы или категории. Кроме того, можно объявлять атрибуты обязательными или присваивать им начальные значения, устые значения можно также игнорировать, если возникающая неоднозначность Нс вызывает затруднений у пользователей.
260 Глава 5. Проектирование баз данных Вопросы группы I ! Что является входной информацией для процесса проектирования базы 2 Назовите основные этапы проектирования базы данных. 3 Опишите процесс преобразования сущности в отношение. 4‘ Как на диаграммах этой главы различаются сущности и отношения? 5 Как вы определяете, является ли атрибут обязательным? 6. В чем состоит важность первичных ключей, помимо того, что они служат идентификаторами строк? 7. Опишите характеристики идеального первичного ключа. 8. Дайте определение альтернативного ключа и объясните запись АКп.т. 9. Опишите ситуацию (отличную от приведенной в тексте), в которой аль- тернативный ключ может быть выбран на роль первичного ключа, по- скольку является более естественным. 10. Дайте определение суррогатного ключа. 11. Опишите ситуацию, в которой напрашивается использование суррогатно- го ключа. 12 Определите термины начальное значение и приращение применительно к суррогатным ключам и объясните, для чего они нужны. 13. 14. 15. 16. 17. 18 19. 20. 21. 22. 23. Укажите два недостатка суррогатных ключей. Считаете ли вы, что если одно отношение имеет суррогатный ключ, то и все остальные отношения в этой базе данных должны иметь суррогатные клю- чи? Обоснуйте свой ответ. Дайте определение ограничения ссылочной целостности и приведите пример. Сформулируйте стандартные правила поддержания ссылочной целостности. К чему следует прибегнуть, если стандартные правила поддержания ссы- лочной целостности не подходят? Дайте определения терминов каскадное обновление и каскадное удаление. Опишите, как реализуется ограничение обязательности родителя. Опишите, как реализуется ограничение обязательности потомка. ципуюпшй свячМеЖДУ иден1иФикационно-зависимой связью и идентифи- цирующей связью принадлежности? модели?НТИ^ИКаЦИ°ННО 3аВ11СИМЫе связи представляются в реляционной Сущностей’ имеющих идентификационно-зави- отношений Cd)ODMvni|Te’"KaK Э™ сущности представляются с помощью лочпой целостности^ Исто 7 В?3никающие пРи этом ограничения ссы- лей в тексте Используйте пример, отличный от того, что приве-
Вопросы группы t 2в1 24. Является ли внешний ключ в вашем ответе на вопрос 23 обязательным (NOT NULL) или необязательным (NULL)? 25. Подходит лн каскадное обновление в качестве процедуры обеспечения ссылочной целостности для вашего ответа на вопрос 23? 26. Подходит ли каскадное удаление в качестве процедуры обеспечения ссы- лочной целостности для вашего ответа на вопрос 23? 27. Если в идентификационно-зависимой связи удаление родительских строк запрещено, как тогда удалить данные родительской строки из базы данных? 28. Приведите соображения, которыми следует руководствоваться, принимая решение о целесообразности каскадного удаления в идентификационно- зависимых связях. 29. Если родитель в идентификационно-зависимой связи имеет суррогат- ный ключ, должен ли потомок также иметь суррогатный ключ? Обоснуйте свой ответ. 30. Приведите пример связи принадлежности вида 1:1, отличный от описан- ных в тексте. Сконструируйте связь, в которой одна сущность будет обяза- тельной, а другая необязательной. 31. Покажите два способа представления связи 1:1 для вашего ответа на во- прос 30. Укажите уникальные и обязательные столбцы. 32. Какую структуру навязывает модель IDEF1X связям вида 1:1? 33. Покажите два способа представления связи 1:1 для вашего ответа на во- прос 30, используя символику модели IDEF1X. 34. Покажите отношения, к которым привел ваш ответ на вопрос 33. 35. Сформулируйте ограничения ссылочной целостности для вашего ответа на вопрос 33. 36. Определите процедуры обеспечения ссылочной целостности для вашего ответа на вопрос 33. Обоснуйте принятые вами решения. 37. Какая сущность в связи вида 1:N является родителем, а какая — потомком? 38. Сформулируйте общее правило помещения внешнего ключа при представ- лении связей вида 1:N. 39. Приведите пример двух сущностей со связью 1:N, отличный от данного в тексте. Укажите минимальные кардинальные числа, как считаете пра- вильным. 40. Представьте ваш ответ на вопрос 39 в виде отношений. 41. Сформулируйте ограничения ссылочной целостности для вашего ответа на вопрос 40. 42. Определите процедуры обеспечения ссылочной целостности для вашего ответа на вопрос 40. Обоснуйте принятые вами решения. 43. Почему стратегия, используемая для представления связей вида 1:N, не ра- ботает на связях вида N:M? 44. Что такое таблица пересечения? Почему она необходима для представле- ния связей N:M?
262 Глава 5. Проектирование баз данных 45. 46. 47. 48. 49. го СПЯ И.ю N М, ОТЛИЧНЫЙ ОТ ДЛННО1Г) Приведите пример двух сущностей со связы в тексте. оп„ТЯП1,т. СУщпости из ваше! о ответа на вопрос 45 с по- Покажите, как п,ет J укажите мивималыдае шрди|шшше чис- лаХпе ИЗ этих ™«л определяют™ систем,,ммн требованиями, а о- кие — природой таблицы пересечения? Сформулируйте ограничения ссылочной целостности для вашего ответа Определите процедуры обеспечения ссылочной целостности для вашего ответа на вопрос 46. Обоснуйте принятые вами решения. Объясните, почему модель на рис. 5.16, а наводит на мысль о недостающей сущности. 50 Объясните разницу между рис. 5.15, б и рис. 5.16, в. Чем идентификацион- но-зависимая сущность па рис. 5.16, в отличается от таблицы пересечения? 51. Объясните, как модель IDEF1X относится к связям вида N:M. 52. Объясните разницу в подходах к связям вида N:M между расширенной моделью «сущность—связь» и моделью IDEF1X. Какой из подходов, по вашему мнению, более правилен? 53. В чем разница между сущностью-надтипом и порождающей сущностью? Между сущностью-подтипом и сущностью-категорией? 54. Приведите пример сущности с двумя категориальными кластерами, от- личный от данного в тексте. Сделайте один из категориальных кластеров полным, а другой неполным. 55. Представьте ваш ответ на вопрос 54 в виде отношений. 56. Сформулируйте ограничения ссылочной целостности для вашего ответа на вопрос 55. 57. 58. 59. 60. 61. 62. 63. Объясните, как влияет на процедуры обеспечения ссылочной целостности правило, гласящее, что категории внутри одного категориального кластера являются взаимоисключающими. Чем отличаются процедуры обеспечения ссылочной целостности для пол- ных и неполных категориальных кластеров? ответа^а^опрсх^бЗ^Р14 °^еспечения ссылочной целостности для вашего ФикапионноНя Предстапля’?тся слабые сущности, не являющиеся иденти- JSZS?”™' "Ройеры Склопапстст - Р’ отличныи °т данного в тексте. ограничениГссьыочтоТцелостнос^!61 “ ОТНОШений- Сформулируйте ссылочной целостности. определите процедуры обеспечения * кажите, гак Представит! эти Пвя™4™6 CM3H ВВДй 1:N с СУЩНОСТЬЮ В' П°‘
Вопросы группы И 283 64. Приведите примеры трех типов рекурсивных связей, отличные от тех, что даны в тексте. 65. Постройте реляционную схему рекурсивной связи вида 1:1 на основе ва- шего ответа на вопрос 64. 66. Постройте реляционную схему рекурсивной связи вида 1:N на основе ва- шего ответа на вопрос 64. 67. Постройте реляционную схему рекурсивной связи вида N:M па основе ва- шего ответа па вопрос 64. 68. Приведите пример тернарной связи, ограниченной бинарной связью. Ис- пользуйте пример, отличный от того, который дан в тексте. 69. Чем отличаются друг от друга ограничения «ДОЛЖНО БЫТЬ», «НЕ ДОЛЖНО БЫТЬ» и «ДОЛЖНО ВКЛЮЧАТЬ»? 70. Каковы три возможные интерпретации пустцх значений? 71. Покажите, как можно избежать появления пустых значений, связанных с неприменимостью атрибута, путем введения подтипов или категорий. Вопросы группы II 72. Ответьте на вопрос 35 главы 3, если вы еще этого не сделали. Создайте ре- ляционную схему для модели данных из вашего ответа на вопрос 3.35, б. Ваша схема должна включать определение таблиц, атрибутов, первичных и внешних ключей, ограничений ссылочной целостности и процедур обес- печения ссылочной целостности. 73. Ответьте на вопрос 36 главы 3, если вы еще этого не сделали. Создайте ре- ляционную схему для вашей модели данных. Схема должна включать опре- деление таблиц, атрибутов, первичных н внешних ключей, ограничений ссылочной целостности и процедур обеспечения ссылочной целостности. 74. Ответьте на вопрос 37 главы 3, если вы еще этого не сделали. Создайте ре- ляционную схему для каждой из моделей данных, полученных вами при ответе на пункты 1)-5) вопроса. Схема должна включать определение таб- лиц, атрибутов, первичных и внешних ключей, ограничений ссылочной целостности и процедур обеспечения ссылочной целостности. 75. Ответьте на вопрос 39 главы 3, если вы еще этого не сделали. Создайте ре- ляционную схему для модели данных из вашего ответа на часть 1) вопроса и для модели данных, изображенной на рис. 3.31. Схема должна включать определение таблиц, атрибутов, первичных и внешних ключей, ограничений ссылочной целостности и процедур обеспечения ссылочной целостности. 76. Ответьте на вопрос 40 главы 3, пункт 5), если вы еще этого не сделали. Создайте реляционную схему для вашей модели данных. Схема должна включать определение таблиц, атрибутов, первичных и внешних ключей, ограничений ссылочной целостности и процедур обеспечения ссылочной целостности.
2б4 Глава 5. Проектирование баз данных__ 77. 78. 79. Ответьте па вопрос 41 главы 3, пункт 3), если вы еще этого не сделки Ст- чайте реляционную схему для вашей модели данных Схема аояжм» и» определение таблиц, атрибутов, первичных и л «них к 1О1И., ссылочной целостное!.. и процедур обеспечения ссылочной ^лослюзд Ответе на вопрос 42 главы 3, пункт 4), если вы еще этого не сделали. Се» дайте реляционную схему для вашей модели данных Схема должна включать определение таблиц, атрибутов, первичных и внешних ключей ссылочной целостности и процедур обеспечения ссылочной целостное^. Ответьте на вопрос 43 главы 3, пункт 3), если вы еще этого не сделала. Создайте реляционную схему для вашей модели данных. Для указания не- ключевых атрибутов вам не хватит данных, поэтому просто укажите таб- лицы, ключи, ограничения ссылочной целостности и процедуры обесм*- нпя ссылочной целостности. 80. Ответьте на вопрос 44 главы 3, часть 3), если вы еще этого не сделали. Создайте реляционную схему для вашей модели данных. Для указания не- ключевых атрибутов вам не хватит данных, поэтому просто укажите таб- лицы, ключи, ограничения ссылочной целостности и процедуры обесоече- ння ссылочной целостности. 81. Обратитесь к реляционной схеме для базы данных университета Highline, изображенной на рис. 5.21, б. Пользуясь принципами, описанными в этой главе, сформулируйте ограничения ссылочной целостности для каждой из связей на этой модели. Вопросы к проекту FiredUp Ответьте на вопрос 4 к проекту FiredUp в конце главы 2, если вы этого еще не сделали. Создапте реляционную схему для вашей модели данных. Схема должна вклю- чать определение таблиц, атрибутов, первичных и внешних ключей, ограниче- нпи ссылочной целостности и процедур обеспечения ссылочной целостноеи Вопросы к проекту Twigs Tree не™™адна ВОПРОСЬ13 И 5 к пР°ек11У FiredUp в конце главы 2, если вы этого еше с?рД1ПТС Реляционную схему для модели данных из ответа на вопрос 3. нч7^а включать определение таблиц, атрибутов, первичных и внеш* criin«u°4"H’ огРан11Чеинй ссылочной целостности и процедур обеспечения ссылочной целостности. СхемТ^пп^7ПЯ1П.1ОННУЮ схемУ для модели данных из ответа на вопрос 5. них кпючой включать определение таблиц, атрибутов, первичных и вне®' ссылочной 7 ерапнченип ссылочной целостности и процеду р обеспечения ссылочной целостности. 17 7i -Г .‘Ч**’-"-' - in-.
Часть III Структурированный язык запросов (SQL) В трех главах, входящих в состав этой часта, рассказывается о структурирован- ном языке запросов (Structured Query Language, SQL). Главу 6 можно назвать вводной, она посвящена основным выражениям SQL, используемым как для соз- дания структур баз данных, так и для составления запросов и манипулирования данными. В главе 7 SQL описывается в контексте приложения. Представления SQL, триггеры и хранимые процедуры, примеры использования выражений SQL в прикладных программах — вот что вы найдете в этой главе. Глава 8 завершает эту часть обсуждением вопросов переделки баз данных. Из этой главы вы узнаете об использовании SQL для изменения структур баз дан- ных. Также здесь будут- обсуждаться две нетривиальные темы, касающиеся SQL: соотнесенные подзапросы и операторы EXISTS/NOT EXISTS. Их использова- ние полезно не только для составления традиционных запросов, но и для оценки контента баз данных с целью выяснения необходимости внесения изменений в их структуру.
Глава 6 Введение в язык SQL В этой главе вы познакомитесь с языком SQL Аббревиатура SQL шифрмымл ся как structured query language, что в переводе с английского означает «язык струк- турированных запросов». SQL не является полноценным языком прогршашр» вания; он представляет собой всего лишь подъязык данных (data sublanr иф В нем имеются операторы только для создания и обработки баз данных Однако операторы SQL можно встраивать в программы на сценарных языках, например VBScript, или универсальных языках программирования, таких как Java или С» таким образом, в реальности ограниченность возможностей SQL не представляет проблемы. Операторы SQL можно также использовать в хранимых процедурах п триггерах, и их можно вводить в интерактивном режиме в командной - СУБД. Более подробно о встраивании операторов SQL в программы на раз- личных языках программирования и использовании его в хранимых процедурах и триггерах вы узнаете из следующей главы. В этой главе мы сосредоточимся на синтаксисе SQL и работе с командной строкой. Язык SQL был разработан фирмой IBM в конце 1970-х годов и был принят Американским национальным институтом стандартов (ANSI) в качестве на- ционального стандарта США в 1992 году. На этом стандарте, называемом также SQL-92, базируется рассматриваемая здесь версия языка. Более поздняя верой стандарта, SQL3, включает в себя ряд концепций, заимствованных из объектно- ориентированного программирования. Эта последняя версия не привлекла при- стал ыюго внимания со стороны фирм-разработчиков коммерческих СУБД и на настоящий момент не представляет важности с точки зрения практической рабо- ты с базами данных. Мы рассмотрим ее вкратце в главе 16. Стандарт SQL-92 обширен п всеобъемлющ. Ни одна из распространенных коммерческих СУБД, таких как DB2, Oracle или SQL Server, не реализует его в полном объеме. В этой главе мы сосредоточимся на тех операторах SQL-92. которые поддерживаются большинством СУБД. Операторы, специфические для Oiacle и SQL Server, будут обсуждаться в главах 10 и 11 соответственно. зык QL ориентирован на текст. Он был разработан задолго до появления графических шпсрфсйсов пользователя, так что для работы с ним требуется лишь текстовый редактор. Разумеется, сегодня в SQL Server, Oracle. DB2 и дру- гих Д имеются графические средства для выполнения многих из тех зада* которые ранее могли быть выполнены только с помощью SQI Но ключевые
База данных управления проектами и предприятии 5t®7 слова здесь — «многих из». Не все из того, что позволяет делать SQL, можно осуществить с помощью графических средств; более того, в ряде случаев, на пример, для динамической генерации операторов SQL в программном коде. SQL использовать необходимо. С помощью SQL можно определять структуры базы данных, а также запраши- вать и обновлять информацию в базе данных. Совокупность команд, служащих для определения данных, называют иногда языком определения данных (data definition language, DDL), а совокупность команд для обновления и запроса дан- ных — языком манипулирования данными (data manipulation language, DML). Далее мы обсудим оба эти подмножества языка SQL, но сначала рассмотрим ба- зу данных, на примере которой будут иллюстрироваться языковые конструкции База данных управления проектами на предприятии На рис. 6.1 изображены модель данных и реляционная схема для базы данных управления проектами на предприятии, которая будет использоваться в этой гла- ве для демонстрации синтаксиса SQL. Здесь с каждым проектом должно быть связано по крайней мере одно назначение, а сотрудник может иметь любое коли- чество назначений, в том числе ноль. Обратите внимание, что внешний ключ свя- зи СОТРУДНИК—НАЗНАЧЕНИЕ носит имя НомерСотрудника, а не ИдСотрудника, хотя указывает он по-прежнему на ИдСотрудника. Имеется два ограничения ссылочной целостности. Значение атрибута НАЗНАЧЕНИЕ.ИдПроекта должно существовать среди значений атрибута ПРОЕКТ.ИдПроекта. Значение атрибута НАЗНАЧЕНИЕ.ИдСотрудника должно существовать среди значений атрибута ПРОЕКТ.ИдСотрудника Процедуры обеспечения ссылочной целостности обозначены на рис. 6.1, б. В связи ПРОЕКТ—НАЗНАЧЕНИЕ разрешены каскадное обновление и удаление, а в свя- зи СОТРУДНИК—НАЗНАЧЕНИЕ — только каскадное обновление. Удаление строк из таблицы СОТРУДНИК ограничено: запись о сотруднике можно удалить только в том случае, если у него нет ни одного назначения. В противном случае необходимо будет удалить имеющиеся назначения или передать их другому сотруднику, и только потом можно будет удалить строку данного сотрудника. Поскольку каждый проект должен иметь минимум одно назначение, вставка строк в таблицу ПРОЕКТ ограничена: всякий раз, когда в таблицу ПРОЕКТ добавля- ется строка, необходимо создавать для нее новую строку в таблице НАЗНАЧЕНИЕ Из главы 7 вы узнаете, как это делается с помощью триггеров. Рассмотрим теперь действия с таблицей НАЗНАЧЕНИЕ. Обновление столбца ИдПроекта ограничено: назначение, сделанное в рамках определенного проекта, нельзя переместить в другой проект. Кроме того, последнее назначение проект* не может быть удалено. В связи СОТРУДНИК-НАЗНАЧЕНИЕ таких ограничений нет. Данные для этого примера приведены в табл. 6.1, 6.2 н 6.3.
268 Глава 6 введение в язык SQL Р 1 НАЗНАЧЕНИЕ ИдПроекта (FK) НомерСотрудника (FK) ФактТрудозатраты а СОТРУДНИК НиыерСо’Рл»’— H T> । •’ 1--- Отдел ПРОЕКТ__________ ^ИдПроекта: NOT NULL Название NOT NULL (AK1.1) Отдел: NOT NULL МаксТрудозатраты: NULL СОТРУДНИК DC IR U:C DR U:C Ц, Ид Проекта NOT NULL Название NOT NULL (АК11) Отдел NOT NULL МаксТрудозатраты NULL D:R U:R Р НАЗНАЧЕНИЕ ^ИдПроекта: NOT NULL (FK) НомерСотрудника: NOT NULL (FK) ФактТрудозатраты: NULL и ~ б Рис. 6.1. База данных управления проектами на предприятии i — модель данных; б — реляционная схема Табл. 6.1. Отношение ПРОЕКТ ИдПроекта Название Отдел МаксТрудозатраты^ 1000 КВЗ Анализ портфеля Финансы 75.0 1200 КВЗ Подготовка налогового отчета Бухгалтерия 145.0 1400 КВ4 Планирование продукта Маркетинг 138.0 1500 КВ4 Анализ портфеля Финансы 110.0 Табл. 6.2. Отношение СОТРУДНИК ТабельныйНомер Имя Телефон Отдел 100 Мэри Джекобс 285-8879 Бухгалтерия 200 Кенджи Нюмото 287-0098 Маркетинг 300 Хэзер Джонс 287-9981 Финансы 400 Розали Джексон 285-1273 Бухгалтерия 500 Джеймс Нестор Инф. системы 600 Ричард By 287-0123 Инф системы 700 Ким Сунг 287-3222 Маркетинг
Средства определения данных языка SOL 209 тоЛп. 6.3. Отношение НАЗНАЧЕНИЕ НомерСотрудника ФактТрудозатраты 1000 100 75.0 1000 300 145.0 1000 400 138.0 1000 500 110.0 1200 100 75.0 1600 400 145.0 1200 600 138.0 1400 200 110.0 1400 700 110.0 1400 500 110.0 Средства определения данных языка SQL С помощью SQL можно создавать и модифицировать структуры базы данных. В этой главе рассматривается только создание таких структур, а модификация существующих структур описывается в главе 8. Таблицы создаются с помощью оператора CREATE TABLE. Иногда вместе с оператором CREATE TABLE используется оператор ALTER для указания первичных и вторичных ключей. Оператор CREATE TABLE Основная функция этого оператора — создание новой таблицы и описание ее столбцов и типов данных. Кроме того, этот оператор позволяет определять пер- вичные ключи, альтернативные ключи и внешние ключи с некоторыми огра- ничениями ссылочной целостности, а также задавать ограничения на столбцы в таблицы. Для начала рассмотрим простой пример (листинг 6.1). Таблице дано имя ПРОЕКТ. В скобках приведены определения четырех столбцов. Определение каж- дого столбца состоит из трех частей: имени столбца, его типа данных и необя- зательных ограничений па этот столбец. Как и все операторы SQL, оператор CREATE TABLE завершается точкой с запятой. Листинг 6.1. Базовый формат оператора CREATE TABLE CREATE TABLE ПРОЕКТ (ИдПроекта Integer Primary Key. Название Char(25) Unique Not Null. Отдел VarChar(lOO) Null. МаксТрудозатраты Numeric(6,l) Default 100); FORETS^L имеегся пять типов ограничений: PRIMARY KEY, NULL/NOT NULL, UNIQUE, GN KEY ii CHECK. Первые четыре ограничения будут рассмотрены п этой гла- е> <» ограничение CHECK будет обсуждаться в главе 7.
270 Глава 6. Введение в язык SQL В листинге 6.1 столбец ИдПроекта принадлежит к тину данных Integer (цело- численный) и имеет свойство Primary Key. Следующий столбец, Название, имеет тип данных Character (строковый) с максимальной длиной 25 символов Посколь- ку этот столбец является альтернативным ключом, в его определение были добав- лены ключевые слова Unique Not Null. Они означают, что значения столбца Название являются уникальными в таблице ПРОЕКТ и что этот столбец обязан иметь значение. В SQL первичные ключи ни при каких условиях не могут иметь пустых зна- чений. Именно поэтому для столбца ИдПроекта можно просто указать свойство Primary Key, не уточняя, что он не должен быть пустым (Not Null). Ключевые слова Primary Key сами по себе уже говорят, что столбец ИдПроекта не будет иметь пус- тых значений. Для уникальных столбцов, однако, пустые значения возможны. Если бы столбец Название был определен просто как Unique, без ключевых слов Not Null, он мог бы иметь пустые значения. В данном случае это неприемлемо, по- скольку столбец Название является альтернативным ключом. Третий столбец, Отдел, принадлежит к типу данных VarChar(lOO) и имеет свой- ство Null. VarChar обозначает строку переменной длины. Таким образом, в разных строках значения столбца Отдел могут различаться по длине, и максимально воз- можная длина строки равна 100 символам. Ключевое слово Null указывает на то, что пустые значения допустимы. Значения типа Char имеют фиксированную длину. Если столбец Название опре- делен как Char(25), это означает, что каждое значение столбца Название будет храниться в виде строки длиной 25 символов, независимо от того, какова реаль- ная длина названия проекта. При необходимости имена будут дополняться про- белами до 25 символов. Значения типа VarChar могут иметь разную длину. Если название отдела состоит всего из четырех символов, то только эти четыре симво- ла и будут храниться в столбце Отдел. Зная об этом преимуществе типа VarChar, почему бы не пользоваться им все время? Дело в том, что обработка столбцов типа VarChar занимает больше време- ни. Для хранения длины строки требуется несколько дополнительных байтов, и чтобы организовать храпение значений с переменной длиной в памяти и надис- ке, СУБД приходится идти на ряд ухищрений. Поставщики СУБД обычно дают указания по поводу того, в каких случаях какой тип данных следует использовать. Эти указания вы можете найти в документации на используемую вами СУБД. Четвертый столбец таблицы ПРОЕКТ, МаксТрудозатраты,’ имеет тип данных Numerical). Это означает число из шести цифр с одной цифрой после десятич- ной точки. (Десятичная точка не хранится и поэтому не считается за цифру-) "‘,пр,1Мер’ хранимое в этом столбце значение 123456 будет отображаться Д в виде 12345.6. По умолчанию, поскольку не указано иного, столбцу Макс- рудозатраты присваивается свойство Null. Запись Default 100 указывает, что при создании новой строки в таблице ПРОЕКТ столбцу МаксТрудозатраты необходимо присвоить начальное значение, равное 100. Четыре типа данных, показанные в листинге 6.1, — это основные типы дан* гмктг ста1,дарте SQL-92 определено много других типов данных, а вряде СУЬД имеются свои, специфические типы. В табл. 6.4 и 6.5 перечислены некото- рые из типов данных, поддерживаемых в СУБД Microsoft SQL Server и Oracle
Средства определения данных языка SQL 271 тябл 6.4. Типы данных SQL в СУБД SQL Server м Описание Binary Массив двоичных данных, длина от 0 до 8000 байт Char Массив символьных данных, длина от 0 до 8000 байт Datetime Дата и время длиной 8 байт Диапазон: от 1 января 1753 года до 31 декабря 9999 года, с точностью до трех сотых секунды Decimal Десятичное число, можно задавать точность и масштаб. Диапазон: от -10яЗВ + 1 до 10"38 - 1 Float Число с плавающей точкой длиной 8 байт. Диапазон значений: от -1.79Е+308 до 1.79Е+308 Image Массив двоичных данных переменной длины. Максимальная длина 2 147 483 647 байт Int 4-баитовое целое число. Диапазон значений: от -2 147 483 648 до +2 147 483 647 Money Денежная сумма, длина 8 байт Диапазон: от -922337203685477.5808 до +922337203685477.5807 Numeric То же, что и Decimal Real 4-байтовое число с плавающей точкой. Диапазон значений: от -3.40Е+38 до +3.40Е+38 Smalldatetime Дата и время длиной 4 байт. Диапазон: от 1 января 1900 года до 6 июня 2079 года, с точностью до одной минуты Smallint 2 байтовое целое число. Диапазон: от -32 768 до 32 767 Smallmoney Денежная сумма, длина 4 байт Диапазон: от -214748.3648 до +214748.3647, с точностью до одной десятитысячной денежной единицы Text Текст переменной длины, максимальная длина 2 147 483 647 символов Tinyint 1-байтовое целое. Диапазон: от 0 до 255 Varchar Массив символьных данных переменной длины, длина от 0 до 8000 байт Табл. 6.5. Типы данных SQL в СУБД Oracle Тип данных Описание BLOB Большой двоичный объект. Может быть длиной до 4 Гбайт CHAR(n) Текстовое поле фиксированной длины п. Максимум 2000 символов DATE Поле длиной 7 байт, содержащее дату и время INT Целое число длиной 38 знаков NUMBER(n.d) Число длиной п с d знаками после запятой VARCHAR(n) Текстовое поле переменной длины до п символов. Максимальное или значение п = 4000 VARCHAR2(n) Определение первичных и альтернативных ключей с помощью оператора ALTER JOr° табл‘ща определена, ее структуру, свойства и ограничения можно этого о,?’ ИСПОЛЬзуя оператор ALTER. В этой главе мы покажем, как с помощью оратора создавать первичные и альтернативные ключи.
272 Глава о Введение в Например, в листинге 6.2 показан альтернативный способ м» вичпого ключа, при котором сначала определяется таблица. я потом ев нпе модифицируется оператором ALTER Оператор CREATE TABLE СНИУдеяяет цщ столбцы таблицы СОТРУДНИК, но пи один и » них не укашвщеня в пгд. личного ключа. Затем при помощи оператора ALTER TABLE вводится н«ЖМг ченне под названием СотрудникПК, которое определяет столбец ТаГ,г>.ьи„<м>-1.. как первичный ключ. Листинг 6.2. Добавление ограничений с помощью оператора ALTER CREATE TABLE ПРОЕКТ (ИдПроекта Integer Primary Key. Название CharC25) Unique Not Null Отдел VarChar(lOO) Null. МаксТрудозатраты Numeric(6.1) Default 100). CREATE TABLE СОТРУДНИК (ТабельныйНомер Имя Телефон Отдел Integer Not Null. Char(25) Not Null. Char(8). VarChar(lOO)); ALTER TABLE СОТРУДНИК ADD CONSTRAINT СотрудникПК PRIMARY KEY (ТабельныйНомер). CREATE TABLE НАЗНАЧЕНИЕ (ИдПроекта Integer Not Null. НомерСотрудника Integer Not Null. ФактТрудозатраты Numeric(5.2) Default 10. CONSTRAINT НазначениеПК PRIMARY KEY (ИдПроекта. НомерСотрудника): ALTER TABLE НАЗНАЧЕНИЕ ADD CONSTRAINT СотрудникВК FOREIGN KEY (НомерСотрудника) REFERENCES СОТРУДНИК(ТабельныйНомер) ON UPDATE CASCADE ON DELETE NO ACTION; ALTER TABLE НАЗНАЧЕНИЕ ADD CONSTRAINT ПроектВК FOREIGN KEY (ИдПроекта) REFERENCES ПРОЕКТ(ИдПроекта) ON UPDATE CASCADE ON DELETE CASCADE; Имя для ограничения может выбираться произвольно, но, как правило, в про ектах по созданию баз данных имеются стандартные соглашения об именован) которых необходимо придерживаться. Здесь мы следуем соглашению, в соотве сгвии с которым имена первичных ключей образуются путем присоединения аб бревиатуры ПК (первичный ключ) к названию таблицы. У других разработчиков (например, у вашего преподавателя) могут быть другие стандарты-
Средства определения данных языка SQL 273 Сравните способы, которыми в листинге 6.2 определены первичные ключи тчбтпш ПРОЕКТ и СОТРУДНИК. Оба способа являются правильными Бди г Дтаетшое различие состоит в том, что для таблицы СОТРУДНИК разработчик ука С имя ограничения первичного ключа. Ограничению первичного ключа таолицы ПРОЕКТ также будет дано имя, по выберет его уже СУБД. Скорее всею, это> будет какое-нибудь ужасно длинное и невразумительное имя, - например, SYSTEM. C0NSTRAINT_PRIMARY.KEY_WCY869O или того хуже. Поэтому второй метод, воооще говоря, более предпочтителен. ПРИМЕЧАНИЕ Все ограничения хранятся в базе данных в виде метаданных. Как вы узнаете из глав 10 и 11, доступ к этим метаданным также можно получить средствами языка SQL. Здесь мы не будем обсуждать этот вопрос, поскольку способ, которым это делается, зависит от кон- кретной СУБД. Однако в любом случае наличие легко распознаваемого имени, следующего принятым стандартам именования, облегчит задачи администрирования данных. Определение третьей таблицы в листинге 6.2 демонстрирует еще один способ определения первичного ключа. Здесь ограничение определяется в теле операто- ра CREATE, после того как определены все столбцы. Используя этот подход, разра- ботчик может присваивать имена ограничениям в момент создания таблиц, не прибегая к использованию оператора ALTER. Большинство разработчиков пред- почитают данный метод определения первичного ключа. Также обратите внимание, что композитный ключ определяется путем пе- речисления имен атрибутов в скобках. Первичный ключ таблицы НАЗНАЧЕНИЕ представляет собой сочетание {ИдПроекта, НомерСотрудника}. Композитный пер- вичный ключ не может быть определен с помощью того метода, который мы ис- пользовали для таблицы ПРОЕКТ. Посредством оператора ALTER можно также определять внешние ключи (см. лис- тинг 6.2). В предпоследнем операторе определено ограничение СотрудникВК. Это ограничение указывает, что столбец НомерСотрудника является внешним ключом, который указывает па столбец СОТРУДНИК.ТабельныйНомер. Как вы видите, имена первичного и внешнего ключей не обязательно должны совпадать. Кроме того, обратите внимание на то, как образуются имена внешних ключей: к имени таб- лицы присоединяется аббревиатура ВК {внешний ключ). В определении внешнего ключа можно указывать процедуры обеспечения ссылочной целостности при обновлении и удалении. Как говорилось в главе 5, по умолчанию изменение первичного ключа строки не допускается, если у нее имеются потомки, и при тех же условиях не допускается удаление строки. Процедуры обеспечения ссылочной целостности определяются с помощью выражений ON UPDATE (при обновлении) и ON DELETE (при удалении). Например, Для ограничения СотрудникВК в листинге 6.2 предписывается при обновлении ро- дителя выполнить каскадное обновление (ON UPDATE CASCADE), а при удалении ие предпринимать никаких действий (ON DELETE NO ACTION). Последнее, между 1оАтпЫУТЫВаТЬ “е обязательно- поскольку по умолчанию задается ’как раз с шее' ДеСЬ МЫ ЯВН° указали этот Режим лля того> чт<>бы вы знали, что он твует и его можно использовать для целей документирования.
274 Глава 6. Введение в язык SQL Ограничение ПроектВК определяет внешний ключ ИдПроекта Для этого огра ничепия установлены и каскадное обновление, и каскадное удаление Как ON UPDATE CASCADE, так и ON DELETE CASCADE являются частью стандарта SQL-92. Не все СУБД поддерживают эти конструкции. В частности, Oracle до- пускает ON UPDATE CASCADE, но ие поддерживает ON DELETE CASCADE В Oracle про- цедура каскадного удаления должна реализовываться разработчиком с помощью триггеров. Листинг 6.3 представляет собой модифицированную версию листинга 6 2, в которой не используются операторы ALTER. Все ограничения вместо этого опре- деляются в теле операторов CREATE. Обратите внимание на два различных спосо- ба определения ограничений внешнего ключа в таблице НАЗНАЧЕНИЕ. В одном из них ограничение вводится при определении столбца ИдПроекта, а в другом — по- сле определения всех столбцов. Ни в одном из этих случаев разработчик не при- сваивает имен ограничениям. За него это сделает СУБД. Листинг 6.3. Еще один способ определения ограничений CREATE TABLE ПРОЕКТ (ИдПроекта Integer Primary Key Название Char(25) Unique Not Null. Отдел VarChar(lOO) Null МаксТрудозатраты Numeric(6.1) Default 100): CREATE TABLE СОТРУДНИК (ТабельныйНомер Имя Телефон Отдел Integer Not Null. Char(25) Not Null. Char(B) VarChar(lOO). CONSTRAINT СотрудникПК PRIMARY'KEY (ТабельныйНомер)); CREATE TABLE НАЗНАЧЕНИЕ (ИдПроекта Not Null Integer Not Null HoHenCnTnv0REIGN КГ REFERENCES ПРОЕКТ(ИдПроекта). НомерСотрудника Integer Not Null тЖштацРаТЬ1 Numeric<5.2) Default 10. S KEVKEY <"*«’» НоиерСотруриика). unciun Kti (НомерСотрудника) REFERENCES СОТРУДНИК(ТабельныйНомер)): Предпочтение _ использованию оператора CREATE “«нию лиц. При прочих равныхХлови^ЛаИЧИЬ1е варианты и способы определения таб- разработчику давать имена ограничены еДП°чнтаю те 113 них> которые позволяют использование оператора ALTER пб ЯМ Я также стараюсь свести к минимуму определялись в теле оператора CREATE. В лиД^и °Тл°"И аС"еКТЫ Ta" ность операторов CREATE Tari f листинге 6.4 приведена последователь- Lt’ ^Ующая этим принципам.
Средства определения данных языка SQL 270 питинг в 4. Примеры записи операторов CREATE TABLE CREATE table проект (ИдПроекта Название Отдел МаксТрудозатраты Integer Primary Key. Char(25) Unique Not Null VarChar(lOO) Null. Numeric(6.1) Default 100); PRIMARY KEY (ИдПроекта)): CONSTRAINT ПроектПК CREATE TABLE СОТРУДНИК (ТабельныйНомер Integer Not Nul1. Имя Char(25) Not Null. Телефон Char(8) Отдел VarChar(100), CONSTRAINT СотрудникПК PRIMARY KEY (ТабельныйНомер)); CREATE TABLE НАЗНАЧЕНИЕ (ИдПроекта Integer Not Null НомерСотрудника Integer Not Null ФактТрудозатраты Numeric(5.2) Default 10. CONSTRAINT НазначениеПК PRIMARY KEY (ИдПроекта. НомерСотрудника). CONSTRAINT СотрудникПК FOREIGN KEY (НомерСотрудника) REFERENCES СОТРУДНИК(ТабельныйНомер) ON UPDATE CASCADE ON DELETE NO ACTION. CONSTRAINT ПроектВК FOREIGN KEY (ИдПроекта) REFERENCES ПРОЕКТ(ИдПроекта) ON UPDATE CASCADE ON DELETE CASCADE); Операторы в листингах 6.2-6.4 приводят к одной и той же структуре базы данных, но последовательность, изображенная в листинге 6.4, выглядит для меня более привлекательной с эстетической точки зрения. Выбор между этими аль- тернативными подходами представляет собой вопрос стиля. Как и в любой дисциплине, стиль может быть предметом спора. Обменяйтесь мнениями с вашим преподавателем: возможно, у него по этим вопросам имеется особая точка зрения. Со временем у вас выработаются собственные предпочте- ния, и в группах, в которых вы будете работать, также, скорее всего, будут соб- ственные стандарты записи. Передача SQL-кода на исполнение СУБД Создав текстовый файл с операторами SQL, вы передаете его на исполнение СУБД. Способ, которым это делается, зависит от конкретной СУБД. В Oracle вы можете использовать текстовую командную оболочку под названием SQL*Plus или программу Oracle Enterprise Manager Console с графическим интерфейсом. ^QL Server можно использовать средство под названием Query Analyzer или среду разработки Visual Studio.Net. Эти возможности мы обсудим в главах 10 и 11.
276 Глава 6. Введение в язык Сю Операторы DROP В языке SQL имеется множество других онера.оров и конструкций ж," Zhu, ОЛ.ШИ самых .юлипых среди них <МЯ«« «к|ы,..р ОВД Над. Ношодаремс,,.,»»,,лле™ и ол.шм ...смыхопасных, „«колшу удаляй rZ, лицу из базы данных вместе со всеми содержащимися в ней оаншями Если вам нужно удалить из базы данных таблицу под названием КЛИЕНТ и содержащиеся в ней данные, используйте следующий оператор DROP TABLE КЛИЕНТ; Оператор DROP TABLE не выполняется, если таблица содержит или может содер- жать значения, необходимые для соблюдения ограничений ссылочной целостно- сти. Например, столбец ИдПроекта таблицы ПРОЕКТ может содержать значения, необходимые для соблюдения ограничения внешнего ключа ПроектВК Попытка передать СУБД на выполнение оператор DROP TABLE ПРОЕКТ окончится неудачей, и система выдаст сообщение об ошибке. Если вы хотите удалить таблицу ПРОЕКТ, нужно сначала удалить либо ограни- чение внешнего ключа ПроектВК, либо всю таблицу НАЗНАЧЕНИЕ. Удалить огра- ничение можно при помощи следующего оператора: ALTER TABLE НАЗНАЧЕНИЕ DROP CONSTRAINT ПроектВК; Если вы предпочитаете удалить всю таблицу, это можно сделать таю DROP TABLE НАЗНАЧЕНИЕ: Выполнив любое из этих действий, вы сможете беспрепятственно удалить таблицу ПРОЕКТ. В главе 8 мы рассмотрим другие применения оператора ALTER, включая изме- нение структуры таблиц, содержащих данные. Сейчас же перейдем к рассмотре- нию средств манипулирования данными в SQL. Средства запроса данных языка SQL даин^1^аблииыЖЛО ЗЭПИСЫВаТЬ ” “ее данные’ менять их значения и удалять Изучить опепятпп ^анные можно также запрашивать различными способами, че, если мы начнем ^Р^”азначенные для выполнения этих действий, будет лег- мощью SQL добавлять vna пҰа заПр<?са- После этого мы покажем, как с по- gvnp nr, ’ удалять и модифицировать данные в базу данных ГЙТЬ’ ЧТО данные- приведенные в табл . 6.1-6.3, уже введены Чтение заданных столбцов из одиночной таблицы Следующий SELECT FROM ератор запросит (прочтет) три из четырех столбцов таблицы ПРОЕКТ Название. Отдел. МаксТрудозатраты
Имена зап|>ашиваемых столбцов пе|>ечисляюгся после м»и>»,|.>1 пкмШКТ, а имя отношения, из которого считываются данные, указы».,.. и я поем* «,«МВВ* го слова FROM. Результатом этого оператора при использовании данных од таб- лицы ПРОЕКТ (см. табл 6.1) будет следующая таблица. КВЗ Анализ портфеля Финансы 75 0 КВЗ Подготовка налогового отчета Бухгалтерия 145 0 КВ4 Планирование номенклатуры изделий Маркетинг 138 0 КВ4 Анализ портфеля Финансы 1100 Результатом работы оператора SELECT всегда является отношение Этот опе- ратор берет одно или несколько отношении, манипулирует ими <И1;» м «ММЫМ образом и выдает на выходе одно отношение. Даже если результатом является всего лишь одно число, это число рассматривается как отношение, имеющее од- ну строку и один столбец. Порядок столбцов в результирующей таблице определяется порядком сле- дования их имен после ключевого слова SELECT. Допустим, мы поменяли п флжж имен столбцов в операторе SELECT следующим образом: SELECT Название, МаксТрудозатраты. Отдел FROM ПРОЕКТ; Результат работы оператора будет таким: КВЗ Анализ портфеля 75.0 Финансы КВЗ Подготовка налогового отчета 145 0 Бухгалтерия КВ4 Планирование номенклатуры изделий 138 0 Маркетинг КВ4 Анализ портфеля 110.0 Финансы Следующий оператор SELECT извлекает из таблицы ПРОЕКТ только столбец Отдел: SELECT Отдел FROM ПРОЕКТ; Результатом будет таблица: Финансы Бухгалтерия Маркетинг Финансы Обратите внимание, что первая и последняя строки этой таблицы одинаковы пустамо0оПРеЛеЛе,’ИЮ’ ДаШ‘ОМУ ” ГЛЛВС 41"овтоРение «Р™ и отношении вело- ?Х° 2Р°ЦССС П°ИСКа ” УДаЛСНИЯ ТЙК!,Х нов™Р™»й отнимает много к£ым.с£Х° РаЗОМ’ На П,Мет,,Ке "Се Же П|ПШ)Л,,ТО1 стакиваться с едина
278 Глава 6. Введение в язык SQL Если нужно, чтобы СУБД нашла и удалила одинаковые строки, при залро^ необходимо использовать ключевое слово DISTINCT- SELECT DISTINCT Отдел FROM ПРОЕКТ; Результат будет иметь вид Финансы Бухгалтерия Маркетинг Как и требовалось, дублирующаяся строка была удалена. Чтение заданных строк из одиночной таблицы Все приведенные выше SQL-операторы выбирали определенные столбцы всех строк таблицы. Можно сделать и наоборот — выбрать все столбцы определен- ных строк. Например, следующий оператор запрашивает все столбцы из тех строк таблицы ПРОЕКТ, которые содержат сведения о проектах финансового от- дела: SELECT ИдПроекта Название. Отдел. МаксТрудозатраты FROM ПРОЕКТ WHERE Отдел = 'Финансы': Результат имеет следующий вид: 1000 КВЗ Анализ портфеля Финансы 75.0 1500 КВ4 Анализ портфеля Финансы 110.0 Второй способ запросить все столбцы таблицы — использовать специальный символ * после ключевого слова SELECT. Приведенный ниже оператор эквивален- тен предыдущему: SELECT * FROM ПРОЕКТ WHERE Отдел = 'Финансы'; Результатом является таблица, содержащая все столбцы тех строк таблицы ПРОЕКТ, в которых находятся сведения о проектах финансового отдела: 1000 КВЗ Анализ портфеля Финансы 1500 КВ4 Анализ портфеля Финансы 75.0 110.0 Шаблон SELECT/FROM/WHERE — это фундаментальный шаблон построения SQL операторов SELECT. В предложении WHERE могут содержаться различного р0*1 условия. Например, следующий запрос извлекает все столбцы тех строк таблицы ПРОЕКТ, где значение столбца МаксТрудозатраты превышает 100:
Средства запроса данных пыа SQL 27® SELECT * FROM ПРОЕКТ WHERE МаксТрудозатраты > 100; Результат таков: 1200 КВЗ Подготовка налогового отчета Бухгалтерия 145 0 1400 КВ4 Планирование номенклатуры изделий Маркетинг 138 0 1500 КВ4 Анализ портфеля Финансы 110.0 Обратите внимание на то, что когда столбец имеет тип данных Char или VarChar, сравниваемые значения должны помещаться в одиночные кавычки. Если столбец имеет тип данных Integer или Numeric, кавычки необязательны. Так, например, для столбца Отдел, имеющего тип VarChar, мы используем в предложении WHERE запись Отдел = 'Финансы', а для столбца МаксТрудозатраты, имеющего тип Numeric, мы пишем просто МаксТрудозатраты = 100. ПРИМЕЧАНИЕ --------------------------------------------------------- Значения, помещенные в скобки, чувствительны к регистру символов. WHERE Отдел = "Финансы" и WHERE Отдел = "ФИНАНСЫ" — не одно и то же. В предложении WHERE можно указать более одного условия, если использо- вать ключевое слово AND: SELECT * FROM ПРОЕКТ WHERE Отдел = 'Финансы' AND МаксТрудозатраты > 100: Результат будет следующим: 1500 КВ4 Анализ портфеля Финансы 110.0 Чтение заданных строк и столбцов из одиночной таблицы Теперь, объединив описанные выше методы, мы можем выбрать из таблицы определенные столбцы и определенные строки. Например, следующий опера- тор извлекает из таблицы СОТРУДНИК столбцы Имя и Отдел сотрудников бухгал- терии: SELECT Иня, Отдел FROM СОТРУДНИК WHERE Отдел - 'Бухгалтерия': Этот запрос выдаст следующую таблицу: Мэри Джекобс Бухгалтерия Розали Джексон Бухгалтерия
280 Глава 6. Введение в язык SQL Еще одна форма предложения WHERE предполагает задание списка значений, которые может иметь столбец Это делается с помощью ключевогр слова IN SELECT Имя. Телефон, Отдел FROM СОТРУДНИК WHERE Отдел IN (’Бухгалтерия', 'Финансы'. 'Маркетинг'), Результат таков: Мэри Джекобс 285-8879 Бухгалтерия Кенджи Нюмото 287-0098 Маркетинг Хэзер Джонс 287-9981 Финансы Розали Джексон 285-1273 Бухгалтерия Ким Сунг 287-3222 Маркетинг Строка исходного отношения войдет в результирующую таблицу, если ее столбец Отдел имеет значение 'Бухгалтерия', 'Финансы' или 'Маркетинг'. Чтобы выбрать строки, у которых столбец Отдел не равен ни одному из этих значений, используйте ключевое слово NOT IN: SELECT Имя. Телефон. Отдел FROM СОТРУДНИК WHERE Отдел NOT IN ('Бухгалтерия'. 'Финансы', 'Маркетинг'); Результат этого запроса будет следующим: Джеймс Нестор Инф. системы Ричард By 287-0123 Инф. системы Обратите внимание на принципиальное различие между ключевыми словами IN и NOT IN. При использовании IN столбец может иметь любое из значений, указанных в списке. При использовании NOT IN столбец не должен принимать ни одно из перечисленных значений. Диапазоны, специальные символы и пустые значения в предложениях WHERE В предложениях WHERE могут также указываться диапазоны и шаблоны поиска. Длг задания диапазонов используется ключевое слово BETWEEN. Например, оператор SELECT Имя. Отдел FROM СОТРУДНИК WHERE ТабельныйНомер BETWEEN 200 AND 500 даст следующий результат: Кенджи Нюмото Хэзер Джонс Розали Джексон Джеймс Нестор Маркетинг Финансы Бухгалтерия Инф. системы
Средства запроса данных языка SQL 281 Этот оператор эквивалентен следующему: SELECT Имя. Отдел FROM СОТРУДНИК WHERE ТабельныйНомер >= 200 AND ТабельныйНомер <= 500; Таким образом, диапазон, задаваемый ключевым словом BETWEEN, включает в себя граничные значения (здесь 200 и 500). Для задания шаблонов поиска в SQL используется ключевое слово LIKE. Сим- вол подчеркивания (_) представляет любой одиночный символ. С его помощью можно находить значения, удовлетворяющие заданному шаблону: SELECT * FROM ПРОЕКТ WHERE Имя LIKE 'КВ_ Анализ портфеля': Подчеркивание означает, что на данном месте может стоять любой символ. Результатом этого оператора является следующая таблица: 1000 КВЗ Анализ портфеля Финансы 75.0 1500 КВ4 Анализ портфеля финансы 110.0 Чтобы найти всех сотрудников, чей номер телефона начинается с '285', мож- но четыре последние цифры номера представить символами подчеркивания: SELECT * FROM СОТРУДНИК WHERE Телефон LIKE '285-_'; Результатом будет таблица: 100 Мэри Джекобс 285-8879 Бухгалтерия 400 Розали Джексон 285-1273 Бухгалтерия Символ процента (%) представляет последовательность из одного или несколь- ких произвольных символов. Запрос, возвращающий строки сотрудников с но- мерами телефонов, начинающимися с '285', можно записать по-другруу: SELECT * FROM СОТРУ/JWK **RE Телефон LIKE '285X'; Результат будет тем же самым. можно НаЙ™ СОТРУДНИКОВ- ч”и имена заканчиваются на букву с ЖНО использовать символ процента следующим образом- ’ SELECT FROM СОТРУДЦЖ Имя LIKE *Хс';
282 Глава 6, Введение в язык SOL Результат будет таким: 100 Мэри Джекобс 285-8879 Бухгалтерия 300 Хэзер Джонс 287-9981 Финансы Между прочим, в Microsoft Access используются иные символы, чем в стад, дарте SQL-92. Функцию символа подчеркивания выполняет вопросительно знак (?), а функцию знака процента — звездочка (*). Для поиска пустых значений в предложении WHERE служит ключевое слово Следующий запрос выдает имена и названия отделов всех сотрудников, для ко- торых не указан номер телефона: SELECT Имя. Отдел FROM СОТРУДНИК WHERE Телефон IS NULL; Результат запроса будет таким: Джеймс Нестор Инф. системы Сортировка результатов Порядок строк в таблице, возвращаемой оператором SELECT, является произволь- ным. Если нужно отсортировать строки результата, это можно сделать с помощью конструкции ORDER BY. Например, следующий запрос возвращает имена и назва- ния отделов всех сотрудников, отсортированные в алфавитном порядке по назва- ниям отделов: SELECT Имя. Отдел FROM СОТРУДНИК ORDER BY Отдел: Результатом будет следующая таблица: Мэри Джекобс Бухгалтерия Розали Джексон Бухгалтерия Джеймс Нестор Инф. системы Ричард By Инф. системы Кенджи Нюмото Маркетинг Ким Сунг Маркетинг Хэзер Джонс Финансы По умолчанию сортировка в SQL производится в порядке возрастания. Д\ явною указания порядка сортировки можно использовать ключевые слова А$С (по возрастанию) и DESC (по убыванию). Например, следующий запрос отсорт*1' рует сотрудников по названиям отдела в обратном порядке:
Средства запроса данных «зыка 8QI 283 SELECT Имя, Отдел FR0M СОТРУДНИК ORDER BY Отдел DESC: Результат будет таким: Хэзер Джонс Ким Сунг Кенджи Нюмото Ричард By Джеймс Нестор Розали Джексон Мэри Джекобс Финансы Маркетинг Маркетинг Инф. системы Инф. системы Бухгалтерия Бухгалтерия Сортировать можно и более чем по одному столбцу. Чтобы отсортировать список имен сотрудников и их отделов сначала по названиям отделов в обрат- ном порядке, а потом внутри каждого отдела по именам в прямом порядке, мож- но было бы использовать такой запрос: SELECT Имя. Отдел FROM СОТРУДНИК ORDER BY Отдел DESC. Имя ASC; Это приведет к следующему результату: Хэзер Джонс Кенджи Нюмото Ким Сунг Джеймс Нестор Ричард By Мэри Джекобс Розали Джексон Финансы Маркетинг Маркетинг Инф. системы Инф. системы Бухгалтерия Бухгалтерия Встроенные функции SQL В SQL имеется пять встроенных функций: COUNT, SUM, AVG, МАХ и MIN. Они выпол- няют различные действия над результатами оператора SELECT. Функция COUNT ра- ботает вне зависимости от типа данных столбца, а функции SUM, AVG, МАХ и MIN оперируют только числовыми столбцами (Integer, Numeric и т. д.). Функция COUNT подсчитывает количество строк в результате, а функция SUM вычисляет сумму значений числового столбца. Например, следующий SQL-one- ратор подсчитывает количество строк в таблице ПРОЕКТ: SELECT COUNTC*) FROM СОТРУДНИК: Результатом этого оператора является следующее отношение: 4
284 Глава 6. Введение в язык SQL Как уже говорилось ранее, результдюм SQL-оператора SELECT всегда a»w ся отношение. Если, как в данном случае, релультат представляет собой й, ное число, это число нее равно считается отношением, имеющим одну гн и один столбец. Рассмотрим следующие два onepaiopa; SELECT СОиИТ(Отдел) FROM ПРОЕКТ: и SELECT COUNTCDISTINCT Отдел) FROM ПРОЕКТ; Результатом первого оператора будет отношение 4 Результатом второго оператора будет отношение 3 Разница в ответах возникает потому, что второй оператор SELECT не учитыва- ет повторяющиеся строки. Вот еще один пример использования встроенных функций: SELECT МШМаксТрудозатраты). МАХ(МаксТрудозатраты). SUM(Ма ксТрудоз а т ра ты) FROM ПРОЕКТ WHERE ИдПроекта < 1500; Результатом будет следующая таблица: 75.00 145.00 358.00 Кроме случая с использованием ключевых слов GROUP BY (см. ниже), нМ столбцов не могут смешиваться со встроенными функциями. Например, сл ДУ 1ций оператор недопустим: SELECT Название. $иМ(МаксТрудозатраты) FROM ПРОЕКТ WHERE ИдПроекта < 1500; Кро ПЫХ СУБД, в частности в "танпз«oiC 1 рое1ШЪ1Х Функции различаются в раз- Функции не могут фигупипо™ S^L'92 “ « большинстве СУБД встроенн^ стве случаев будет недопустим? * предложе«иях WHERE. Например, в больший WHERE м. предложене WHERE: H«P„03aIpaiu < «<„аксТрмюЛраи)
Средства запроса данных языка SQL 285 Встроенные функции и группировка Полезность встроенных функций увеличивает тот факт, что их можно применят^ к группам строк данных. Например, следующий оператор подсчитывает количе- ство сотрудников в каждом отделе: SELECT FROM GROUP BY Отдел. COUNT!*) СОТРУДНИК Отдел: Результат будет таким: Бухгалтерия 2 Инф. системы 2 Маркетинг 2 Финансы 1 Ключевое слово GROUP BY предписывает СУБД отсортировать таблицу по указанному столбцу, а затем применить встроенные функции к группам строк, имеющим одинаковые значения данного столбца. При использовании GROUP BY имя столбца, по которому производится группировка, и встроенные функции могут сосуществовать в предложении SELECT. Это единственный случай, когда имя столбца можег появляться вместе со встроенными функциями. Далее ограничить множество выдаваемых результатов можно, применяя к фор- мируемым группам различные условия. Например, если нас интересуют только те группы, в которых имеется более одной записи, мы могли бы написать сле- дующее: SELECT Отдел. COUNT(*) FROM СОТРУДНИК GROUP BY Отдел HAVING COUNT!*) > 1; Результатом этого оператора будет следующая таблица: Бухгалтерия 2 Инф системы 2 Маркетинг 2 WHFRipeCTe С КЛ1очевым словом GROUP BY можно использовать и предложение ERE. Однако здесь имеет место неоднозначность. Если условие в предло- жении WHERE применяется до формирования групп, результат будет иным, чем когда это условие применяется к уже сформированным' группам. Для устране я этой неоднозначности стандарт SQL устанавливает, что в случаях, когда предложения WHERE и GROUP BY используются одновременно, первым дол™
286 Глава 6. Введение в язык SOL применяться условие, записанное в предложении WHERE. Рам,мО|рим __ следующий оператор: SELECT Отдел. COUNTC*) FROM СОТРУДНИК WHERE ТабельныйНомер < 600 GROUP BY Отдел HAVING COUNTC*) > 1; При выполнении данного оператора сначала применяется условие из преддо жения WHERE, которое отбирает сотрудников, чей табельный номер меньше 600 Затем, после формирования групп, применяется условие из предложения HAYING Результат имеет следующий вид: Бухгалтерия 2 Чтение данных из нескольких таблиц с применением вложенных запросов Все запросы, рассмотренные нами до сих пор, считывали данные из одиночной таблицы. Бывает, однако, что для получения требуемой информации необходимо обработать более одной таблицы. Предположим, например, что мы хотим знать имена сотрудников, проработавших в рамках любого из своих назначений более 40 часов. Имена сотрудников хранятся в таблице СОТРУДНИК, а количество отра- ботанных ими часов - в таблице НАЗНАЧЕНИЕ. Если бы мы знали, что более 40 часов трудозатрат по назначению имеется у сотрудников с номерами 100 и 500, мы бы могли получить имена этих сотруд- ников с помощью следующего оператора: SELECT DISTINCT Имя FROM СОТРУДНИК WHERE ТабельныйНомер IN (100. 500); Но в том то и дело, что в условии задачи номера сотрудников нам не даны. прос°' °ДНаК°’ не мешает нам узнать эти номера, инициировав следующий за SELECT НомерСотрудника FROM НАЗНАЧЕНИЕ WHERE ФактТрудозатраты > 40: Результатом будет таблица: 100 400 600 200
Средства заир языка ъмс Ж87 Теперь мы можем объединить эти два SQL-oik ратора при помощи там .... .и ваемого вложенного запроса (subquery): SELECT FROM WHERE DISTINCT Имя СОТРУДНИК ТабельныйНомер IN (SELECT НомерСотрудника FROM НАЗНАЧЕНИЕ WHERE ФактТрудозатраты > 40): Результатом этого оператора будет следующее: Кенджи Нюмото Мэри Джекобс Ричард By Розали Джексон И действительно, здесь мы видим имена сотрудников, проработавших над ка- ким-либо из своих назначений более 40 часов. Вложенность запросов может быть расширена до трех, четырех и более уров- ней. Предположим, например, нам нужно знать имена сотрудников, проработав- ших более 40 часов в проекте, который оплачивается бухгалтерией. Идентификаторы проектов, оплачиваемых бухгалтерией, можно узнать при помощи следующего запроса: SELECT ИдПроекта FROM ПРОЕКТ WHERE Отдел = 'Бухгалтерия': Номера сотрудников, проработавших более 40 часов в рамках этих проектов, возвратит такой оператор: SELECT НомерСотрудника FROM НАЗНАЧЕНИЕ WHERE ФактТрудозатраты > 40 AND ИдПроекта IN (SELECT ИдПроекта FROM ПРОЕКТ WHERE Отдел - 'Бухгалтерия') Наконец, имена сотрудников, номера которых мы только что узнали, можно определить с помощью следующего оператора' SELECT DISTINCT Имя FROM СОТРУДНИК WHERE ТабельныйНомер IN (SELECT НомерСотрудника FROM НАЗНАЧЕНИЕ WHERE ФактТрудозатраты > 40 AND ИдПроекта IN
288 Глава 6. Введение в язык SQL (SELECT ИдПроекта FROM ПРОЕКТ WHERE Отдел - 'Бухгалтерия')), Результатом будет таблица: Мэри Джекобс Ричард By Розали Джексон Чтение данных из нескольких таблиц с помощью операции соединения Вложенные запросы подходят для обработки нескольких таблиц до тех пор, пока результаты (столбцы в предложении SELECT) относятся к одной и той же таблице. Если же нам нужно извлечь данные из двух или более таблиц, при помощи вло- женного запроса это сделать не удастся. Вместо эюго необходимо использовать операцию соединения (join). Основная идея здесь — создать повое отношение, связав между собой содер- жимое двух или более исходных отношений. Рассмотрим следующий пример: SELECT Имя. ФактТрудозатраты FROM СОТРУДНИК. НАЗНАЧЕНИЕ WHERE ТабельныйНомер = НомерСотрудника; мысл этого оператора заключается в том, что создается новая таблица с дву- мя стол цами, Имя и ФактТрудозатраты. Эти столбцы берутся соответственно из гшг П гптРчпиш/ИК И НА^НАЧЕНИЕ ПРИ условии, что столбец ТабельныйНомер в таб- ше РУДНИК равен столбцу НомерСотрудника в таблице НАЗНАЧЕНИЕ. <2 “7Ра11ИЮХТН° пРедставить себе следующим образом. Начнем с первой сгпоке о Возьмем значение столбца ТабельныйНомер в данной Найля В 6,2 илэЛ г И ,1р0СМОТРим строки таблицы НАЗНАЧЕНИЕ (табл. 6.3). соедини Л'/7 и С1Р°ку, где НомерСотрудника также равняется юо: дозатоаты топ??** ИМЯ "ерВ°И СГроКИ таблицы СОТРУДНИК со столбцом ФактТру- Пеовэя ™ ЧТк Наиде1ШОИ строки таблицы НАЗНАЧЕНИЕ. ный 100 нтт°Ка T l ЛИЦЬ1 НАЗНАЧЕНИЕ (см. табл. 6.3) имеет НомерСотрудника, рав- ен столбцом ФактТМЬ1 соедипяем столбец Имя первой строки таблицы СОТРУДНИК тем самым пепт™ РУДОзатраты пеР»ой строки таблицы НАЗНАЧЕНИЕ, и получаем тем самым первую строку соединения: Мэри Джекобс 17,5 1еперь, по-прежнему используя ТабельныйНомер = 100, найдем вторую строку в отношении НАЗНАЧЕНИЕ, которая имеет НомерСотрудника, равный 100“ В нашем СПтрупммн УДСТ “ятая строка. Соединив столбец Имя первой строки таблицы СОТРУДНИК со столбцом ФактТрудозатраты пятой строки таблицы НАЗНАЧЕНИЕ, мы получим вторую строку соединения-
Средства запроса данных и 8OL Мэри Джекобс 17.50 Мэри Джекобс 45 75 Продолжим в той же манере, разыскивая строки, в которых НомерСотрудника равен 100. В нашем случае таких строк больше не окажется, поэтому перейдем ко второй строке отношения СОТРУДНИК, в которой ТабельныйНомер - 200. Будем теперь искать соответствующие ей строки в отношении НАЗНАЧЕНИЕ. У нас восьмая строка отношения НАЗНАЧЕНИЕ (см. табл. 6.3) имеет НомерСотрудника, равный 100, и мы получаем третью строку результата, соединяя столбцы Имя и ФактТрудозатраты Мэри Джекобс 17.50 Мэри Джекобс 45.75 Кенджи Нюмото 75.00 Будем продолжать далее, пока не будут перебраны все строки отношения СОТРУДНИК. Окончательный результат будет таким: Мэри Джекобс 17.50 Мэри Джекобс 45.75 Кенджи Нюмото 75.00 Хэзер Джонс 12 50 Розали Джексон 8.00 Розали Джексон 70.50 Джеймс Нестор 20.25 Джеймс Нестор 25.25 Ричард By 40.50 Ким Сунг 20.25 Обработка результирующей таблицы Таблицу, получившуюся в результате соединения, можно обрабатывать так же, как и любую другую таблицу. Например, мы можем сгруппировать строки по именам сотрудников и просуммировать количество часов, отработанных ими. Это сделает следующий запрос: SELECT Имя. 511М(ФактТрудозатраты) FROM СОТРУДНИК. НАЗНАЧЕНИЕ WHERE ТабельныйНомер = НомерСотрудника; GROUP BY Имя; Результатом будет следующая таблица: Джеймс Нестор 45.50 Кенджи Нюмото 75.00 Ким Сунг 20 25 Мэри Джекобс 63.25 Ричард Ву 40.50
290 Глава 6. Введение в язык SQL Розали Джексон 78 50 Хэзер Джонс 12.50 Предложение WHERE мы также можем применить в процессе создания соеди- нения: SELECT Имя, ФактТрудозатраты FROM СОТРУДНИК. НАЗНАЧЕНИЕ WHERE ТабельныйНомер = НомерСотрудника AND ФактТрудозатраты > 40: Результат соединения будет таким: Мэри Джекобс 45.75 Розали Джексон 70.50 Ричард By 40.50 Кенджи Нюмото 75.00 Это такая же таблица, поэтому все описанные выше SQL-операторы к ней применимы. Теперь предположим, что мы хотим соединить информацию о проектах и на- значениях. Структура SQL-оператора для выполнения этого запроса может быть той же, что и прежде, но здесь есть одна трудность. У нас имеется два столбца с именем ИдПроекта: один — в таблице ПРОЕКТ, а другой — в таблице НАЗНАЧЕНИЕ. Этот конфликт имен можно разрешить уже известным вам способом — присо- единив к имени столбца имя таблицы, которой он принадлежит. Таким образом, столбец ИдПроекта в таблице ПРОЕКТ мы будем обозначать как ПРОЕКТ.ИдПроекта, а столбец ИдПроекта в таблице НАЗНАЧЕНИЕ — как НАЗНАЧЕНИЕ.ИдПроекта. При использовании такой записи оператор, выполняющий соединение таблиц ПРОЕКТ и НАЗНАЧЕНИЕ, будет выглядеть следующим образом: SELECT Название. ФактТрудозатраты FROM ПРОЕКТ. НАЗНАЧЕНИЕ WHERE ПРОЕКТ.ИдПроекта = НАЗНАЧЕНИЕ.ИдПроекта; Результат будет таким: КВЗ Анализ портфеля 17.50 КВЗ Анализ портфеля 12.50 КВЗ Анализ портфеля 8.00 КВЗ Анализ портфеля 20.25 КВЗ Подготовка налогового отчета 45.75 КВЗ Подготовка налогового отчета 70.50 КВЗ Подготовка налогового отчета 40.50 КВ4 Планирование номенклатуры изделий 75.00 КВ4 Планирование номенклатуры изделий 20.25 КВ4 Планирование номенклатуры изделий 25.25
Средства запроса данных язык» 8OL 291 Результаты, показанные здесь, являются правильными, но несколько неожи- данными. Что случилось с проектом под названием 'КВ4 Анализ портфеля7 Ом отсутствует среди результатов соединения, поскольку в таблице НАЗНАЧЕНИЕ ве нашлось строки, в которой столбец ИдПроекта был бы равен 1500. Это абсолютно законно: необходимо просто иметь в виду, что строки, для которых не выполне- но условие равенства, не включаются в результат соединения. Соединение трех таблиц Мы обсудим проблему исчезающей строки далее, но прежде рассмотрим случай, когда требуется соединить три таблицы. Предположим, нам нужно знать назва- ние каждого проекта, имена всех сотрудников, работающих в проекте, и фактиче- ские трудозатраты каждого из сотрудников. Чтобы получить эти результаты, не- обходимо соединить все три таблицы: SELECT ПРОЕКТ.Название. ФактТрудозатраты. СОТРУДНИК.Имя FROM ПРОЕКТ, НАЗНАЧЕНИЕ. СОТРУДНИК WHERE ПРОЕКТ.ИдПроекта = НАЗНАЧЕНИЕ.ИдПроекта AND СОТРУДНИК ТабельныйНомер = НАЗНАЧЕНИЕ.НомерСотрудника Результатом соединения будет следующая таблица: КВЗ Анализ портфеля 17.50 Мэри Джекобс КВЗ Анализ портфеля 12.50 Хэзер Джонс КВЗ Анализ портфеля 8.00 Розали Джексон КВЗ Анализ портфеля 20.25 Джеймс Нестор КВЗ Подготовка налогового отчета 45.75 Мэри Джекобс КВЗ Подготовка налогового отчета 70.50 Розали Джексон КВЗ Подготовка налогового отчета 40.50 Ричард By КВ4 Планирование номенклатуры изделий 75.00 Кенджи Нюмото КВ4 Планирование номенклатуры изделий 20.25 Ким Сунг КВ4 Планирование номенклатуры изделий 25.25 Джеймс Нестор Альтернативный синтаксис соединения В стандарте SQL-92 введен альтернативный синтаксис соединения, ставший весь- ма популярным, поскольку его легче интерпретировать. Здесь вместо WHERE ис- пользуются ключевые слова JOIN и 0N: SELECT Имя. ФактТрудозатраты FROM СОТРУДНИК JOIN НАЗНАЧЕНИЕ 0N СОТРУДНИК ТабельныйНомер = НАЗНАЧЕНИЕ.НомерСотрудника Результат имеет следующий вид: Мэри Джекобс ~ 17.50 Мэри Джекобс 45.75 ^нджи Нюмото 75.00
292 Глава 6. введение в язык SQI Хэзер Джонс 12.50 Розали Джексон 8 00 Розали Джексон 70.50 Джеймс Нестор 20.25 Джеймс Нестор 25.25 Ричард By 40.50 Ким Сунг 20.25 Сделать оператор соединения более удобным для чтения можно, используя псевдонимы для имен таблиц. Выражение FROM СОТРУДНИК С присваивает табли- це СОТРУДНИК псевдоним С. Это позволяет переписать предыдущий оператор сле- дующим образом: SELECT Имя. ФактТрудозатраты FROM СОТРУДНИК AS С JOIN НАЗНАЧЕНИЕ AS Н ON С.ТабельныйНомер = Н.НомерСотрудника: Соединение трех таблиц можно выполнить путем добавления предложения JOIN в конец первого оператора SELECT: SELECT П.Название. ФактТрудозатраты. С.Имя FROM ПРОЕКТ П JOIN НАЗНАЧЕНИЕ К ON П.ИдПроекта = Н.ИдПроекта JOIN СОТРУДНИК С ON Н.НомерСотрудника = С.ТабельныйНомер Обратите внимание, что когда требуется указать имя столбца в первой стро- ке оператора SELECT, необходимо использовать псевдоним, а не имя таблицы. Так, в вышеприведенном операторе SELECT используется запись П.Название, а не ПРОЕКТ.Название. Также обратите внимание на то, что ключевое слово AS при же- лании можно опустить. По мере того как запросы усложняются, этот формат оказывается легче ин- терпретировать, и именно его мы будем использовать для всех соединений в гла- вах 7 и 8. Тем не менее, знать необходимо оба формата, поскольку и тот, и другой используются в промышленности. Сравнение вложенного запроса и соединения Соединение во многих случаях можно использовать в качестве альтернативы вложенным запросам. Например, мы использовали вложенный запрос для нахо ждения имен сотрудников, которые проработали более 40 часов в проекте. Этот же запрос можно реализовать и с помощью соединение: SELECT DISTINCT Имя FROM СОТРУДНИК JOIN НАЗНАЧЕНИЕ ON СОТРУДНИК.ТабельныйНомер = НАЗНАЧЕНИЕ.НомерСотрудника AND ФактТрудозатраты > 40;
Средства запроса данных язык» SQt 2®3 Хотя ситуации, когда соединение можно использовать вместо вложенного за- проса, нередки, такая замена все же возможна не всегда. Например, соединения не могут заменить коррелированные вложенные запросы, а также запросы с ис- пользованием ключевых слов EXISTS и NOT EXISTS (глава 8). И наоборот, не всегда вложенный запрос может служить заменой для соеди- нения. В соединении запрашиваемые столбцы могут принадлежать любой из со- единяемых таблиц, а во вложенном запросе все возвращаемые столбцы должны принадлежать только одной таблице, а именно той, которая указана в предложе- нии FROM самого первого оператора SELECT. Например, в следующем вложенном запросе в результат войдут только столбцы таблицы СОТРУДНИК: SELECT DISTINCT Имя FROM СОТРУДНИК WHERE ТабельныйНомер IN (SELECT НомерСотрудника FROM НАЗНАЧЕНИЕ WHERE ИдПроекта IN (SELECT ИдПроекта FROM ПРОЕКТ WHERE Отдел = 'Бухгалтерия')); Если нужно включить в результат столбцы НАЗНАЧЕНИЕ.ФактТрудозатраты и ПРОЕКТ.Название, придется использовать соединение: SELECT СОТРУДНИК.Имя. ФактТрудозатраты. ПРОЕКТ.Название FROM СОТРУДНИК. НАЗНАЧЕНИЕ. ПРОЕКТ WHERE СОТРУДНИК.ТабельныйНомер = НАЗНАЧЕНИЕ.НомерСотрудника AND НАЗНАЧЕНИЕ.ИдПроекта = ПРОЕКТ.ИдПроекта: или, используя альтернативный формат записи соединения: SELECT С.Имя. ФактТрудозатраты. П.Название FROM СОТРУДНИК JOIN НАЗНАЧЕНИЕ ON НАЗНАЧЕНИЕ.НомерСотрудника = СОТРУДНИК.ТабельныйНомер JOIN ПРОЕКТ DN НАЗНАЧЕНИЕ.ИдПроекта - ПРОЕКТ.ИдПроекта: Внешние соединения в одном из приведенных ранее примеров мы столкнулись с тем, что при выпол- нении соединения могут быть потеряны данные. В частности, если строка имеет значение, которое не удовлетворяет условию, заданному в предложении WHERE, эта строка не будет включена в результат соединения. Мы потеряли при соедине- нии строку *КВ4 Анализ портфеля', поскольку в таблице НАЗНАЧЕНИЕ не оказалось строки с таким же значением ИдПроекта, как в предложении WHERE. Такая потеря может быть нежелательной, и для предотвращения подобных ситуаций был вве- Дсн специальный тип соединения — внешнее соединение (outer join).
294 [лава 6 Во«д<>ние в язык SQL Если нужно построить соединение таким сюр.. иш, чтобы « ргЛ лыппМ каждая строка таблицы следе от ключевом* с .i-imJOIN, даж« «сям для апод стр», ки не имеется соответствия во второй таблице, то необходимо и. <... мтъщ, дующий синтаксис: SELECT Название. ФактТрудозатраты FROM ПРОЕКТ LEFT JOIN НАЗНАЧЕНИЕ ON ПРОЕКТ.ИдПроекта - НАЗНАЧЕНИЕ ИдПроекта, Смысл этого оператора в том, что строки таблицы ПРОЕКТ Соедикяюю^ £© строками таблицы НАЗНАЧЕНИЕ, как и раньше, но теперь, если какая-то Сфот в таблице слева от ключевого слова JOIN (здесь это таблица ПРОЕКТ) не имеетсо- ответствия в таблице, находящейся справа, эта строка все равно будет ключе* в результат. Такое соединение называется левым внешним соединением (left outer join). Для данных из табл. 6.1-6.3 результат этого запроса будет таким: КВЗ Анализ портфеля 17.50 КВЗ Анализ портфеля 12.50 КВЗ Анализ портфеля 8.00 КВЗ Анализ портфеля 20.25 КВЗ Подготовка налогового отчета 45.75 КВЗ Подготовка налогового отчета 70.50 КВЗ Подготовка налогового отчета 40.50 КВ4 Планирование номенклатуры изделий 75.00 КВ4 Планирование номенклатуры изделий 20.25 КВ4 Планирование номенклатуры изделий 25.25 КВ4 Анализ портфеля Null Как видите, в последней строке результата столбец 'КВ4 Анализ портфеля' со- единен с пустым столбцом. Правое внешнее соединение (right outer join) функционирует аналогичным об- разом, только в результат включаются все строки таблицы, находящейся от ключевого слова JOIN: SELECT Название, ФактТрудозатраты FROM ПРОЕКТ RIGHT JOIN НАЗНАЧЕНИЕ ON ПРОЕКТ.ИдПроекта = НАЗНАЧЕНИЕ.ИдПроекта; Внешние соединения могут быть вложенными. Например, мы можем соедя- нить все три таблицы следующим образом: SELECT ПРОЕКТ.Название. ФактТрудозатраты. СОТРУДНИК Имя FROM ((ПРОЕКТ LEFT JOIN НАЗНАЧЕНИЕ ON ПРОЕКТ.ИдПроекта » НАЗНАЧЕНИЕ ИдПроекта) LEFT JOIN СОТРУДНИК ON СОТРУДНИК.ТабельныйНомер - НАЗНАЧЕНИЕ.НомерСотрудника).
Средства модификации данных языка SQL 295 Результат этого соединения будет следующим: КВЗ Анализ портфеля 17.50 Мэри Джекобс KB3 Анализ портфеля 12.50 Хэзер Джонс КВЗ Анализ портфеля 8.00 Розали Джексон КВЗ Анализ портфеля 20.25 Джеймс Нестор КВЗ Подготовка налогового отчета 45.75 Мэри Джекобс КВЗ Подготовка налогового отчета 70.50 Розали Джексон КВЗ Подготовка налогового отчета 40.50 Ричард By КВ4 Планирование номенклатуры изделий 75.00 Кенджи Нюмото КВ4 Планирование номенклатуры изделий 20.25 Ким Сунг КВ4 Планирование номенклатуры изделий 25.25 Джеймс Нестор КВЗ Анализ портфеля Null Null Средства модификации данных языка SQL Модификация данных подразумевает три возможных операции вставка, изменение и удаление. Посмотрим, как выполняются эти операции средствами языка SQL. Вставка данных Для вставки данных в таблицы служит SQL-оператор INSERT. Этот оператор име- ет две формы, в зависимости от того, всем ли столбцам таблицы присваиваются значения. Если указываются значения всех столбцов, то оператор имеет следу- ющий вид: INSERT INTO ПРОЕКТ VALUES (1600. 'КВ4 Подготовка налогового отчета'. 'Бухгалтерия', 100): Оо] атпге внимание, что значения типа Integer и Numeric нс заключаются в ка- выч! н, в отличие от Char и VarChar. Если данные для каких-то столбцов отсутствуют, необходимо перечислить имена столбцов, которым будут присвоены значения. Например, следующий опе- ратор добавляет в таблицу ПРОЕКТ строку, в которой столбцам Название и ИдПроек- та присвоены значения, а столбцы Отдел и МаксТрудозатраты оставлены пустыми: INSERT INTO ПРОЕКТ (Название. ИдПроекта) VALUES СКВ4 Подготовка налогового отчета'. 1700); В-пом 1ите, однако, что при создании таблицы ПРОЕКТ в операторе CREATE TABLE Для столбца МаксТрудозатраты было задало начальное значение 100, поэтому несмот- ря на то, что в операторе INSERT значение этому столбцу не присваивалось, СУБД все равно установит его равным 100. Столбец Отдел будет иметь пустое значение. с-сть несколько дополнительных замечаний, которые следует сделать по по- еду второй формы оператора INSERT. Во-первых, порядок, в котором перечис- В ПТСЯ Значенпя столбцов, должен соответствовать порядку следования их имен Редыдущем примере имена столбцов идут в порядке (Название, ИдПроекта)
296 Глава 6. Введение в язык SQL поэтому сначала должно быть указано значение столбца Название, а йотом Й*. Проекта. (Кстати, столбцы в таблице идут в друюм иорядке ) Во взоры*. вставка была выполнена, необходимо задать значения и < х столбцов, оиредэдед. ных как NOT NULL. В-третьих, в обеих формах INSERT, если первичный ключ является сурропл ным ключом, его значение указывать не нужно: это за нас сделает СУБД Сдедо- вательно, если ИдПроекта является суррогатным ключом, то вставку строки но* но произвести следующим образом' INSERT INTO ПРОЕКТ VALUES ('КВ4 Подготовка налогового отчета'. 'Бухгалтерия'. 100); Значение столбцу ИдПроекта присвоит СУБД. Между прочим, если вы исполь- зуете Oracle, это происходит несколько по-другому, как вы узнаете из главы 10 Наконец, если требуется скопировать большое количество данных из другой таблицы, их значения можно получить с помощью оператора SELECT. Например, следующий оператор копирует значения столбцов Имя и ТабельныйНомер из таб- лицы СОТРУДНИК в таблицу под названием СОТРУДНИК!: INSERT INTO С0ТРУДНИК1 (Имя. ТабельныйНомер) SELECT Имя. ТабельныйНомер FROM СОТРУДНИК; Обратите внимание, что в этом случае ключевое слово VALUES не входит в опе- ратор SELECT. Изменение данных СОТРУДНИК Телефон = '287-1435' Имя = 'Джеймс Нестор’; оператор устанавливает значение столбца Телефон в строке сотрудника Г .Г П\1/Ли и у. 11л _ л . f л л — - . — 11 Значения существующих данных могут быть изменены с помощью SQL-оператора UPDATE. Имейте в виду, что это мощная команда, и ее следует использовать с осто- рожностью. Рассмотрим следующий пример: UPDATE SET WHERE Этот по имени Джеймс Нестор равным ’287-1435'. Теперь посмотрим, что имелось в виду, когда мы говорили об осторожности, опу стим, что собираясь произвести это изменение, вы сделали ошибку и забы- ли про предложение WHERE. Таким образом, вы передали на исполнение СУБД следующий оператор: UPDATE СОТРУДНИК SET Телефон = '287-1435'; После этого отношение СОТРУДНИК примет следующий вид: 100 Мэри Джекобс 287-1435 Бухгалтерия 200 Кенджи Нюмото 287-1435 Маркетинг 3°°^, Хэзер Джонс 287-1435 Финансы
Средства модификации данных я»ык» SQL 400 Розали Джексон 287-1435 Бухгалтерия 500 Джеймс Нестор 287 1435 Инф. системы 600 Ричард By 287-1435 Инф. системы 700 Ким Сунг 287-1435 Маркетинг Это явно не то, что вы хотели осуществить. А представьте, что вы сделали бы это на вашей новой работе, причем в таблице СОТРУДНИК было бы, скажем, 10 000 строк... В общем, смысл таков: оператор UPDATE весьма мощен и прост в использова- нии, но может приводить к печальным последствиям. С помощью оператора UPDATE можно обновлять и несколько столбцов за один прием. Это демонстрирует следующий пример: UPDATE СОТРУДНИК SET Телефон - '287-1435'. Отдел = 'Производство' WHERE ТабельныйНомер = 200; Эта команда изменяет значения столбцов Телефон и Отдел _пя указанного со- трудника. Удаление данных Для удаления строк служит SQL-оператор DELETE. К нему относятся те же самые предостережения, что и к оператору UPDATE. Он обманчиво прост в использова- нии, и неосторожное его применение может привести к самым неожиданным по- следствиям. Следующий оператор удаляет из таблицы ПРОЕКТ данные обо всех проектах, спонсируемых бухгалтерией: DELETE FROM ПРОЕКТ WHERE Отдел - 'Бухгалтерия'; В связи с ограничением ссылочной целостности ON DELETE CASCADE эта опера- ция удаляет не только строки таблицы ПРОЕКТ, но и все связанные с ними строки в таблице НАЗНАЧЕНИЕ. Для данных из табл,. 6 1-6.3 этот оператор удаляет пятую и седьмую строки таблицы НАЗНАЧЕНИЕ. Как и в случае с оператором UPDATE, если вы забудете указать предложение WHERE, последствия будут катастрофическими. Например, следующий оператор Удаляет все строки из отношения ПРОЕКТ (а вместе с ними, ввиду ограничения ON ELETE CASCADE, и все связанные с ними строки отношения НАЗНАЧЕНИЕ). delete FROM ПРОЕКТ. Это действительно будет беда! Обратите внимание на различия в процедурах обеспечения ссылочной цело- °СТи между таблицами ПРОЕКТ и СОТРУДНИК. Если мы попытаемся выполнить
298 Глава 6. Введение в язык SQL следующую команду, нас постигнет неудача, поскол1’ку У^3анК<1Я CfPWaTaW цы СОТРУДНИК имеет дочерние строки в таблице НАЗНАЧЕНИЕ DELETE FROM СОТРУДНИК WHERE ТабельныйНомер = 100 Если требуется удалить строку этого сотрудника, необходимо сначала пере- назначить или удалить соответствующие строки в таблице НАЗНАЧЕНИЕ. Резюме SQL представляет собой подъязык данных, содержащий конструкции для созда- ния и обработки базы данных. Он может использоваться непосредственно в ко- мандной оболочке СУБД, встраиваться в триггеры и хранимые процедуры, а так- же в программы на сценарных языках, например VBScript, или на таких языках программирования, как Java и С#. Язык SQL был разработан компанией IBM и был принят Американским на- циональным институтом стандартов (ANSI) в качестве национального стандарта США в 1992 году. Более поздняя версия стандарта, SQL3, не прлучила рас- пространения в промышленности, поэтому здесь не рассматривается. В совре- менных СУБД имеются графические средства для выполнения многих задач, решаемых с помощью SQL. Использование SQL является обязательным, когда необходимо динамически создавать SQL-операторы в программах. Оператор CREATE TABLE служит для создания отношений. Каждый столбец описывается тремя характеристиками: именем, типом данных и необязательны- ми ограничениями. Есть пять типов ограничений: PRIMARY KEY, UNIQUE, NULL/NOT NULL, FOREIGN KEY и CHECK. (Ограничения CHECK будут рассматриваться в следу- ющей главе.) По умолчанию подразумевается ограничение NULL. Первичные ключи ни при каких условиях не могут иметь пустых значений, и ограничение PRIMARY KEY включает в себя ограничение NOT NULL. Столбцы с ограничением UNIQUE могут иметь пустые значения. Если столбец должен быть и уникальным, и непустым, необходимо явно указывать оба ограничения. Стандартными типами данных являются Char, VarChar, Integer и Numeric; кроме них существуют другие типы данных, специфичные для конкретных СУБД. Тип аг аг позволяет хранить строки переменной длины, но они требуют дополни- тельной обработки по сравнению со строками фиксированной длины (тип Char). ( казания по поводу того, какой тип данных в каких случаях лучше исполь- зовать, обычно даются в документации на СУБД.) На табл. 6.4 перечислены не- которые дополнительные типы данных, используемые в Microsoft SQ1 Server и Oracle. Ограничения можно определять в теле оператора CREATE TABLE или добав- лять после создания таблицы при помощи оператора ALTER. Некоторые формы
Резюме 299 определения ограничений позволяют разработчику давать ограничениям имена, а некоторые — нет. В последнем случае имя ограничению присваивает СУЬД, п, как правило, это имя является длинным и не особенно осмысленным. В этой книге мы будем использовать те формы операторов CREATE TABLE и ALTER, ко- торые всегда позволяют присваивать имена ограничениям. Кроме того, по возможности, ограничения будут определяться внутри оператора CREATE TABLE. В листинге 6.4 показан предпочтительный метод определения таблиц и огра- ничений. Удалять таблицы (и другие данные) из базы данных можно с помощью опе- ратора DROP TABLE. Для удаления ограничений служит команда ALTER TABLE DROP CONSTRAINT. Базовый формат SQL-оператора SELECT таков: SELECT (имена столбцов или *), FROM (имена таблиц, разделенные запятыми, если таблиц больше, чем одна), WHERE (условия). С помощью оператора SELECT можно запрашивать определенные столб- цы, определенные строки или то и другое вместе. В условиях, задаваемых в предложении WHERE, значения столбцов, имеющих типы данных Char и VarChar, необходимо заключать в одинарные кавычки (апо- строфы). Для столбцов типов Integer и Numeric этого не требуется. Объединять несколько условий можно с помощью ключевого слова AND. Множества значений задаются с использованием ключевых слов IN (соответствие любому значению из списка) и NOT IN (несоответствие ни одному значению из списка). Шаблоны поиска можно задавать при помощи специальных символов _ (произвольный одиночный символ) и % (произвольная последовательность символов) в сочета- нии с ключевым словом LIKE. Для поиска пустых значений используются ключе- вые слова IS NULL. Сортировка результатов осуществляется с помощью команды ORDER BY. В SQL имеется пять встроенных функций: COUNT, SUM, MAX, MIN и AVG. Группировать ре- зультаты можно, используя предложение GROUP BY, а для отбора строк в группе ио определенному критерию служит конструкция HAVING. Если в SQL-операторе одновременно используются и WHERE, и HAVING, первым применяется условие, заданное в предложении WHERE. Чтение данных из нескольких таблиц может осуществляться посредством вложенных запросов или соединений. Если все данные, которые должны войти в результат, содержатся в одной таблице, то можно использовать вложенные запросы. Если результаты принадлежат двум или более таблицам, необходи- мо использовать операцию соединения. Строки, не удовлетворяющие услови- ям соединения, не будут включены в результат. Чтобы все строки таблицы вошли в результат соединения, можно использовать операцию внешнего со- единения. Вставка данных производится оператором INSERT, изменение — оператором UPDATE, а удаление — оператором DELETE. Неправильное применение операторов UPDATE и DELETE может привести к катастрофическим последствиям, поэтому их необходимо использовать с большой осторожностью.
300 Глава С- Введение в язык bQl Обзорные вопросы 1. Как расшифровывается аббревиатура SQL? 2. Что такое подъязык данных? 3. В чем состоит важность SQL-92? 4, Почему важно изучать SQL? 5. Опишите своими словами смысл конструкций ON UPDATE CASCADE ц gg DELETE CASCADE. Для ответов на вопросы 6-9 используйте следующие таблицы СОТРУДНИК (ИдСотрудника, Имя, Телефон, АдресЭлПочты) КОМПЬЮТЕР (СерийныйНомер, Производитель, Модель, ИдСотрудника} Таблица СОТРУДНИК ИдСотрудника Имя Телефон АдресЭлПочты 100 Мэри Сматерс 206.555.1234 MS@somewhere com 200 Трэн Чау 213.555.1299 TC@somewhere com 300 Кай Чой 312.555.3344 KC@somewhere.com 400 Брайан Джексон 222.555.8858 BJ@somewhere com Таблица КОМПЬЮТЕР СерийныйНомер Производитель Модель ИдСотрудника 1000 Compaq 4000 400 2000 Toshiba 200 200 2500 Compaq 4000 300 7000 Dell 4100 300 8000 Dell 8100 300 6 Напишите оператор CREATE TABLE, создающий таблицу СОТРУДНИК. Обо- снуйте выбор типов данных столбцов и ограничений. 7. Напишите оператор CREATE TABLE, создающие! таблицу КОМПЬЮТЕР. Обо- снуйте выбор типов данных столбцов и ограничений. Может ли столбец ИдСотрудника иметь пустые значения? 8. Определите ограничение ссылочной целостности для столбца КОМПЬЮТЕР ИдСотрудника. Пускай для этого столбца будет выполняться каскадное об- новление, но не удаление. 9. Напишите последовательность SQL-операторов, создающих следуюшу альтернативную версию таблицы КОМПЬЮТЕР: КОМПЬЮТЕР! (СерийныйНомер, Производитель, Модель, ИдСотрудника) 10. Какая структура является более подходящей - КОМПЬЮТЕР или КОМПЬЮТЕР! Обоснуйте свой ответ.
Обзорны» вопросы 301 11. Напишите SQL-код, удаляющий таблицу СОТРУДНИК из базы данных, в пред положении, что ограничение ссылочной целостности должно быть удалена 12. Напишите SQL-код, удаляющий таблицу СОТРУДНИК из базы данных, в пред положении, что таблица КОМПЬЮТЕР также должна быть удалена. Для вопросов 13-42 мы будем использовать таблицы СОТРУДНИК и КОМПЬЮТЕР Пусть ИдСотрудника и ИдКомпьютера будут суррогатными ключами 13. Напишите SQL-оператор, возвращающий все столбцы всех строк таблиц КОМПЬЮТЕР. Не используйте запись со звездочкой (*). 14. Напишите SQL-оператор, возвращающий все столбцы всех строк таблиц КОМПЬЮТЕР. Используйте запись со звездочкой (*). 15. Напишите SQL-код, возвращающий столбцы Производитель и Модель для всех компьютеров. 16. Напишите SQL-код, возвращающий столбцы ИдКомпьютера, Производитель и Модель для всех компьютеров от производителя Dell. 17. Напишите SQL-код, возвращающий столбец Производитель таблицы КОМПЬ- ЮТЕР. 18. Напишите SQL-код, возвращающий столбец Производитель таблицы КОМПЬ- ЮТЕР (исключая дублирующиеся строки). 19. Напишите SQL-код, возвращающий название производителя и модель для всех компьютеров модели 4100 от производителя Dell. 20. Напишите SQL-код, возвращающий серийный номер, название произво- дителя и модель для всех компьютеров, производителем которых не явля- ется ни IBM, ни Dell. 21. Напишите SQL-код, возвращающий серийный номер, название произво- дителя и модель для всех компьютеров, название производителя которых состоит из четырех букв и начинается с буквы D. 22. Напишите SQL-код, возвращающий имена и адреса электронной по- чты всех сотрудников, чей адрес электронной почты заканчивается на somewhere.com. Пусть адреса электронной почты могул состоять из любого количества символов. 23. Напишите SQL-код, возвращающий серийные номера всех компьютеров, для которых не указана модель. 24. Напишите SQL-код, возвращающий название производителя и молод ь для всех компьютеров, отсортированные по ИдСотрудника. 25. Напишите SQL-код, возвращающий название производителя и модель для всех компьютеров, отсортированные по производителям в порядке возрас- тания и по моделям каждого производителя — в порядке убывания 26. Напишите SQL-код, подсчитывающий количество компьютеров. 27. Напишите SQL-код. подсчитывающий количество различных производи- телей.
302 Глава 6. Введение в язык SQL 28. Для следующей таблицы напишите SQL-код, отображающий мини иый, максимальный и средний вес компьютеров каждого производителя ' КОМПЬЮТЕР? (СерийныйНомер, Производитель, Модель, Вес, ИдВладельца) 29 Для таблицы КОМПЬЮТЕР? напишите SQL-код, группирующий данные производителю и отображающий средний вес компьютеров каждого про- изводителя. 30. Ответьте на вопрос 29, но рассматривайте только тех производителей, для которых в базе данных имеется 5 и более компьютеров. 31. Ответьте на вопрос 30, но не рассматривайте компьютеры марки Dell. 32. Используя изображенные выше таблицы СОТРУДНИК и КОМПЬЮТЕР, напи- шите SQL-код, возвращающий имена и адреса электронной почты сотруд- ников, имеющих компьютеры марки Dell. 33. Используя изображенные выше таблицы СОТРУДНИК и КОМПЬЮТЕР, напи- шите SQL-код, возвращающий имена и адреса электронной почты сотруд- ников, имеющих компьютеры марки Dell модели 4100. Используйте со- единение. 34. Допустим, в базу данных добавлена следующая таблица: ПРОИЗВОДИТЕЛЬ (Название, Город, Штат) Пусть столбец Производитель таблицы КОМПЬЮТЕР будет внешним ключом, указывающим на столбец Название таблицы ПРОИЗВОДИТЕЛЬ. Напишите SQL-код, отображающий имена и адреса электронной почты сотрудников, произведенных компанией из Атланты. Используйте вложенный запрос. 35. Ответьте на вопрос 34, но используйте соединение в стандартном формате SELECT FROM WHERE. 36. Ответьте на вопрос 34, ио используйте формат JOIN ON. 37. Ответьте на вопрос 34, но включите в результат всех сотрудников незави- симо от того, есть ли у них компьютер. 38. Напишите SQL-код, добавляющий три строки в таблицу КОМПЬЮТЕР. Пусть СерийныйНомер является суррогатным ключом, значение которому присваи- вает СУБД, а все остальные данные у вас есть. 39. Напишите SQL-код, добавляющий три строки в таблицу СОТРУДНИК Пус ь ИдСотрудника является суррогатным ключом, значение которому прпсваи вает СУБД. Предположите, что вам известны имя и телефон, а сю е АдресЭлПочты пусть останется пустым. 40, Напишите SQL-код, меняющий в столбце Производитель таблицы КОМПЬЮТЕР значение 'Compaq' на 'HP'. 41. Что произойдет, если вы опустите предложение WHERE в вашем огвете на вопрос 40? 42. Напишите SQL-код, удаляющий из таблицы КОМПЬЮТЕР все модели Desktop. Что произойдет, если вы забудете указать пред WHERE в этом операторе?
Упражнения 303 о» J-" Упражнения 43. Напишите J QL-опсраторы, < отдающие таблицы для Модели данных, при исдспнои на рис. .>.17, в. Записывайте операторы в формате, покапанном в лис тише 6.4 Определите внешние ключи и установите каскадное уда лспие и обновление в соответствии с обозначенными процедурами обепи чения ссылочной целостности. Какие из »тих процедур и.- Moiyi быть реа- лизованы посредством 01 р.сничеиий внешнего ключа? 44. С помощью опера юра INSERT добавьте данные в таблицы, созданные вами при ответе на вопрос 43. Пусть будет по меньшей мерс три тортовых aicu та, три шкала и семь записей о доле комиссионных агента. 45. Используя таблицы из ваших ответов па вопросы 43 и 44, напишите SQL операторы, выполняющие указанные ниже действия. Там, где требуется соединение, пользуйтесь форматом JOIN ON; в операторах соединения ис- пользуйте псевдонимы таблиц. J) Выведите имена и номера телефонов ак-птов, для которых не указан адрес электронной почты. Объясните, почему запрос не должен найти ни одной такой строки. 2) Выведите имена всех агентов, а также общую и среднюю сумму всех сделок, в которых они участповали. 3) Выведите номер заказа и процент комиссионных для каждого заказа. 4) Выведите номера заказов и имена агентов для заказов, в которых участ- вовало более двух агентов. 5) Ответьте на вопрос 2), включив в ответ всех агентов, независимо от то- го, имеются ли для них данные о проценте комиссионных. G) В операторах SELECT можно проинюдигь вычисления Зак, например, следующий оператор отображает произведение столбцов А и В i;ai$ но вый столбец С: SELECT А, В, (А*В) AS С FROM TABLE1. Взяв за образец эту структуру, напишите SQL-оператор, перечисляю щий имена агентов и сумму комиссионных, полученных ими за каждый заказ, в котором они участвовали 46 Напишите SQL-ош раiоры, создающие таблицы, которые изображены на рис. 5 19, 6. Записывайте операторы в формате, показанном в лип nine 6.4. Определи и- шк шпис ключи и установите каскадное удаление и обновле- ние в соответствии с обо шач.-пными процедурами обеспечения ссылочной целостно. 1и. Имеются ли здесь процедуры, которые не могут быть реали- зованы нот ред< твом ограничений внешнего ключа? 47 С помощью ош ритора JNSI RT добавьте данные в таблицы, созданные ва ми при отвей на тюпро- 4G Пусть будет хотя бы три строки н таблице ГОСТИНИЧНЫЙ СЧЕТ, ше< ть < т|юк в таблице СТРОКА РАСХОДОВ и двенадцать
304 Глава 6. Введение в язык SQL строк - в таблице ПОДСТРОКА_РАСХОДОВ. Кроме тою, по меньшей мерс . ном из счетов не должно быть ни одной строки расходов, и минимум Одна строка расходов не должна содержать ни одной подстроки. 48. Используя таблицы из ваших ответов на вопросы 46 и 47, напишите SOL операторы, выполняющие указанные ниже действия. Там, где требуется соединение, пользуйтесь форматом JOIN ON; в операторах соединения нс пользуйте псевдонимы таблиц. 1) Выведите номер счета и имя клиента для всех счетов, где итог по кате- гории превышает 100. 2) Пускай требуется вывести номер счета, имя клиента и сумму итогов по категориям для каждого счета. С помощью вложенного запроса этого сделать не удастся. Объясните, почему. 3) Постройте соединение, включающее номер счета, имя клиента и сумму итогов по категориям для каждого заказа. 4) Постройте соединение, включающее имя клиента и сумму итогов по ка- тегориям для каждого клиента. 5) Постройте соединение, включающее итог по категории и сумму итогов по подкатегориям для каждой строки расходов. 6) Объясните, почему нельзя построить соединение, включающее номер счета, имя клиента, сумму итогов по категориям и сумму итогов по под- категориям для каждого счета. Вопросы к проекту FiredUp Предположим, что фирма FiredUp создала базу данных со следующими таблицами: КЛИЕНТ (КлиентСК, Имя, Телефон, АдресЭлПочты) ГОРЕЛКА (СерийныйНомер, Тип, Версия, ДатаВыпуска) РЕГИСТРАЦИЯ (КлиентСК, СерийныйНомер, Дата) РЕМОНТ_ГОРЕЛКИ (НомерСчета, СерийныйНомер, Дата, Описание, Стоимость, КлиентСК) Напишите SQL-операторы, выполняющие указанные ниже действия. Пусть все даты будут в формате ДДММГГГГ. 1. Выведите все данные в каждой из четырех таблиц. 2. Выведите версии всех горелок. 3. Выведите версии всех горелок типа FiredNow. 4. Выведите серийные номера и даты регистраци i для горелок, зарегистри рованных в 2002 году. 5. Выведите серийные номера и даты регистрации для горелок, зарегпстр! рованных в феврале. Используйте символ подчеркивания (_). 6. Выведите серийные номера и даты регистрации для горелок, зарегистри рованных В феврале. Используйте символ процента (%).
Вопросы к проекту Twigs Tree 305 7 Выведите имена и адреса электронной почты всех клиентов, у которых эти адреса указаны. 8. Выведите имена всех клиентов, у которых не указан адрес электронной почты, отсортировав результаты по имени клиента в обратном порядке. 9 Определите максимальную стоимость ремонта горелки. 10 Определите среднюю стоимость ремонта горелки. 11. Подсчитайте общее количество горелок. 12. Подсчитайте количество горелок каждого типа и выведите тип и количество. 13. Выведите имена и адреса электронной почты всех клиентов, ремонт горел- ки для которых стоил более $50. Используйте вложенный запрос. 14. Выведите имена и адреса электронной почты всех клиентов, ремонт горел- ки для которых стоил более $50. Используйте синтаксис JOIN ON. 15. Выведите имена и адреса электронной почты всех клиентов, зарегистриро- вавших горелку типа FiredNow. Используйте синтаксис JOIN ON. 16. Выведите имена, адреса электронной почты и даты регистрации для всех зарегистрированных клиентов. 17. Выведите имена и адреса электронной почты всех клиентов, зарегистриро- вавших горелку и обращавшихся за ремонтом. 18. Выведите имена и адреса электронной почты всех клиентов, зарегистриро- вавших горелку, но не обращавшихся за ремонтом. Вопросы к проекту Twigs Tree Предположим, что фирма Twigs Tree создала базу данных со следующими таб- лицами. ВЛАДЕЛЕЦ (ИмрВлалел^ЦД, Телефон, Дом, Улица, Город, Штат, Индекс) РАБОТА (ДдтаВыполиения. ИмявлаЗельиа, Описание, Стоимость, Уплачено, Дата- Выллаты) ДОСТАВКА_СТРУЖКИ (ИмяКлиента, ДатаДостаики, Объем, Стоимость, Уплачено, Да- таВыплаты) Напишите SQL-операторы, выполняющие указанные ниже действия. Пред- Положим, что столбцы РАБОТА.ИмяВладельца и ДОСТАВКА_СТРУЖКИ,ИмяКлиента яв- Лякгтси внешними ключами, указывающими на столбец ВЛАДЕЛЕЦ. Имя Владельца, а все даты записываются в формате ДДММГПТ. 1 Выведите все данные в каждой из грех таблиц. 2 Выведите названия городов, в которых прожинают владельцы участков. 3 Выведите названия городов, в коюрых проживают владельцы участков, опуская повторения 4 Выведите имена владельцев участков и даты выполнения работ для всех работ вмнолнсйных в 2002 году
зов Главаб^ведение в язык SQL 5 Выведите имени клиентов и даты доставки для веем fiueiaeu* п>гааш оплаченных В феврале Используйте символ подчерки! шив ( ) 6. Выведите имена клиентов и даты доставки для всех мм laaut < ip.*»- оплаченных в феврале. Используйте < импол процента (%) 7. Выведите имена и названия городов тех владельцев участков, у указан номер телефона. 8. Выведите имена и названия городов тех владельцев участков, у которых не указан номер телефона, отсортировав результаты по именам в обратном порядке. 9. Определите максимальную стоимость работы 10. Определите средний объем доставленной стружки 11. Подсчитайте общее количество доставок стружки 12. Подсчитайте количество доставок стружки для каждого владельца участка и выведите имя владельца и количество доставок. 13. Выведите имена тех владельцев участков, кто заказывал доставку стружки и у кого при этом имеются выполненные работы, по которым не сделамо ни одной выплаты. Укажите объемы доставленной им стружки. 14. Ответьте на вопрос 12, используя синтаксис с JOIN ON 15. Ответьте на вопрос 13, используя синтаксис с JOIN ON. 16. Выведите имена и номера телефонов всех владельцев участков, для кото- рых выполнялись какие-то работы и которым доставлялась стружка. 17. Выведите имена и номера телефонов всех владельцев участков, которым доставлялась стружка, но для которых не выполнялись никакие : мты
Глава 7 Использование SQL в приложениях В главе 6 вы изучили синтаксис базовых операторов SQL, но эти операторы рас- сматривались нами изолированно. В настоящей главе мы рассмотрим SQL в кон- тексте практических приложений. Начнем с анализа потребностей воображаемой небольшой художественной галереи под названием View Ridge. На основании этого анализа мы построим модель данных и затем преобразуем ее в реляционную структуру базы данных. Этот пример будет использоваться нами не только в дан- ной главе, но и в последующих. На примере базы данных галереи View Ridge мы продемонстрируем сущест- вующие в SQL средства для формулировки ограничений (оператор CHECK) и соз- дания представлений (оператор CREATE VIEW). Далее мы обсудим две важные проблемы, которые приходится решать при встраивании операторов SQL в при- кладные программы. Затем будет рассмотрено использование триггеров для проверки допустимости вводимых данных, вычисления начальных значений, обновления представлений и реализации процедур обеспечения ссылочной це- лостности Завершающий раздел главы будет посвящен использованию SQL в хранимых процедурах и прикладных программах. Галерея View Ridge View Ridge — небольшая художественная галерея, которая продает современные произведения европейского и североамериканского искусства, включая литогра- фии оригинальную живопись и фото! рафии. Все литографии и фотографии под- писаны и пронумерованы, и цепа большей части произведений находится в пре- делах от $5000 до $50 000 View Ridge занимается продажей уже в течение 30 лет. У галереи есть бессменный владелец, три продавца и два рабочих, которые изго- таяливают рамы, раавешииают работы в галерее и готовят их к отправке клиенту'. Галерея View Ridge проводит выставки и другие, мероприятия для привлече- ния клиентов Произведения искусства выставляются также в офисах местных компаний, ресторанах и друптх общественных местах. Все продаваемые произве Я««ия являются собственно* гыо View Ridge; комиссионной торговлей галерея * имеется
308 Глава 7 Использование SQL в приложениях ....I Требования к приложению Требования к приложению для галереи View Ridge приведены во врезке Пр всего, владелец и продавцы желают вести учет личных данных клиентов их имен, адресов, номеров телефонов и адресов электронной почты Кроме того, они хотят знать, творчеством каких художников интересуется тот или иной клиент Эта информация позволяет продавцам определять, кого следует извещать о по- ступлении новой работы, а также организовывать персональное общение с клиен- тами в устной и письменной форме. ПЕРЕЧЕНЬ ТРЕБОВАНИЙ К ПРИЛОЖЕНИЮ ДЛЯ ГАЛЕРЕИ VIEW RIDGE ----------- ♦ Вести учет покупателей и их художественных интересов. ♦ Отслеживать приобретения, которые делает галерея. ♦ Отслеживать покупки клиентов. ♦ Вести список художников и произведений, когда-либо появлявшихся в галерее ♦ Генерировать отчет о том, насколько быстро и с какой прибылью продаются произ- ведения конкретного художника. ♦ Отображать на веб-странице список произведений, выставленных на продажу Когда галерея покупает произведение, сведения о нем, его авторе, дате и сто- имости приобретения записываются в базу данных. В отдельных случаях галерея может выкупить произведение у клиента и вновь выставить его на продажу, так что одно и то же произведение может появляться в галерее неоднократно. При повторном приобретении информация о работе и ее авторе не вводится заново: записывается только дата и стоимость последнего приобретения. Когда работа продается, записываются дата совершения сделки, уплаченная сумма и сведения о покупателе. Данные о предыдущих продажах необходимы продавцам для того, чтобы они могли уделять больше времени наиболее активным покупателям. Иногда эти за- писи используются для определения местонахождения ранее проданных произ- ведений. Для маркетинговых целей требуется, чтобы приложение базы данных выда- вало список всех произведений, которые когда-либо появлялись в галерее, и их авторов. Владелец хотел бы также иметь возможность определять, насколько быстро продаются произведения каждого из художников и какова прибыль от их продажи. Наконец, приложение должно отображать список работ, имеющих ся в наличии, на веб-странице, к которой потенциальные клиенты могли бы о ращаться через Интернет. Модель данных На рис 7 1, а показана модель данных для галереи View Ridge. В ней есть две сильные сущности - CUSTOMER (клиент) и ARTIST (художник). Кроме того, и ется сущность WORK (произведение), идентификационно-зависимая от сущ
Галерея View Ridge 309 ARTIST, и сущность TRANSACTION (транзакция), идентификационно-зависимая от сущности WORK. Между сущностями CUSTOMER и WORK имеется неидентифици- рующая связь принадлежности. ARTIST a ARTIST CUSTOMER 4 Email- NOT NULL Name NOT NULL AreaCtxfe: NULL IlJXsMwnber. NULL Street NULL Sy NULL State NULL । ZipPoetaColf NULL I County NULL WORK TRANSACTION 4Name: NOT NULL (FK) 4Title. NOT NULL (FK) Чсору: NOT NULL (FK) DateAcquired: NOT NULL Acquisitionprice: NULL PurchaseDate: NULL SalesPrice: NULL AskingPrice: NULL Email: NULL(FK) 4Name: NOT NULL (FK) 4Title: NULL Чсору: NULL____________ Description: NULL 4Name NOT NULL Nationality: NULL Birthdate: NULL DeceasedDate: NULL P CUSTOMERARTISTJNT 4Name: NOT NULL (FK) 4Emall NOT NULL (FK) 6 Рис. 7.1. База данных галереи View Ridge с использованием данных в качестве ключей: а — модель данных; б — реляционная схема 1 Явления о художнике мшут присутствовать в базе данных, даже если ни од- W из его работ не появлялась в tajiepee. Эго сделано для того, чтобы можно бы- ло регистрировать интерес клиентов к художникам, чьи работы галерея может приобрести в будущем Таким образом, с художником может быть связано любое количество прои «ведений, в iom числе ноль
3^0______Глава 7. Использование SQL в приложении* Идентификатором сущности WORK является группа (Title, Сору) (название мер копии), поскольку в случае литографий и фо ни рафий произведение существовать в нескольких экземплярах. Кроме того, в требованиях к ии< жению указано, что одно и то же произведение может неоднократно появлятьс в галерее, поэтому с каждым произведением потенциально может быть связаад много транзакций. Каждый раз, когда произведение появляется в галерее, необ- ходимо записывать дату и стоимость приобретения. Таким образом, каждой ра- боте должна соответствовать по меньшей мере одна транзакция. Клиент может приобрести множество работ; этот факт обозначен связью i 1:N между сущностями CUSTOMER и TRANSACTION. Обратите внимание, что данная связь является необязательной в обоих направлениях. Наконец, между сущно- стями CUSTOMER и ARTIST существует связь вида N:M. Это реальная связь «мно- гие ко многим»: все усилия группы разработчиков обнаружить какую-либо про- межуточную сущность оказались тщетными. Реляционная схема с использованием данных в качестве ключей На рис. 7.1, б показана реляционная схема для модели данных, изображенной на рис. 7.1, а. В этом варианте в качестве ключей используются данные, и, как можно видеть, с каждым первичным ключом, за исключением ARTIST.Name, связаны какие-нибудь проблемы. Ключи таблиц WORK и TRANSACTION чересчур велики, а ключ таблицы CUSTOMER и вовсе сомнителен: далеко не у всех покупателей име- ется адрес электронной почты. В связи с этим напрашивается очевидное реше- ние — ввести суррогатные ключи. Модель данных с суррогатными ключами Модель данных с использованием суррогатных ключей показана на рис. 7.2. а. Обратите внимание, что вместо двух идентификационно-зависимых связей по- явились две неидентифицирующие связи. Дело в том, что теперь, когда сущность ARTIST имеет суррогатный ключ, исчезла потребность в композитных идентифи- кационно-зависимых ключах для сущностей WORK и TRANSACTION. Необходимость подобных изменений обсуждалась в главе 5. Обратите внимание, что атрибут ARTIST. Na те определен как альтернатпвн ключ. Тем самым гарантируется, что в базе данных не будет нескольких записей об одном и том же художнике. Аналогичным образом в качестве альтернативно^ го ключа определена комбинация (Title, Сору), чтобы нельзя было одну и работу записать в базу данных несколько раз. Реляционная схема с суррогатными ключами Реляционная схемы для модели данных с суррогатными ключами ,,зобР^^. на рис. 7.2, б. Именно эту схему мы будем использовать на протяжении дани & вы, а также в последующих главах. Все ключи представлены как суррогата _ ч мате IDENTITY (и, т), где п - начальное значение суррогатного ключа, нЯ ращение. Все ключи имеют приращение, равное 1, но разные начальн
Галерея View Ridge 311 a CUSTOMER ^CustomerlD lDENTITY(1000,1) Name NOT NULL AreaCode: NULL LocalNumber: NULL Street NULL City: NULL State. NULL NULL Country: NULL Ema»- NULL l:SD UR D:R U:C D:R U:C ► - - - D:R LSD U:R D:R - - P-|^WorklD: I DR i LSD ; U:R Title: Copy: ArtistID: WORK IDENTITY (500 TNULL(AK1.1) ЭТ NULL (AK1.2) эп: NULL NOT NULL (FK) *P ARTIST ^ArtistlD. IDENTITY (1,1) ArtistName: NOT NULL (AK1.1) Nationality: NULL Birthdate: NULL DeceasedDate: NULL ______________TRANS_________________ «VransactionlD: IDENTITY (100,1) DateAcquired: NOT NULL AcquisitionPrice. NULL PurchaseDate- NULL SalesPnce: NULL CustomerlD: NULL (FK) AskingPrice: NULL WorkID NOT NULL (FK) CUSTOMER_ARTIST_INT UR —« 4 ^CustomerlD NOT NULL (FK) ^ArtistID' NOT NULL (FK) UR ► — ‘ 6 Рис 7.2. База данных галереи View Ridge с использованием суррогатных ключей а - модель данных, б — реляционная схема Размещение внешних ключей является резулыагом непосредственного при* ***'Нения принципов, описанных в главе 5. Атрибут TRANSACTION.CustomerlD no* иметь пустые «качения; это позволяет создать строку в таблице RANSAC I0N v»toro как произведение приобретет какой пибудь клиент. Все прочие внешние Жлг’**м являются гЛязагепьными.
312 Глава 7 Использование SQL в приложениях Процедуры обеспечения ссылочной целостности со стороны родительских таблиц Удаление строк в таблицах CUSTOMER и ARTIST вызывает каскадное удаление в щЛ лице CUSTOMER_ARTIST_INT. Это имеет смысл, поскольку когда сведения о клиенте или художнике удаляются из базы данных, нет нужды сохранять ииформаци о предпочтениях данного клиента или интересе к данному художнику. Помимо этого, каскадное удаление больше нигде не применяется. Если с клиентом связа на хотя бы одна транзакция, этот клиент не может быть удален из базы данных. Аналогично, если с художником связана хотя бы одна картина, удалить его будет нельзя. Наконец, записи о работах, по которым имели место какие-либо транзак- ции, удалению также не подлежат. Последнее обстоятельство ставит нас перед проблемой. Когда в базу данных добавляется новое произведение, для него должна быть создана строка в таблице TRANSACTION, в которой будут указаны дата и стоимость приобретения. Поэтому с каждой из работ должна быть связана по крайней мере одна транзакция. Одна- ко последнее правило, касающееся удаления, гласит, что нельзя удалить работу, с которой связана хотя бы одна транзакция. Таким образом, работу невозможно удалить из базы данных, даже если она никогда не была продана. Возможно, галерея вообще не желает удалять сведения о работах, однажды добавленных в базу данных. Если нет, то можно ввести следующее правило: если работа появлялась в галерее только один раз, и при этом не была продана (стол- бец CustomerlD в соответствующей строке таблицы TRANSACTION пуст), то работу можно удалить из базы данных. В нашем примере мы будем подразумевать по- следний случай. Для обработки удаления нам потребуется создать триггер, как будет показано далее в этой главе. Что касается обновления, то во всех связях вида «родитель—потомок» обнов- ление родительской таблицы вызывает каскадное обновление дочерней. В дей- ствительности это правило не нужно, поскольку значения суррогатных ключей никогда не меняются. Наконец, вставка с родительской стороны обрабатывается согласно стандартным правилам обеспечения ссылочной целостности. Например, значение атрибута WORK.ArtistID должно существовать среди значений атрпоута ARTIST.ArtistlD. О соблюдении всех этих ограничений позаботится СУБД, от нас же требуется лишь указать их на схеме. Процедуры обеспечения ссылочной целостности со стороны дочерних таблиц Обновление со стороны дочерних таблиц ограничено. Ни при каких условиях^ должно возникать необходимости в изменении значения внешнего ключа < лицах CUSTOMER„ARTIST_INT, WORK и TRANSACTION (столбец WorkID), следоват• в данном случае слово «ограничено» обозначает, что обновление просто пел л* кается. Что касается столбца TRANSACTION.CustomerlD, то его значение измен при первой продаже работы. После этого, однако, значение Customer не должно. Таким образом, если столбец CustomerlD пуст, его обновлен 6хОДИмо в противном случае обновление не допускается. Это правило также реализовать с помощью триггера.
Галерея View Ridge 313 При вставке строк в таблицы WORK и TRANSACTION их внешним ключам при- сваиваются начальные значения (процедура SD), а именно значения ключей со- ответствующих строк в таблицах ARTIST и WORK. Внешний ключ CustomerlD таб- лицы TRANSACTION при вставке определяется как пустой, и пустым он останется до тех нор, пока кто-нибудь не купит данное произведение. Удаление строк в таблицах WORK и TRANSACTION объявлено как ограниченное, но по разным причинам. Если столбец TRANSACTION.CustomerlD не является пус- тым, строка не может быть удалена. Если он пуст, строку можно удалить только при условии, что данная транзакция является единственной для некоторого про- изведения, и данное произведение само будет удалено из базы. Как было указано выше, эта пара ситуаций должна обрабатываться с помощью триггеров. Наконец, произведение можно удалить, если с ним связана одна-единственная транзакция с пустым столбцом CustomerlD. Строки таблицы CUSTOMER_ARTIST_INT могут быть удалены как в процессе каскадного удаления, так и непосредственно приложени- ем, когда клиент решает, что его более не интересует тот или иной художник. Создание таблиц SQL-процедура, создающая таблицы базы данных галереи View Ridge, представ- лена в листинге 7.1. Она состоит из пяти операторов CREATE TABLE — по одному на каждую из таблиц. Мы используем рекомендованный стиль записи, при котором разработчик может давать имена всем ограничениям (см. листинг 6.4). Обратите внимание, что столбец TRANSACTION.CustomerlD определен как необязательный; все остальные первичные ключи являются обязательными. Листинг 7.1. Создание таблиц для базы данных галереи View Ridge CREATE TABLE CUSTOMER! CustomerlD int NOT NULL IDENTITY (1000.1). Name char(25) NOT NULL, Street char(30) NULL. City char(35) NULL. State char(2) NULL. ZipPostalCode char(95) NULL. Country char(50) NULL. AreaCode char(3) NULL. PhoneNumber char(8) NULL. Email char(lOO) NULL CONSTRAINT CustomerPK ): PRIMARY KEY (CustomerlD) create table artist< Artist ID 1nt NOT NULL IDENTITY (11). Name char(25) NOT NULL, Nationality char(30) NULL.
314 Глава 7. Использование SQL в приложениях Листинг 7.1 (продолжение) Вт rthDate DeceasedDate numeric(4) NULL, numeric(4) NULL, CONSTRAINT ArtistPK PRIMARY KEY (ArtistID). CONSTRAINT ArtistAKl UNIQUE (ArtistID). CONSTRAINT NationalityValues CHECK (Nationality IN ('Canadian1. ’English1. 'French1. 'German1. ’Mexican'. ’Russian1. 'Spanish1. ’US1.)). CONSTRAINT BirthValuesCheck CHECK (BirthDate < DeceasedDate). CONSTRAINT ValidBirthYear CHECK (BirthDate LIKE 1[l-2][0-9][0-9][0-9]1). CONSTRAINT VaiidDeathYear ): CHECK (DeceasedDate LIKE '[l-2][0-9][0-9][0-9]') CREATE TABLE CUSTOMER_ARTIST_INT( ArtistID CustomerlD int NOT NULL. char(25) NOT NULL. CONSTRAINT CustomerArti stPK PRIMARY KEY (ArtistID. CustomerlD). CONSTRAINT Customer_Artist_Int_Arti stFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) ON UPDATE CASCADE ON DELETE CASCADE. CONSTRAINT Customer_Artist_Int_CustomerFK FOREIGN KEY (CustomerlD) REFERENCES CUSTOMER (CustomerlD) ON UPDATE CASCADE ): ON DELETE CASCADE CREATE TABLE W0RK( WorkID Title Description Copy ArtistID int NDT NULL IDENTITY (1.1). char(25) NDT NULL. varchar(lOO) NULL. char(8) NOT NULL. int NOT NULL. CONSTRAINT WorkPK PRIMARY KEY (WorkID). CONSTRAINT WorkAKl UNIQUE (Title. Copy).
Галерея View Ridge 315 CONSTRAINT ArtiStFK FOREIGN KEY (ArtiStID) REFERENCES ARTIST (ArtiStID) CREATE TABLE WORK( TransactionlD DateAcqui red int NOT NULL IDENTITY (100,10). date NOT NULL. AcqulsitionPrice numeric(8,2) NULL. PurchaseDate SalesPrice Askingprice CustomerlD WorkID date NULL. numeric(8.2) NULL, numeric(8.2) NULL, int NULL, int NOT NULL. CONSTRAINT TransactlonPK PRIMARY KEY (TransactionlD), CONSTRAINT SalesPriceRange CHECK ((SalesPrice > 1000) AND (SalesPrice <= 200000)). CONSTRAINT ValidTransDate CHECK (DateAcquired <= PurchaseDate). CONSTRAINT Transact)onWorkFK FOREIGN KEY (WorkID) REFERENCES WORK (WorkID) CONSTRAINT T ransacti onCustomerFK FOREIGN KEY (CustomerlD) REFERENCES CUSTOMER (CustomerlD) ): Кроме того, стоит отметить, что столбцы Birth Date (дата рождения) и Deceased Date (дата смерти) определены как четырехзначные числа, обозначающие год. Сотруд- никам галереи не важны месяц и день рождения и смерти, им достаточно знать лишь год. Все операторы, встречающиеся в листинге 7.1, обсуждались нами в главе 6, за исключением ограничений CHECK. Эти ограничения определяют множество допус- тимых значений столбца. Наиболее распространены два типа таких ограничений: диапазоны и перечисления. Пример ограничения первого типа можно видеть в таб- лице TRANSACTION, где столбец SalesPrice (продажная цена) должен иметь значение, превышающее 1000, но меньшее или равное 200 000. Ограничение второго типа имеет место в определении таблицы ARTIST. Здесь множество значений столбца Nationality (национальность) ограничивается толь- ко теми значениями, которые перечислены в скобках. Это ограничение отражает политику галереи работать только с произведениями европейских и североаме- риканских художников. Есть также ограничения, сравнивающие между собой значения двух столб- цов Например, ограничение BirthValuesCheck (проверка даты рождения) в табли- це WORK предписывает, что значение столбца Birth Date (дата рождения) должно ныть меньше, чем DeceasedDate (дата смерти). Похожее ограничение сформули- ровано в определении таблицы TRANSACTION.
3 6 Глава 7. Использование SQL в приложениях Еще одни тип ограничений — ограничения формата. В определении таблиг ARTIST на столбцы Birth Date и DeceasedDate наложено ограничение, согласно кот1* рому они должны состоять из четырех десятичных цифр, причем первой цифрой должна быть 1 или 2. Таким образом, значения вроде 799 или 3100 являют этих столбцов недопустимыми. Согласно стандарту SQL-92, ограничения CHECK не могут включат», систем- ную дату. И это жаль, поскольку для таких столбцов, как PurchaseDate (дата обретения), весьма полезным было бы ограничение, в соответствии с которым значение столбца должно быть меньше или равно текущей дате. Но это ограни- чение можно реализовать с помощью триггера. Существует еще один интересный тип ограничений CHECK (не показан в лис- тинге 7.1) — ограничения, содержащие в себе вложенный запрос. Предположим например, что таблица STATECODE (код штата) имеет столбец ValidStateAbbreviation (допустимое сокращение штата), содержащий все допустимые сокращения на- званий штатов. Тогда в оператор CREATE TABLE для таблицы CUSTOMER можно бы- ло бы добавить следующее ограничение: CONSTRAINT ValidStateCheck CHECK (State IN (SELECT ValidStateAbbreviation FROM STATECODE WHERE ValidStateAbbreviation = State)). OoceaeeclOntn Такое ограничение, однако, может быть реализовано не во всех СУБД. В стан- дарте SQL-92 определено множество других типов ограничений CHECK, но их поддержка в различных СУБД неоднородна. Поищите в документации на вашу СУБД термин «ограничения CHECK», чтобы узнать, какие типы ограничений вам доступны. Данные для примера В табл. 7.1-7.5 приведены данные для пяти таблиц, определенных в листинге 7.1. Эти данные мы будем использовать на протяжении оставшейся части этой главы, а также при обсуждении SQL Server и Oracle в главах 10 и 11. SQL-представления SQL-представление (SQL view) - это виртуальная таблица, составленная из ДРУ гих таблиц или представлений. Представление не имеет своих собствен ных, а объединяет данные из таблиц или представлений, которые в н ’ниче. Представления создаются с помощью операторов SELECT;едаиСТВВ”” oRDer BY'- вне заключается в том что они не могут включать в себя батЫвает Сортировка должна обеспечиваться оператором SELECT, который Р представление. 7 ™ SO1 -92 Тем не менее, Oracle и (при определенных условиях) Q “ ...................
Таблица 7.1. Данные ДЛЯ таблицы ARTIST ArtistID Name Nationality BirthDate DeceasedDate 3 Miro Spanish 1870 1950 4 Kandinsky Russian 1854 1900 5 Frings US 1700 1800 6 Klee German 1900 <NULL> 3 Moos US <NULL> <NULL> 14 Tobey US <NULL> <NULL> 15 Matisse French <NULL> <NULL> 16 Chagall French <NULL> <NULL> Таблица 7.2. Данные для таблицы WORK WorkID Title Description Copy ArtistID 505 Mystic Fabric One of the only pr 99/135 14 506 Mi Vida Very black, but ve 7/100 3 507 Slow Embers From the artist’s HC 14 525 Mystic Fabric Some water damage 105/135 14 530 Northwest by Night Wonderful, moody 37/50 16 Таблица 7.3. Данные для таблицы TRANSACTION TransactionlD DateAcquired AcquisitionPrice PurchaseDate SalesPrice AskingPrice CustomerlD WorkID 100 2/27/1974 8750 3/18/1974 18500 20000 1015 505 101 7/17/1989 28900 10/14/1989 46700 47000 1001 505 121 11/17/1989 4500 11/21/2000 9750 10000 1040 525 122 2/27/1999 8000 3/15/2000 17500 17500 1036 525 124 4/7/2001 38700 8/17/2000 73500 75000 1036 506 129 11/21/2001 6750 3/18/2002 14500 15000 1040 507 130 11/21/2001 21500 <NULL> <NULL> <NULL> <NULL> 525 135 7/17/2002 47000 10/2/2002 71500 72500 1015 530
Таблица 7.4. Данные для таблицы CUSTOMER Cus- tomer- lD Name Street City State Zip- Postal- Code Country Area- Code Phone- Number Email 1000 Jeffrey Janes 123 W. Elm St Renton WA 98123 USA 206 555-1345 Customerl 000@somewhere. com 1001 David Smith 813 Tumble- weed Lane Loveland CO 80345 USA 303 555-5434 Customerl 001 ©somewhere.com 1015 Tiffany Twilight 88 - First Avenue Langley WA 98114 USA 206 555-1000 Customer1015@somewhere.com 1033 Fred Smathers 10899 - 88th Ave Bainbridge Island WA 98108 USA 206 555-1234 Customer1033@somewhere.com 1034 Mary Beth Frederickson 25 South Lafayette Denver CO 80210 USA 303 555-1000 Customerl 034@somewhere.com 1036 Selma Warning 205 Burnaby Vancouver BC VON 1B4 Canada 253 555-1234 Customerl 036@somewhere.com 1037 Susan Wu 105 Locust Ave Atlanta GA 23224 USA 721 555-1234 Customerl 037@somewhere com 1040 Donald G. Gray 55 Bodega Ave Bodega Bay CA 92114 USA 705 555-1234 Customerl 040@somewhere.com 1041 Lynda Johnson 117 C Street Washington DC 11345 USA 703 555-1000 <NULL> 1051 Chris Wilkens 87 Highland Drive Olympia WA 98008 USA 206 555-1234 <NULL> te I'» S Таблица 7.5. Данные для таблицы CUSTOMER_ARTIST_INT ArtiStID CustomerlD ArtiStID CustomerlD 3 1036 14 1015 5 1015 14 1033 5 1034 14 1034 5 1041 14 1036 5 1051 14 1040 8 1034 14 1041 8 1041 14 1051 14 1001 16 1015
SQL-представления 319 Например, следующий оператор определяет представление под названием CustomerNameView, базирующееся на таблице CUSTOMER: CREATE VIEW CustomerNameView AS SELECT Name AS CustomerName FROM CUSTOMER: Для получения отсортированного списка имен клиентов это представление можно обработать при помощи такого SQL-оператора: SELECT * FROM CustomerNameView ORDER BY CustomerName Вот как будет выглядеть результат. Листинг 7.2. Результаты запроса данных из представления CustomerNameView / CustomerName Chris Wilkens David Smith Donald G. Gray Fred Smathers Jeffrey Janes Lynda Johnson Mary Beth Frederickson Selma Warning Susan Wu Tiffany Twilight No more results. (10 row(s) returned) Результат выполнения этого оператора для данных из табл. 7.4 показан в лис- тинге 7.2. Обратите внимание, что используется выражение SELECT * для запроса данных из представления CustomerNameView. Как вы знаете, это выражение воз- вращает все столбцы. В данном случае возвращается только один столбец, так как он является единственным в представлении CustomerNameView, хотя таблица CUSTOMER, из которой он взят, имеет несколько столбцов. Также обратите внимание, что столбцу CUSTOMER.Name из оригинальной таб- лицы в представлении CustomerNameView было дано имя CustomerName. По этой причине в предложении ORDER BY оператора SELECT необходимо использовать имя CustomerName, а не Name. В возвращаемых СУБД результатах в качестве имени столбца также фигурирует CustomerName. Представления имеют множество применений. Во-первых, с их помощью мож- но скрывать от доступа отдельные столбцы или строки. Кроме того, они позво- ляют отображать вычисляемые столбцы и скрывать сложные SQL-операторы, а также обеспечивают уровень абстракции между данными, обрабатываемыми приложением, и реальными данными, содержащимися в таблицах. Далее мы
320 Глава 7. Использование SQL в приложениях рассмотрим примеры каждого из этих применений, а затем другие варианты использования представлений. обсудим некоторые Использование представлений для скрытия столбцов и строк С помощью представлений можно скрывать отдельные столбцы таблиц. Это де- лается для того, чтобы возвращаемый результат имел более простой вид, а также для предотвращения доступа к конфиденциальным данным. Предположим, что пользователям базы данных View Ridge нужны только имена и номера телефонов клиентов, но не их домашние адреса или адреса электронной почты. Следующий оператор создает представление BasicCustornerData, содержащее только эти данные. CREATE VIEW SELECT FROM BasicCustornerData AS Name. AreaCode. PhoneNumber CUSTOMER: Результаты выполнения оператора SELECT* над этим представлением показа- ны в листинге 7.3. Аналогичный метод можно использовать для скрытия таких столбцов, как Acquisitionprice или SalesPrice в таблице TRANSACTION, в ситуациях, когда показ этих конфиденциальных данных был бы неуместным. Листинг 7.3. Содержимое представления BasicCustornerData Name AreaCode PhoneNumber Jeffrey Janes 206 555-1345 David Smith 303 555-5434 Tiffany Twilight 206 555-1000 Fred Smathers 206 555-1234 Mary Beth Frederickson 303 555-1000 Selma Warning 253 555-1234 Susan Wu 721 555-1234 Donald G. Gray 705 555-1234 Lynda Johnson 703 555-1000 Chris Wilkens 206 555-1234 No more results. (10 row(s) returned) Можно скрывать от просмотра и строки таблиц. Для этого в определен*”* представления должно присутствовать предложение WHERE. Следующий оп^ ратор определяет представление, содержащее имена и номера телефонов клиентов, проживающих в штате Вашингтон: CREATE VIEW BasicCustomerData_WA AS SELECT Name. AreaCode. PhoneNumber FROM CUSTOMER WHERE state = 'WA';
SQL-представления 321 Содержимое этого представления показано в листинге 7.4. Как и требовалось, нем присутствуют сведения только о тех клиентах, которые проживают в штате Вашингтон. Данный факт не является очевидным, поскольку столбец State не входит в результат. Это может быть хорошо или плохо в зависимости от того, как используется представление. Если оно используется только в тех случаях, когда значение имеют лишь клиенты из Вашингтона, это хорошо; в противном случае это будет дезориентировать пользователя, создавая впечатление, что кро- ме перечисленных персон, у галереи View Ridge больше нет клиентов. Листинг 7.4. Содержимое представления BasicCustomerData_WA AreaCode PhoneNumber Jeffrey Janes 206 555-1345 Tiffany Twilight 206 555-1000 Fred Smathers 206 555-1234 Chris Wilkens 206 555-1234 No more results. (4 row(s) returned) Использование представлений для отображения вычисляемых столбцов Еще одно применение представлений — отображение результатов вычислений, не прибегая к вводу формул пользователем. Например, следующее представле- ние объединяет столбцы AreaCode и PhoneNumber и форматирует результат: CREATE VIEW CustomerPhone AS SELECT Name. ('(' + AreaCode + ')’) + PhoneNumber) As Phone FROM CUSTOMER: Допустим, пользователь вводит следующий запрос: SELECT * FROM CustomerPhone; Результаты выполнения этого запроса показаны в листинге 7.5‘. Листинг 7.5. Содержимое представления BasicCustomerData Name Phone Jeffrey Janes (206) 555-1345 David Smith (303) 555-5434 Tiffany Twilight (206) 555-1000 Fred Smathprs (206) 555-1234 Mary Beth Frederickson (303) 555-1000 В Oracle для конкатенации < грок имело плюса (•) необходимо черты () продал жвние# использовать дне вертикальные
322 Глава 7, И пользование SQL в приложениях Листинг 7,5 (продолжение) Selma Warning (253) 555-1234 Susan Wu (721) 555-1234 Donald G. Gray (705) 555-1234 Lynda Johnson (703) 555-1000 Chris Wilkens (206) 555-1234 No more results. (10 row(s) returned) Выполнение необходимых вычислений в представлениях имеет два преиму- щества. Во-первых, это избавляет пользователей от необходимости вводить ма- тематическое выражение, чтобы получить желаемый результат (а также от необ- ходимости знать, как это делается). Во-вторых, это обеспечивает единообразие результатов. Если каждый разработчик, использующий вычисления, будет пи- сать собственные выражения, то они, скорее всего, будут написаны по-разному, из-за чего результаты будут иметь неодинаковый вид. Использование представлений для скрытия сложного синтаксиса Еще одно применение представлений — скрытие SQL-операторов со сложным синтаксисом. Это может делаться для того, чтобы избавить разработчиков от необ- ходимости вводить сложный оператор всякий раз, когда им требуется определен- ное представление, или для того, чтобы разработчики, не знающие SQL, могли тем не менее воспользоваться преимуществами, которые предоставляют сложные SQL-операторы. Кроме того, как и в случае использования представлений для вычислений, это обеспечивает единообразие результатов. Два наиболее распространенных варианта использования представлений в дан- ной ипостаси — это скрытие соединений и скрытие вложенных запросов. Скрытие соединений Продавцам-консультантам галереи View Ridge необходимо знать, какими худож никами интересуется тот или иной клиент. Поскольку связь между сущностями CUSTOMER и ARTIST имеет вид N:M, она представлена в виде таблицы пересечения. Таким образом, чтобы отобразить сведения об интересах клиентов, не0^™^!гп° выполнить два соединения: сначала соединить таблицы CUSTOMER и CUS - ARTST_INT, а затем полученный результат соединить с таблицей ARTIST. Предст леиие, содержащее эти два соединения, конструируется с помощью следу SQL-оператора: CREATE VIEW SELECT FROM JOIN Customerinterests AS C.Name as Customer. A.Name as Artist CUSTOMER C CUSTOMER_ARTIST_INT CI ON C.CustomelD = CI.CustomerlD JOIN ARTIST A ON CI.ArtistID = A.ArtistID:
SQL-представления 323 * 4 Этот оператор выполняет стандартное двойное соединение. Обратите внимание на использование псевдонимов для таблиц (С вместо CUSTOMER, CI вместо CUSTOMER- ARHST.INT, А вместо ARTIST). Такие псевдонимы упрощают выражения ON. На- пример, проще написать C.CustomerlD = CI.CustomerlD, чем CUSTOMER.CustomerlD = CUSTOMER-ARTIST-INT.CustomerlD. Использовать псевдонимы не обязательно. Также обратите внимание на переименование С.Name в Customer и A.Name в Artist. Такое переименование выполнять необходимо, в противном случае в пред- ставлении оказались бы два столбца с именем Name. СУБД не смогла бы разли- чить эти два столбца и выдала бы ошибку при создании представления. Следующий оператор запрашивает данные из представления Customerinterests и сортирует результаты по столбцу Customer: SELECT FROM ORDER BY CustomerInterests Customer; Результат показан в листинге 7.6. Очевидно, что использовать представление гораздо легче, чем строить соединения. Листинг 7.6. Содержимое представления Customerinterests Customer Arti st — Frings Tobey Tobey Tobey Tobey Tobey Moos Frings Fri ngs Moos Tobey Tobey Miro Chagall Frings Tobey Chris Wilkens Chris Wilkens David Smith Donald G. Gray Fred Smathers Lynda Johnson Lynda Johnson Lynda Johnson Mary Beth Frederickson Mary Beth Frederickson Mary Beth Frederickson Selma Warning Selma Warning Tiffany Twilight Tiffany Twilight Tiffany Twilight No more results (16 row(s) returned) Скрытие группировки и встроенных функций Представления используются также для скрытия группировки и встроенных функций Рассмотрим следующее определение представления: CREATE VIEW ArtlstWorkNet AS W Workld Name, Title. Copy. AcquisitionPrice. SalesPrice. (SalesPrice AcquisitionPrice) AS NetPrice TRANSACTION T
324 Г лава 7. Использование SQL в приложениях JOIN WORK W ON T.WorkID = yj. WorkID JOIN ARTIST A ON W.ArtistID = A.ArtistID; Это представление соединяет таблицы TRANSACTION, WORK и ARTIST и создает вычисляемый столбец NetPrice. С этим представлением можно выполнять раз- личные операции на языке SQL, как если бы NetPrice был обычным столбцом таблицы. Например, чтобы отобразить совокупную прибыль от продажи каждой картины, можно использовать следующий оператор: SELECT Name. Title. Copy. sum(NetPrice) as TotalNet FROM ArtistWorkNet ORDER BY Name. Title. Copy: Результаты выполнения этого запроса показаны в листинге 7.7. Листинг 7.7. Содержимое представления ArtistWorkNet Name Title Copy TotalNet Chagall Northwest By Night 37/50 24500 Mi ro Mi Vida 7/100 34800 Tobey Mystic Fabric 105/135 14750 Tobey Mystic Fabric 99/135 27550 Tobey Slow Embers HC 7750 No more results. (5 row(s) returned) Этот оператор можно использовать для определения другого представления: CREATE VIEW WorkNet AS SELECT Name. Title. Copy. sum(NetPrice) AS TotalNet FROM Arti stWorkNet GROUP BY Name. Title. Copy; Теперь для того чтобы получить результаты, представленные в листинге 7.7, пользователю достаточно ввести лишь: SELECT FROM * WorkNet; Аналогичным образом можно определить представление ArtistNet CREATE VIEW ArtistNet AS SELECT Name. sum(NetPrice) AS TotalNet FROM Arti StWorkNet GROUP BY Name; Пользователь будет запрашивать данные из этого представления с помошь следующего оператора: SELECT * FROM ArtistNet: f дне’ цате CM- Hiro Tobe No « (3 о ДР У П{ обес ных исто ются опре. GREAT SELEC FROM В Custo же ос Ес ных, ХОДИЛ Вбуд; NEWJ «нес. create SELECT EROM Be( б-1ем f Из т°Рые
SQL-представления 325 Результат показан в листинге 7.8. Листинг 7.8. Содержимое представления ArtistNet Name Total Net Chagall 24500 Miro 34800 Tobey 50050 No more results. (3 row(s) returned) Другие варианты использования представлений У представлений имеется еще три важных применения. Во-первых, они могут обеспечивать определенный уровень абстракции между приложением базы дан- ных и реальными таблицами. Этот уровень абстракции может быть важен, когда источник данных может меняться, а также в других случаях, которые обсужда- ются в следующей главе. Чтобы понять, о чем идет речь, рассмотрим следующее определение представления CREATE VIEW CustomerTablel AS SELECT * FROM CUSTOMER: В сущности, это представление присваивает таблице CUSTOMER псевдоним CustomerTablel. Представление CustomerTablel можно обрабатывать точно таким же образом, как и таблицу CUSTOMER. Если в коде приложения используется имя CustomerTablel, то источник дан- ных, на котором основано это представление, может меняться, не вызывая необ- ходимости переписывать приложение. Следовательно, в определенный момент в будущем, если источником данных о клиентах станет другая таблица, например, NEW_CUSTOMER, все, что потребуется сделать, — это переопределить представле- ние CustomerTablel следующим образом: CREATE VIEW CustomerTablel AS SELECT * FROM NEW_CUSTOMER. Весь код приложения, в котором используется имя CustomerTablel, без про- блем будет работать с новым источником данных. Из-за потенциальной необходимости в изменении источников данных неко- торые организации никогда не предоставляют разработчикам доступ к реальным таблицам Вместо этого используются представления, базирующиеся на данных из этих таблиц. Такая стратегия повышает гибкость для будущих проектов по разработке баз данных и упрощает их перепроектирование, как вы узнаете из следующей главы. Аиало1И’И1ым образом, иногда представления используются для предоставле- ния различных нрав досгуна к одной и гой же таблице. Вопросы безопасности
326 Глава 7. Использование SQL в приложениях будут обсуждаться более подробно в главах 9 И, а сейчас |лавние понять . можно ограничить права пользователей на вставку, обновление, удаление и чт° нне данных из таблиц и представлении. Например, организация может определить базирующееся на таблице CUSTOMER представление CustomerRead, которое предоставляет право лишь на запрос дан ных из этой таблицы, и представление CustomerUpdate, базирующееся на той ад таблице, но дающее право как на чтение, так и на обновление данных в ней. Прило- женпя, которым не требуется обновлять данные, будут работать с представлени- ем CustomerRead, а приложения, выполняющие обновление данных, — с представ- лением CustomerUpdate. Третье применение представлений состоит в том, чтобы определить для таб- лицы несколько различных наборов триггеров. Триггеры назначаются таблицам и представлениям, так что каждое представление может иметь свой собственный набор триггеров. Соответственно, для одних и тех же данных, доступ к которым производится через различные представления, можно определить различные пра- вила обработки. Обновление представлений В зависимости от способа определения, представления могут быть обновляемы- ми или необновляемыми. Правила, по которым определяется возможность об- новления представления, сложны и зависят от конкретной СУБД. Чтобы понять, почему это так, рассмотрим следующие два оператора, запрашивающие обновле- ние представлений, определенных в предыдущем разделе: UPDATE CustomerTablel SET Email = 'NewEmailAddress@soniewhere.com' WHERE CustomerlD = 1000: и UPDATE ArtiStNet SET Email = 'NewEmailAddress@somewhere.com' WHERE CustomerlD = 1000: Первый запрос будет обработан без каких-либо проблем, поскольку представ- ление CustomerTablel имеет идентичную структуру с таблицей CUSTOMER; по сути, оно является просто псевдонимом для этой таблицы. Второй же запрос вообще не имеет смысла. TotalNet представляет собой сумму значений вычисляемого стол ца. Нигде в базе нет столбца с таким именем, который можно было бы обновить Поэтому ясно, что второй запрос выполнен быть не может. Во врезке «Правила обновления представлений» приведены общие прав na- no которым можно определить, является ли представление обновляемым. говоря, чтобы обновить представление, СУБД должна иметь в03М”жнос‘Ьт^101ч зать столбцы, предназначенные к обновлению, с конкретной строкой к01’к^ таблицы. Чтобы выяснить, так ли это, задайте себе вопрос: что сделали бы
SQL-представления 327 месте СУБД, если бы вас попросили обновить это представление? Имеет ли смысл данный запрос? Если да, то достаточно ли у вас данных, чтобы его выпол- нить? Очевидно, например, что если таблица содержится в представлении цели- ком и вычисляемые столбцы отсутствуют, то такое представление является об- новляемым. ПРАВИЛА ОБНОВЛЕНИЯ ПРЕДСТАВЛЕНИЙ ----------------------------------------- Обновляемые представления: ♦ основанные на одной таблице, в которой нет вычисляемых столбцов, а все непустые столбцы присутствуют в представлении, ♦ основанные на любом количестве таблиц, с возможным наличием вычисляемых столбцов — в случае, если для представления определен замещающий триггер. Представления, которые могут быть обновляемыми: ♦ основанные на одной таблице, первичный ключ присутствует в представлении, неко- торые обязательные столбцы отсутствуют Обновление и удаление могут быть раз- решены, вставка запрещена; ♦ основанные на нескольких таблицах; обновление может быть разрешено для самой нижней таблицы в иерархии подчинения, если строки этой таблицы могут быть уни- кальным образом идентифицированы. Если в представлении отсутствуют какие-либо обязательные (NOT NULL) столбцы, добавление новых данных через это представление невозможно. Его, однако, можно использовать для обновления и удаления данных, если представ- ление содержит первичный ключ (или ключ-кандидат, как в некоторых СУБД). Многотабличные представления могут быть обновляемыми по самой подчинен- ной таблице, если первичный ключ или ключ-кандидат этой таблицы присут- ствует в представлении. Все представления, для которых определен замещающий триггер (триггер INSTEAD OF), считаются обновляемыми. Когда СУБД получает запрос на обновле- ние такого представления, она вызывает замещающий триггер, как описывается в разделе, посвященном триггерам, далее в этой главе. SQL-представления не являются внешними представлениями Прежде чем мы запершим обсуждение представлений, важно, чтобы вы поняли следукдцее; SQL-представления — это не то же самое, что мы называли внешни- ми представлениями и главе 2. SQL-предсгавлепня, которые мы обсуждаем в этой •Тшвс, содержат данные возвращаемые одним SQL оператором Чтобы уяснить разницу между ними, вернемся к рис. 7.2, б. Предположим, ^©пользователям требуется форма для ввода данных, содержащая все сведения ©клиенте Внешнее ирсд<тандешк-, необходимое для создания такой формы, долж- но тоиочт все покупки, сделанные этим клиентом, а также перечень ннтерс его художников С помощью SQL представления мы можем получить Айниые обо жгх покупках ипи данные о художественных интересах клиента,
328 Глава 7 Испслъзоваяие 8QL в ж> мы не можем построить SQL представление, мпириг гм* данные. Дело в том. что получение обоих видов данных гргб^.бы ври» дсння схемы базы данных по шум различным многозначным ыаршручЖМ w, каждого из этих маршрутов необходим отдельный оператор SflfCT SQL-представления являются подмножеством шн-шрих пргдг ммлетт* £ помощью можно реализовать некоторые — но не все — внешние tipeari«b.wMJU Представление, содержащее все данные о клиенте, должно строиться приход, ной программой, как будет показано в последнем разделе этой главы, Его мож- но также материализовать в форме XML-документа, как вы узнаете мл гмвм и Но в виде SQL-представления его выразить нельзя. Я Встраивание SQL-операторов в прикладные программы SQL-операторы можно встраивать в триггеры, хранимые процедуры и приклад- ные программы. Но прежде чем мы приступим к обсуждению каждого из этих случаев, необходимо описать в общих чертах принцип встраивания SQL-onepero- ров в программный код. Необходимо преодолеть два затруднения. Во-первых, нужен какой-то способ позволяющий записывать результаты выполнения SQL-операторов в программ- ные переменные. Это можно сделать по-разному. В одних случаях для этого ис- пользуются объектно-ориентированные программы (главы 12 и 13), в других применяются более простые методы. Например, в PL/SQL, собственном языке СУБД Oracle, следующий оператор присваивает переменной rowcount значение, равное количеству строк в таблице CUSTOMER: SELECT Count(*) into rowcount FROM CUSTOMER; В SQL Server оператор с той же функциональностью выглядит сл< n » ••• '’ образом: SELECT FROM В обоих случаях количество строк в таблице CUSTOMER будет записано в про- граммную переменную rowcount или @rowcount. Вторая трудность заключается в несоответствии парадигм SQL паради языков программирования. Язык SQL оперирует множествами: болыииж: операторов SQL возвращают таблицу или набор строк. В отличие от этого, граммы оперируют отдельными элементами или строками. Из-за этой раз оператор, подобный приведенному ниже, не имеет смысла: SELECT FROM 1 3J •*4г @rowcount = Count(*) CUSTOMER: Q Name into custName CUSTOMER.
Триггеры 329 Если в таблице CUSTOMER имеется 100 строк, то запрос столбца Name возвра- тит 100 значений, в то время как переменная custName может принять только одно значение. Чтобы преодолеть это затруднение, результаты выполнения SQL-операторов обрабатываются как псевдофайлы. SQL-оператор возвращает набор строк. На первую строку помещается курсор, и данная строка обрабатывается. Затем кур- сор перемещается на следующую строку, и так далее, пока не будут обработаны все строки. Типичный процесс обработки выглядит так: Открыть файл SQL (SELECT * FROM CUSTOMER); Поместить курсор на первую строку. Пока курсор не вышел за пределы таблицы { Присвоить custName значение столбца Name в строке под курсором : ...Прочие операторы, использующие это значение custName... Переместить курсор на следующую строку; }: .. .Продолжение обработки... Таким образом, строки, возвращенные SQL-оператором, обрабатываются по одной. Многочисленные примеры применения этих и других методов вы увидите в последующих главах. В данный момент просто попытайтесь уяснить себе в об- щих чертах принцип встраивания SQL-операторов в программный код. Триггеры Триггер (trigger) — это специальная программа, назначаемая таблице или пред- ставлению. Триггер вызывается СУБД, когда пользователь запрашивает вставку, обновление или удаление строки из таблицы или представления, которому при- надлежит данный триггер. Триггеры для Oracle можно писать на собственном языке программирования этой СУБД, носящем название PL/SQL (Programming Language for SQL — язык программирования для SQL), или на Java. Триггеры Для SQL Server пишутся на собственном языке этой СУБД, который называется (Transaction SQL, транзакционный SQL). Oracle поддерживает три вида триггеров: предваряющие (BEFORE), замеща- ющие (INSTEAD OF) и завершающие (AFTER). Как и логично было бы ожидать, пред- варяющие триггеры вызываются перед обработкой запроса на вставку, обновле- ние или удаление, замещающие — вместо него, а завершающие после обработки Запроса Всею имеется девять возможных типов триггеров: предваряющий триг- fep вставки, обновления и удаления, замещающий триггер вставки, обновления И удаления и завершающий триггер вставки, обновления и удаления. SQL Server поддерживает только замещающие и завершающие триггеры, ««этому для данной СУБД имеется только шесть возможных типов триггеров. В Других СУБД Поддержка тpin iеров также имеет разный уровень. Перечень Лйстуинмх нам типов трип срои вы панде тс в документации па используемую «Ми СУБД.
ззо Глава 7. Использование SQL в приложениях При запуске триггера СУБД предоставляет доступ к вставляемым -4- емым или удаляемым из тела триггера данным В случае вставки тригщ** тупны значения столбцов новой строки, в случае удаления - знания , т *7 цов удаляемой строки, а в случае обновления триггер может новыми, так и старыми значениями Способ, при помощи которого это делается, зависит от конкретной СУ К т Пока что предположим, что для получения новых значений необходимо вить к имени столбца префикс :new. Так. например, при вставке в таблэд CUSTOMER переменная :new.Name содержит значение столбца Name «-гацинмХ строки. В случае обновления переменная .new. Na те содержит значение, г.-?,, будет иметь столбец Name после выполнения запроса Аналогичным будем считать, что для получения старых значений необходимо добавить к хмщ» интересующего нас столбца префикс rold.. Например, при удалении •v-eBa .•old.Name содержит значение столбца Name удаляемой строки В случае лення эта переменная содержит значение столбца Name до выполнения вт<ха (На самом деле именно такая стратегия используется Oracle. Эпякалемпм стратегия SQL Server будет описана в главе И.) Триггеры имеют множество применений. В этой главе мы рассмотрим че- тыре из них: проверка допустимости вводимых данных, присваивание значе- ний по умолчанию, обновление представлений и обеспечение ссылочной цело- стности. Использование триггеров для проверки допустимости вводимых данных Предположим, у галереи View Ridge есть правило, что ни одна работа не может быть продана менее, чем за 90 % от запрошенной цены. Чтобы обеспечить - ние этого правила, можно написать триггер обновления для таблицы TRANSACTION, сравнивающий значения AskingPrice и SalesPrice. Если правило нарушается, в стол- бец AskingPrice ставится исходное значение. Можно использовать две стратегии. Одна заключается в том. чтобы написать предваряющий триггер, который проверяет и переустанавливает, если необхп» мо, значение столбца SalesPrice до выполнения обновления. Вторая стратсгня- написать завершающий триггер, проверяющий и переписывающий строку г липы TRANSACTION после обновления. Любая из этих стратегий годится, гяа ное, чтобы СУБД поддерживала соответствующий тип триггеров. SQL Sen не поддерживает предваряющие триггеры, поэтому мы воспользуемся втор подходом. Код триггера показан в листинге 7.9. Этот код близок к реальному коду Oracle, но детали, несущественные для нашего обсуждения, были опушены альный код триггера для Oracle вы увидите в главе 10, а для SQL Server ве 11, после того как мы обсудим опущенные нами детали. Обратите вн что комментарии помешаются в скобки вида /* */.
Триггеры 331 Листинг 7.9. Пример завершающего триггера, проверяющего допустимость значений CREATE TRIGGER TRANSACTION_SalesPricecheck AFTER UPDATE ON TRANSACTION BEGIN IF .new.SalesPrice < .9 * :old.AskingPrice THEN /* Продажная цена слишком низка, необходимо повысить ее */ UPDATE TRANSACTION SET SalesPrice = :old.AskingPrice: AskingPrice = :old.AskingPrice: • /* Примечание: это обновление приведет к рекурсивному вызову данного триггера. Рекурсия остановится во второй раз. поскольку продажная цена будет равняться запрашиваемой. */ /* Кроме того, нужно выдать пользователю сообщение о том', что было сделано. */ END IF: END: Логика работы триггера очевидна. Если новая продажная цена составляет ме- нее 90 % от старой запрашиваемой цены, продажная цена устанавливается рав- ной запрашиваемой цене. Обратите внимание, что новая продажная цена срав- нивается со старой запрашиваемой ценой; в противном случае можно было бы, изменив обе цены, успешно совершить обновление, нарушающее данное ограни- чение. На тот случай, если именно так и произошло, столбец AskingPrice в опера- торе UPDATE устанавливается равным :old.AskingPrice. Также обратите внимание, что этот триггер будет вызываться рекурсивно. Оператор UPDATE в триггере вызовет обновление таблицы TRANSACTION, что, в свою очередь, приведет к повторному вызову триггера. На этот раз, однако, столбец SalesPrice будет равен :old.AskingPrice, поэтому новых обновлений произведено не будет и рекурсия остановится. Этот пример показывает суть обработки, происходящей в простом триггере. В следующем примере мы рассмотрим несколько более сложный случай. Использование триггеров для присвоения значений по умолчанию В главе 6 вы научились ирис ввивать столбцам значения по умолчанию с помощью квалификатора DEFAULT. В качестве таких значений можно задавать константы Или рсчулыаты вычисления простых выражении. Если же задание значения по умолчанию требует более сложной логики, необходимо использовать триггер. И|и-диоложим, например, что у галереи View Ridge имеется правило, согласно Которому запрашиваемая цепа произведения устанавливается равной удвоенной стоим<»< in счо ириобрсчення или сумме общей стоимости приобретения н чпе- *ОЙ выручки от Продажи этого произведения в прошлом. Эго пр шило реализуется
332 Глава 7. Использование SQL в приложения» с помощью завершающего триггорз, показанного в листинге 7 10 Кол ~,ш гора также упрощен по сравнению с реальным. Листинг 7.10. Пример завершающего триггера, присваивающего <”>• по ум&лчани^ CREATE TRIGGER TRANSACTION AskingPricelnitialValue AFTER INSERT ON TRANSACTION DECLARE rowcount as int; sumNetPrice as numeric (10.2). avgNetPnce as numeric (8,2). BEGIN /* Сначала проверяем, появлялась ли работа в галерее прежде */ SELECT Count!*) INTO rowcount FROM TRANSACTION T WHERE :new.WorkID = T.WorkID IF rowcount = 1 THEN /* Работа появилась в галерее впервые */ .•new.Askingprice = 2 * -.new.AcquisitionPrice; ELSE IF rowcount > 1 THEN /* Работа уже появлялась в галерее */ SELECT sum(NetPrice) Into sumNetPrice FROM ArtistWorkNet AW WHERE AW.WorkID = :.new.WorkID GROUP BY AW.WorkID; avgNetPrice = sumNetPrice / (rowcount - 1)'; /* Теперь устанавливаем более высокую цену */ IF avgNetPrice >2* :new.AcquisitionPhce THEN :new.Askingprice = avgNetPrice; ELSE .new.Askingprice = 2 * :new.Acquisitionprice; END IF; ELSE /* Ошибка: количество строк не может быть меньше 1 - выполняем какие-то действия*/ END IF; END IF; END;
Триггеры 333 После объявления программных переменных триггер подсчитывает строки в таблице TRANSACTION, относящиеся к данному произведению, и записывает ре- зультат в переменную rowcount. Поскольку триггер завершающий, к этому мо- менту новая строка уже будет вставлена в таблицу TRANSACTION, и количество строк будет равно 1, если это первый раз, когда данное произведение появляется в галерее. В таком случае значение столбца SalesPrice устанавливается равным удвоенному значению столбца Acquisition Price. Если количество строк больше 1, это значит, что произведение уже появлялось в галерее ранее. Для вычисления средней выручки от продажи этого произведения мы можем использовать представление ArtistWorkNet, описанное ранее в разделе «Скрытие группировки и встроенных функций». Следующий SQL-оператор с по- мощью этого представления вычисляет совокупную чистую выручку от продажи данного произведения, результат записывается в переменную sumNetPrice. Обра- тите внимание, что предложение WHERE выбирает только те строки, которые от- носятся к данному произведению. Затем вычисляется среднее арифметическое путем деления этой суммы на количество строк минус 1. Вас может удивить, что для вычисления среднего значения мы не использо- вали встроенную функцию SQL — Avg(NetPrice). Дело в том, что функция Avg при вычислении среднего значения учла бы и только что добавленную строку. Мы же этого не хотим, поэтому перед расчетом среднего вычитаем 1 из общего количества строк. Рассчитанное значение avgNetPrice сравнивается с удвоенным значением Acquisition Price, и большее из них устанавливается в качестве нового значения AskingPrice. Обновление представлений Как уже говорилось, одни представления могут быть обновлены с помощью СУБД, а другие нет. Обновление тех представлений, которые невозможно обно- вить с помощью СУБД, в ряде случаев может выполнить само приложение. Про- цедура обновления оформляется в этом случае в виде замещающего триггера. Рассмотрим представление Customerinterests, описанное выше в разделе «Скры- тие соединений» (листинг 7.6). Это представление строится путем соединения таблиц CUSTOMER и ARTIST через таблицу пересечения. Пусть это представление используется для заполнения данными некоторой формы, и при необходимости пользователи должны иметь возможность внести изменения в эту форму. Если внести изменения будет невозможно, это вызовет недовольство пользователей: в самом деле, вот передо мной мое имя, почему же я не могу его изменить? (Сами они, разумеется, не имеют ни малейшего представления о том, что пришлось ис- пытать бедной СУБД, чтобы только отобразить эти данные!) В общем случае представление Customerinterests является необновляемым. Однако если пользователь хочет изменить имя, и это имя оказалось уникальным в таблице CUSTOMER, то мы можем просто обновить таблицу CUSTOMER, а затем заново сгенерировать представление. Так мы можем создать впечатление, что представление обновляется. В листинге 7.11 изображен замещающий триггер выполняющий >гу процедуру.
334 Глава 7. Использовании SQL в приложениях Листинг 7.11. Пример замещающего триггера, обновляющего представление CREATE TRIGGER CustomerinterestJkistomerNameUpdate INSTEAD OF UPDATE ON CustomerInterests DECLARE rowcount as int; BEGIN SELECT Count!*) INTO rowcount FROM CUSTOMER C WHERE C.Name = .-old.Customer; IF rowcount > 1 THEN /* Неуникальное имя - обновление невозможно */ /* Выдаем пользователю сообщение о том. что имеется несколько клиентов с таким именем и обновление невозможно, поскольку неизвестно, для какого из них выполнять обновление */; ELSE /* Имеется только один клиент с таким именем. Изменяем имя. */ UPDATE CUSTOMER SET CUSTOMER.Name = new.Customer WHERE CUSTOMER.Name = ;old.Customer' END IF; END; Логика работы триггера проста. Сначала подсчитывается количество строк в таблице CUSTOMER, в которых значение столбца Name совпадает со значением пе- ременной rold.Customer (напомним, что столбцу CUSTOMER.Name в представлении Customerinterests дан псевдоним Customer). Если таких строк больше одной, об- новление невозможно, поскольку значение rold.Customer не является уникальным в таблице CUSTOMER. Если имеется только одна такая строка, триггер выполняет обновление таблицы CUSTOMER. Обратите внимание, что триггер не обновляет са- мо представление — обновлению подвергается таблица, на которой базируется представление. По завершении работы триггера приложение должно повторно запросить данные из представления, чтобы получить обновленное имя клиента. Эта логика типична для замещающих триггеров. Они обычно обрабатывают разною рода особые случаи — например, как здесь, выполнение неко торого лей ствпя над одной пли несколькими таблицами. Процедуры обеспечения ссылочной целостности Написание триггеров, выполняющих процедуры обеспечения ссылочной ,,сЛ0^ пости, требует тщательного анализа и проектирования. £слн целью три'
- ____________________________Триггеры 335 является сделать некоторое действие возможным (например, удалить строку из таблицы TRANSACTION, чтобы сделать возможным удаление строки из таблицы WORK), то завершающий триггер использовать нельзя, поскольку СУБД откажет в удалении прежде, чем будет вызван триггер. Еще одно затруднение состоит в том, что для триггеров не существует меха- низма передачи отклика вызывающей процедуре. Это особенно серьезная про- блема. поскольку работа одного триггера может привести к запуску другого триггера, и т. д. Таким образом, иногда может быть трудно уведомить пользо- вателя вызывающей программы о том, что было сделано триггером, включая кас- кадные триггеры. Все это означает, что код триггера должен быть тщательно спроектирован и написан. Еще более важно протестировать его работу во всех возможных си- туациях. Кроме того, исправление ошибок может представлять трудность, если источник проблем скрыт и его трудно отследить. В этом разделе описывается два простых триггера, реализующих процеду- ры обеспечения ссылочной целостности. Имейте в виду, однако, что реальные ситуации могут оказаться куда более сложными. При добавлении нового произведения для него уже должна существовать транзакция Согласно модели данных View Ridge, каждой строке в таблице WORK должна соот- ветствовать по крайней мере одна строка в таблице TRANSACTION. Для новых работ в этой строке должны быть указаны дата и стоимость приобретения. Если приложение по ошибке добавит строку в таблицу WORK, не создав пред- варительно строку в таблице TRANSACTION, эту ситуацию должен исправить триг- гер. Есть две возможности: либо удалить вставленную только что строку, либо добавить в таблицу TRANSACTION строку с заданными по умолчанию значениями атрибутов. Удаление строки из таблицы WORK — слишком радикальное средство, поэтому лучше было бы создать новую строку в таблице TRANSACTION и связать ее с новой строкой в таблице WORK. В таком случае возникает вопрос: какие значения необходимо присвоить столбцам по умолчанию. Единственными обязательными столбцами являются DateAcquired и WorkID, причем значение WorkID у нас имеется. Поэтому если в стол- бец DateAcquired в качестве значения по умолчанию записать системную дату, то У нас будет достаточно данных для того, чтобы создать новую строку в таблице TRANSACTION. Задать стоимость приобретения по умолчанию мы не можем, по- этому столбец AcquisitionPrice придется оставить пустым. Это означает, что все процедуры, обрабатывающие эту базу данных, должны быть готовы к тому, что им может встретиться пустое значение AcquisitionPrice. Обычно именно в этот момент кто-нибудь из разработчиков вспоминает о триг- гере из листинга 7.10. Посмотрите па код триггера, и вы увидите, что пустое Значение AcquisitionPrice будет представлять трудности. Пам необходимо либо Изменить трип ср из лис инна 7.10, чтобы учесть там возможность появления пустою значения, либо все таки пайги способ определить значение по умолча- нию для столбца AcquisitionPrice вновь создаваемой строки таблицы TRANSACTION.
336 Г лава 7. Использование SQL в приложениях Из этого примера вы можете получи и» представление о природе решеяий торые приходится принимать при реализации процедур обеспечения целостности с помощью триггеров. Па данный момент для упрощения ми ™ мем, что любая новая строка в таблице WORK, для которой не имеется Conner ствия в таблице TRANSACTION, будет удаляться. Трин-ер, реализующий эту тику, показан в листинге 7.12. Листинг 7.12. Пример завершающего триггера, реализующего ограничение обязательного потомка CREATE TRIGGER WORK_TRANSACTION_Check AFTER INSERT ON WORK DECLARE rowcount as int; BEGIN /* Сначала ищем соответствующую строку в таблице TRANSACTION */ SELECT Count!*) INTO rowcount FROM TRANSACTION T WHERE ;new.WorkID = T.WorkID; IF rowcount = 0 THEN /* Удаляем только что добавленную строку */ DELETE FROM WORK WHERE WORK.WorkID = :new.WorkID /* Необходимо как-то уведомить пользователя о том. что произошло */ END IF; END: огика прос та, сначала подсчитывается количество строк в таблице TRANSACTION ля hoboi о значения WorkID, и если таких строк не найдено, созданная только что строка в таблице WORK удаляется. Между прочим, более подходящим способом шлейфе С™ ЭТ? Удги1ение был бы откат транзакции, вызвавшей вставку в таблиц) WORK. 1 аким образом, все действия с базой данных, выполненные в связи с данной вставкой в таблицу WORK, были бы также отменены. Мы опишем этот способ, после того как обсудим обработку транзакций в главе 9. Одновременное удаление из таблиц WORK и TRANSACTION Вспомните, что в соответствии с процедурами обеспечения ссылочной целос31^ ста, определенными для базы данных галереи View Ridge, произведение быть удалено из базы данных только в гом случае, если оно появлялось в данных лишь однажды и ни разу не было продано. На языке операций с та®3
Триггеры 337 мл это означает, что строку из таблицы WORK можно удалить только в том случае, если ей соответствует только одна строка в таблице TRANSACTION, причем столбец CustomerlD в этой строке является пустым. Это правило можно реализовать с помощью замещающего триггера удаления для таблицы WORK. Обобщенный код такого триггера показан в листинге 7.13. Таблица WORK не должна содержать строк, которым не соответствовало бы ни одной строки в таблице TRANSACTION, поэтому если значение переменной rowcount равно нулю, выдается сообщение об ошибке. Далее, если rowcount = 1, необходимо определить, не является ли столбец TRANSACTION.CustomerlD пус- тым. Для подсчета соответствующих строк используется оператор SELECT. Если nullCount = 1, то строки будут удалены. Удаление должно производиться в ука- занном здесь порядке. Если бы порядок был обратный, СУБД отказала бы в уда- лении строки из таблицы WORK, поскольку у нее есть зависимая строка в таблице TRANSACTION. Листинг 7.13. Пример замещающего триггера удаления, реализующего правило удаления произведений CREATE TRIGGER WORK_Deletion INSTEAD OF DELETE ON WORK DECLARE rowcount as int; nullCount as int: BEGIN /* Сначала ищем соответствующие строки в таблице TRANSACTION */ SELECT Count!*) INTO rowcount FROM TRANSACTION T WHERE :new.WorkID = T.WorkID: IF rowcount = 0 THEN /* Такого не должно происходить - ошибка. Делаем запись в журнале ошибок и выходим */ ELSE IF rowcount = 1 THEN /* Проверяем, не пуст ли столбец CustomerlD */ SELECT Count!*) into nullCount FROM TRANSACTION T WHERE :old.WorkID - T.WorkID AND T.CustomerID IS NULL. IF nullCount - 1 THEN /* Удаление должно производиться именно в таком порядке */ продолжение#
338 Г лава 7 Использование SQL в приложениях Листинг 7.13 (продолжение) DELETE FROM TRANSACTION Т WHERE :old.WorkID - T WorkID DELETE FROM WORK W WHERE :old.WorkID - W WorkID END IF: END IF: END IF: END; Хранимые процедуры Хранимая процедура (stored procedure) — это программа, которая выполняет не- которые действия с информацией в базе данных и при этом сама хранится в базе данных. В Oracle хранимые процедуры можно писать на языках PL/SQL и Java. В SQL Server хранимые процедуры пишутся на языке T-SQL. Хранимые процедуры могут принимать входные параметры и возвращать ре- зультаты. В отличие от триггеров, которые принадлежат определенной таблице или представлению, хранимые процедуры принадлежат базе данных в целом. Они Moi-ут вызываться любым процессом, использующим базу данных, при условии, что у этого процесса есть достаточные права доступа. Хранимые процедуры используются для многих целей. Хотя администраторы баз данных используют их для выполнения рутинных задач администрирования, главной областью их применения являются все же приложения баз данных. Эти процедуры могут вызываться из прикладных программ, написанных на таких языках, как Java, С#, C++ или VB.Net, а также из веб-сценариев, написанных на VBScript или JavaScript. Кроме того, эти процедуры можно вызывать в интерак- тивном режиме из командной оболочки СУБД — например, SQL*Plus в Oracle пли Query Analyzer в SQL Server. Наконец, хранимые процедуры как Oracle, так и SQL Server могут вызываться из среды Microsoft Visual Studio.NET. Преимущества хранимых процедур Преимущества использования хранимых процедур перечислены во врезке. В от- личие от кода приложения, хранимые процедуры никогда не передаются на кли- ентские компьютеры. Они всегда находятся в базе данных и выполняются СУБД на том компьютере, где располагается сервер базы данных. Такны образом, они более безопасны, чем распространяемый код приложения, а кроме того, снижают сетевой трафик. Хранимые процедуры постепенно становятся предпочтитель- ным режимом реализации логики приложения в сети Интернет и корпоративных интрасетях. Еще одно преимущество хранимых процедур заключается в том, что SQL-операторы в них могут быть оптимизированы компилятором СУБД.
Хранимые процедуры 339 ПРЕИМУЩЕСТВА ХРАНИМЫХ ПРОЦЕДУР ---------------------------------—---------— ♦ Большая безопасность. ♦ Меньший сетевой трафик. ♦ SQL можно оптимизировать. ♦ Совместное использование кода: • меньшее количество работы; • стандартизированная обработка; • специализация между разработчиками. Когда логика приложения реализуется ввиду хранимой процедуры, получен- ный код может совместно использоваться разными программистами. Совместное использование не только уменьшает трудозатраты, по и обеспечивает стандар- тизацию обработки. Кроме того, это позволяет более эффективно распределить работу': программисты, специализирующиеся на базах данных, могут создавать хранимые процедуры, а другие программисты, например, специализирующиеся на веб-разработке, могут выполнять другую работу. Благодаря этим преимуществам представляется весьма вероятным, что хра- нимые процедуры получат большее распространение в будущем. Далее, эти пре- имущества, скорее всего, побудят Microsoft модифицировать SQL Server таким образом, чтобы хранимые процедуры можно было писать на языках .NET, на- пример, VB.Net и С#. Как уже упоминалось, Oracle уже сейчас позволяет писать хранимые процедуры на Java. Хранимая процедура Add_WORK В листинге 7.14 представлена хранимая процедура, регистрирующая приобрете- ние произведения галереей View Ridge. Этот код также является упрощенным, но стиль его близок к тому, что используется в SQL Server, в отличие от Oracle- подобного стиля, использованного в приведенных выше примерах с триггерами. Сравнив эти примеры, вы получите некоторое представление о различиях между PL/SQL и T-SQL. Листинг 7.14. Хранимая процедура, регистрирующая приобретение произведения CREATE PROCEDURE AddWORK ( ©ArtistlD int. /* Художник должен уже присутствовать в базе данных */ ©Title ciiar(25), ©Copy char(B). ©Description varchar(lOOO). ©AcquisitionPrice Numeric(6.2). 1 /* Хранима процедура, регистрирующая приобреюние илсреей произведения Если произведений никогда раньше не появлялось • галерее в таблицу WORK добавляется новая строка
340 Глава 7. Использование SQL в приложениях Листинг 7.14 (продолжение) В противном случае испольуется существующая строка Далее добавляется строка в таблицу TRANSACTION, а столбец DateAcquired в ней устанавливается равным системной дате */ AS DECLARE Prowcount as int DECLARE PworkID as int /* Сначала следует убедиться, что ArtistID имеет допустимое значение */ SELECT Prowcount = Count!*) FROM ARTIST A WHERE A.ArtistID = PArtistID IF Prowcount = 0 /* Нет такого художника */ BEGIN Print 'Нет художника c ID = ' + Str(PartistID) Print ’Обработка прервана.' return END /* Теперь смотрим, есть ли это произведение в базе данных */ SELECT Prowcount = Count!*) FROM WORK W WHERE W.ArtistID = PArtlstID and W.Title = PTitle and W.Copy = PCopy IF Prowcount = 0 /* Произведения нет в базе, записываем его */ INSERT INTO WORK (Title. Copy.. Description. ArtistID) VALUES (PTitle. PCopy. PDescription. PArtistID) /* Получаем значение суррогатного ключа WorkID */ SELECT PworkID - W.WorkID FROM WORK W WHERE W.ArtistID = PArtistID and W.Title - PTitle and W.Copy - PCopy /* Вставляем новую строку в таблицу TRANSACTION */ INSERT INTO TRANSACTION (DateAcquired. AcquisitionProce. WorkID) VALUES (GetDateO.PAcquisitionPrice. PworkID) RETURN
Использование SQL в коде приложения 341 П цедура Add.WORK принимает пять входных параметров и не возвращает никакого значения. В более реалистичном примере процедура передавала бы в вызывающую программу код возврата, указывающий на успешное или неудач „се завершение операции. Однако это увело бы „ас от оборкдения баз дан" поэтому мы не будем рассматривать этот вопрос. роцедура подразумевает, что переданное ей значение ArtistID является дей- ствующим идентификатором. Чтобы убедиться в том, что это так, первый блок операторов подсчитывает количество строк, имеющих указанное значение ArtistID. Если это количество равно нулю, значит, процедуре было передано недопусти- мое значение ArtistID; в этом случае процедура выводит сообщение об ошибке и завершает работу. В противном случае’ процедура проверяет, не появлялось ли это произведе- ние в галерее в прошлом. Если да, то в таблице WORK уже есть строка, содержа- щая данные о художнике, названии произведения и номере копии. Если нет, то таблице WORK создается новая строка. После этого с помощью оператора SELECT процедура получает значение WorkID. Если мы имеем дело с только что создан- ной строкой в таблице WORK, этот оператор необходим, чтобы получить повое значение суррогатного ключа WorkID. Если произведение уже существовало в ба- зе данных, то с помощью этого оператора мы получаем WorkID уже существую- щей строки. Получив значение WorkID, процедура вставляет новую строку в таблицу TRANSACnON. Обратите внимание, что для присвоения значения по умолчанию столбцу DateAcquired используется системная функция GetDate(). Эта процедура представлена здесь для того, чтобы дать вам общее представ- ление о том, как встраивать операторы SQL в хранимые процедуры. Она не яв- ляется законченной — главным образом потому, что необходимо еще гарантиро- вать, что в базе данных будут выполнены либо все изменения, либо ни одно из них. Как это сделать, вы узнаете из главы 9. Пока что сосредоточьтесь на том, как операторы SQL, с которыми вы познакомились в предыдущей главе, могут использоваться в приложениях баз данных. Использование SQL в коде приложения В завершение пой главы кратко обсудим использование SQL в прпк.J^po граммах Рассмотрим форму с данными о покупках клиента, изо н• с ' РЖ 73 Эв Форма является ма.ерналнзацисн внешнего предел таблицы CUSTOMER. Вверху в центре в шй представлены <к О Клиенте, справа интересующие клиента художники, а в ., «ершенные данным клиентом Г г, ,т сколько «трок имеет > казанное значение ArtistID одну йе РроШводю проверку гкольк псл0 п т<>м, чтх> ArtistID Ав
342 Глава 7. Использование SQL в приложениях Рис. 7.3. Форма с данными о покупках клиента Поскольку данные, содержащиеся в этой форме, требуют прохождения схемы базы данных по двум различным многозначным маршрутам (один через таблицу CUSTOMER_ARTIST_INT, а другой через таблицу TRANSACTION), форма не может быть заполнена данными с помощью SQL-представления. Для получения данных не- обходимо использовать несколько SQL-операторов. Для обработки этой формы прикладная программа передает на выполнение СУБД соответствующие SQL-операторы и отображает результаты запросов в по- лях формы. Кроме того, прикладная программа обрабатывает и координирует действия пользователя при работе с формой — например, наполнение раскры- вающегося списка и внесение необходимых изменений во внешние ключи для создания связей, когда пользователь выбирает элемент из списка. В форме на рис. 7.3 список интересующих клиента художников заполняется путем соединения таблиц CUSTOMER и ARTIST через CUSTOMER_ARTIST_INT. как мы делали для представления Customerinterests. Это делает следующий SQL-оператор- SELECT A.Name FROM CUSTOMER С JOIN CUSTOMER_ARTIST_INT CA ON C.CustomerlD = CA.CustomerlD JOIN ARTIST A ON CA.ArtistID = A.ArtistID WHERE Customerld = Form.CUSTOMER.Customer.ID: Здесь Form.CUSTOMER.CustomerlD — это значение столбца CustomerlD для данные о котором отображаются в форме (в данном случае это Tiffany Tw 1 1F
Использование SQL в коде приложения 343 «За кулисами» прикладная программа передает СУБД на выполнение этот или похожий оператор, а результаты отображает в списке Artists Interests (Инте- рес к художникам). v с Далее, для заполнения таблицы Purchases (Покупки) необходим ратор: другой SQL-one- SELECT A.Name. W.Title. W.Copy. W.PurchaseDate. W SalesPrice FROM CUSTOMER C JOIN TRANSACTION T ON C.CustomerlD = T.CustomerlD JOIN WORK W ON T.WorkID = W WorkID JOIN ARTIST A ON W.ArtiStID = A.ArtiStID WHERE CustomerlD = Form.CUSTOMER.CustomerlD. Результаты выполнения этого оператора программа помещает в таблицу Purchases (Покупки). Наконец, на рис. 7.3 пользователь регистрирует новую покупку. В раскры- вающемся списке показа1цл произведения, имеющиеся в галерее. Наполнение это- го списка производит следующий SQL-оператор: SELECT A.Name. W.Title. W.Copy FROM TRANSACTION T JOIN WORK W 0. T.WorkID = W.WorkID JOIN ARTIST A ON W.ArtiStID = A.ArtiStID: Если пользователь выбирает элемент из комбинированного списка, приложе- ние должно связать этот элемент с покупками пользователя, создав новую стро- ку в таблице TRANSACTION. Значения столбцов DatePurchased и SalesPrice необхо- димо взять из формы. На самом деле на рис. 7.3 изображена форма Microsoft Access, и большая часть SQL-кода была сгенерирована встроенными мастерами этой программы. Но по крайней мере, вы знаете, что они делают. Можно также поправить результат работы мастеров. Например, обобщенный запрос, который программа Access сгенерировала для наполнения комбиниро- ванного списка, не годился, поскольку отображал все произведения, независимо от того, проданы они или пет. Зная это, можно открыть окно параметров формы и модифицировать запрос, чтобы отображались только те произведения, у кото- рых столбец TRANSACTION.CustomerlD пуст: A Name, W Title. W Copy FROM TRANSACTION T JOIN WORK W ON T WorkID - W WorkID JOIN ARTIST A ON W ArtiStID * A ArtiStID WHF TRANSACTION CustomerlD * Null
344 Глава 7. Использование SQL в приложениях При исполъзоваияи Лгопт мпрюса форма примет вид, и иЮрлженный |Ч, 7 Единственная доступная для продажи рабом — ио копня № 105 литогпыкт «Mystic Fabric». Поскольку у Tiffany Twilight уже есть копня этой работ рее придется найти па нее другого покуцаи-ля. Рис. 7.4. Предпочтительный вид формы Конкретные аспекты встраивания SQL-кода в прикладные щюграммы зави- ся г от используемых языка программирования п технологии манипулирования данными. Мы обсудим использование SQL в сочетании с VBScript при рас смотрении веб-приложеппп баз данных в главе 12, а также использование SQL в XML-ирпложеннях в главе 13. В главе 14 будет показано использование SQL операторов в языке Java в контексте Java Server Pages. Эго не сделает вас разра ботчиком SQL-ирнложеинн, по даст вам толчок и правильном направлении. По завершении этого курса вы должны будете представлять себе', как использовать SQL в любом языке программирования, с которым вы работаете. Знание этого языка в сочетании со знанием SQL позволит вам стать успешным разработчиком приложений баз данных, Резюме 3ia 1 лава базируется на фундаменте, заложенном в главе б, и |таге.матрнвае1 испопь зование SQL в контексте базы данных для галереи View Ridge. 11еречень rpi'Txws иий aroii галереи приведен во нрезке «Требования к приложению для галереи View Ridge», а модель данных представлена па рис 7 I Реляционная схема.
-------------------------------------____---------- Резюме 345 использующая в качестве ключей данные (см. рис. 7.1, 6), имеет серьезные про- блемы с ключами. В связи с этим в данной и последующих главах используется схема с суррогатными ключами (см. рис. 7.2, б). Для этой модели определены процедуры обеспечения ссылочной целостности (см. рис. 7.2, б). Операторы CREATE TABLE, создающие таблицы для базы данных галереи View Ridge, показаны в листинге 7.1. Единственное, что здесь появилось нового в пла- не синтаксиса, — это ограничения CHECK. Такие ограничения определяют множе- ство допустимых значений столбца. Чаще всего с помощью таких ограничений задается диапазон значений или нумерованный список. Кроме того, эти ограни- чения позволяют сравнивать между собой значения двух столбцов, а также ука- зывать формат значений столбца. Стандарт SQL-92 и некоторые СУБД разреша- ют использовать вложенные запросы в ограничениях CHECK. Данные для схемы, изображенной на рис. 7.2, б, приведены в табл. 7.1-7.5. SQL-представление — это виртуальная таблица, создаваемая из других таблиц и представлений. Представления определяются с помощью оператора SELECT; единственное ограничение заключается в том, что определение представления не может включать в себя предложение ORDER BY. Представления используются для скрытия отдельных строк или столбцов, для отображения вычисляемых столбцов и скрытия SQL-операторов со слож- ным синтаксисом, например, использующих соединения и группировку. Некото- рые организации с помощью представлений создают уровень абстракции между прикладными программами и таблицами. Представления позволяют также опре- делять различные наборы прав доступа к одним и тем же таблицам, а также на- значать им различные наборы триггеров. Правила, позволяющие определить, является ли представление обновляемым, сложны и зависят от конкретной СУБД. Общие соображения относительно обновляемости представлений приведены во врезке «Правила обновления пред- ставлений». Чтобы обновить представление, СУБД должна иметь возможность связать столбец, подлежащий обновлению, с конкретной строкой конкретной таблицы. Если для представления определен замещающий триггер обновления, СУБД будет считать это представление обновляемым. SQL-представления являются подмножеством внешних представлений, кото- рые обсуждались в начале главы 2. С их помощью можно реализовать только те внешние представления, для построения которых достаточно пройти схему базы данных только по одному многозначному маршруту. Внешние представления, содержащие два таких маршрута, например, представление базы данных View Ridge, содержащее сведения о покупках клиента и интересующих его художни ках, не могут быть выражены с помощью SQL-представления. Операторы SQL могут встраиваться в триггеры, хранимые процедуры и при- кладные программы. Для этого необходим какой-то способ, позволяющий связы вать столбцы таблиц, возвращаемых SQL-запросами, с программными перемен- ными. Кроме того, имеет место несоответствие парадигм между SQL и языками программирования. Большинство SQL-операторов возвращают наборы строк, а приложение рассчитывает получать строки по одной Для разрешения этого
346 Глава 7. Использования SQL в приложениях несоответствия результаты выподпеппя SQL-операторов обрабатываются псевдофайлы. Триггер — эго программа, .хранимая в базе данных и вызываемая СУБД ( . кип раз, когда выполняется заданное действие над определенной таблицей ил представлением. В Oracle триггеры можно писать па принадлежащем ОгасЬ языке под названием PL/SQL, а также па Java. В SQL Server трип еры можт писать на принадлежащем Microsoft, языке T-SQL. Есть три вида триггеров: предваряющие (BEFORE), замещающие (INSTEAD OF) и завершающие (AFTER). Каждый из этих типов триггеров может быть назван для вставки, обновления и удаления, поэтому всего имеется девять типов тригге- ров. Oracle поддерживает все девять типов, a SQL Server поддерживает только замещающие и завершающие триггеры. Когда запускается триггер, в случае обновления СУБД предоставляет ему доступ к новым и старым значениям данных. Новые значения доступны тригге- рам при вставке и обновлении, а старые — при обновлении и удалении. Способ доступа к этим значениям в теле триггера зависит от СУБД. Триггеры имеют множество применений. В этой главе обсуждаются четыре из них: проверка допустимости данных (см. листинг 7.9), присвоение значений по умолчанию (см. листинг 7.10), обновление представлений (см. листинг 7.11) и обеспечение ссылочной целостности (см. листинги 7.12 и 7.13). Хранимая процедура — это программа, которая хранится в базе данных в ском- пилированном виде. В Oracle хранимые процедуры можно писать на PL/SQL и Java. В SQL Server хранимые процедуры можно писать на Т-SQL. Хранимые процедуры могут принимать входные параметры и возвращать результаты. В от- личие от триггеров, они принадлежат всей базе данных в целом: их может вызы- вать любой процесс, имеющий достаточные права доступа. Хранимые процедуры могут вызываться из программ на стандартных языках программирования, таких как Java или С#, и па сценарных языках, например. JavaScript и VBScript. Их также можно вызывать в интерактивном режиме из командной оболочки СУБД — например, SQL*Plus в Oracle или Query Analyzer в SQL Server. Преимущества, свойственные хранимым процедурам, перечислены во врезке «Преимущества хранимых процедур». Пример хранимой процедуры приведен в листинге 7.14. SQL можно также встраивать в прикладные программы. Иногда для напол нения данными внешнего представления необходимо использовать несколько SQL-операторов. Прикладная программа передает операторы на выполнен СУБД и затем отображает результаты в полях формы. Кроме того, приклад программа должна обрабатывать и координировать действия пользователя работе с формой — например, наполнение раскрывающегося списка и внес необходимых изменений во внешние ключи для создания связей. j. Конкретные аспекты встраивания SQL-кода в прикладные программы . # сят от используемых языка программирования и технологии маиппулпроы данными. По завершении этого курса вы должны будете представлять с^т^еТе. использовать SQL в любом языке программирования, с которым Ра
Вопросы группы I 347 Вопросы группы I Для модели данных на рис. 7 1 объясните, почему следует моделировать сущности WORK и TRANSACTION как идентификационно-зависимые. 2 . Почему минимальное кардинальное число связи между сущностями ARTIST и WORK со стороны последней не равно 1? 3 . Почему идентификатором сущности WORK является группа (Title, Сору)? 4 . Обоснуйте решение, в соответствии с которым связь между сущностями CUSTOMER и TRANSACTION была сделана необязательной в обоих направле- ниях. 5 . Перечистите три возможные промежуточные сущности для связи вида N:M между сущностями CUSTOMER и ARTIST. Объясните, почему их следует (или не следует) включить в модель базы данных. 6 . Объясните, чем плоха реляционная схема на рис. 7.1, б. 7 . В модели данных с суррогатными ключами на рис. 7.2, а сущности WORK и TRANSACTION из идентификационно-зависимых превратились в сильные. Почему это было сделано? 8 . Что означает выражение IDENTITY (4000, 5)? 9 . Перечистите и обоснуйте процедуры обеспечения ссылочной целостности с родительской стороны связей для реляционной схемы на рис. 7.2, б. 10 Опишите потенциальную проблему, имеющую место при удалении строки из таблицы WORK или TRANSACTION. 11 Перечислите и обоснуйте процедуры обеспечения ссылочной целостности с дочерней стороны связей для реляционной схемы на рис. 7.2, б. 12 Опишите необычные характеристики столбцов BirthDate и Deceased D.ate со- гласно определению базы данных в листинге 7.1. 13 Приведите пример ограничения CHECK, задающего диапазон допустимых значений, отличный от приведенного в тексте. 14 Приведите пример ограничения CHECK, задающего список допустимых зна- чений, отличный от приведенного в тексте. 15 Приведите пример шраничеипя CHECK, использующего значения одного или двух столбцов, отличный 01 приведенного в тексте. 16 Напишите ограничение CHECK, тающее следующий формат значений столб- ца КодДетали пять десятичных цифр, верная из которых равна 5. 6 или 7, а последняя не равна 0 17 Прицедите пример ограничения CHECK, использующего вложенный запрос, отличный от приведенною в тексте. 1» Чего ис допуска! г стандар» SQL 92 в ограничениях CHECK? 1 • Обымните в общих словах, что такое SQL представление. 20 Какое ограничение имеет место и oi ношении операторов SELECT, исполь зуемм* для определения представлении
4 Глава 7. Использование SQL в приложениях 21. 22. Напишите SQI -оператор, определяющий значения столбца CUSTOMER.State. пред» тление, которое, -,.и,в1п Напишите SQL-оператор, определяющий представление, которое . < уникальные значения столбца CUSTOMER.State. 23. Напишите SQL-оператор, определяющий представление, которое содержат столбцы Name, City и State таблицы CUSTOMER. 24. Напишите SQL-оператор, определяющий представление, которое содерж значения столбцов Name, City и State таблицы CUSTOMER для клиентов, про- живающих в штате Калифорния. 25. Напишите SQL-оператор, определяющий представление, которое содержит столбец CUSTOMER.Name и вычисляемый столбец Location, объединяющий столбцы CUSTOMER.City и CUSTOMER.State в формате 'Chicago, IL’. 26. Ответьте на вопрос 25, но теперь пусть представление содержит данные только о клиентах, проживающих в штате Калифорния. 27. Напишите SQL-оператор, определяющий представление, которое содержит столбцы ARTIST.Name, WORK.Title и WORK.Description. 28. Напишите SQL-оператор, определяющий представление, которое содержит значения столбцов CUSTOMER.Name, WORK.Title и ARTIST.Name для всех поку- пок, сделанных клиентами. 29. Напишите SQL-оператор, определяющий представление, которое вычис- ляет чистую выручку (разницу между продажной и запрашиваемой цена- ми) для всех покупок, сделанных клиентами. 30. Напишите SQL-оператор, определяющий представление, которое вычис- ляет совокупную чистую выручку (сумму чистой выручки по всем покуп- кам) для каждого клиента. 31. Напишите SQL-оператор, определяющий представление, которое вычис- ляет совокупную чистую выручку для каждой комбинации клиента и ху- дожника. . 32. Опишите, как представления используются для формирования уровня аб- стракции между прикладными программами и таблицами базы данных. Почему это может быть важно? 33. Объясните, как представления могут повысить безопасность данных. 34. Объясните, как представления обеспечивают дополнительную функино нальность триггеров. 35. Приведите пример представления, которое явно является обновляемым- 36. Приведите пример представления, которое явно является необновляемым- 37. Приведите общие соображения, позволяющие судить о том, является представление обновляемым. 38. Если в редставлении отсутствуют обязательные элементы, какое де1 по отношению к представлению явно недопустимо?
Вопросы группы II 349 39. Объясните разницу между SQL-представлением и внешним представле- нием, как оно описано в главе 2. В каких случаях эти понятия совпадают? В каких различаются? 40. Объясните различие в парадигмах между SQL и языками программирования. 41. Как решается проблема несоответствия, описанная вами в ответе на во- прос 40? 42. Дайте определение триггера. 43. Что такое PL/SQL и T-SQL? 44. Какова связь между триггером и таблицей или представлением? 45. Перечислите девять возможных типов триггеров. 46. Объясните в общих чертах, как СУБД предоставляет триггерам доступ к старым и новым значениям. 47. Опишите четыре варианта применения триггеров. 48. Объясните в общих чертах, как использовать триггер для удаления строки из таблицы WORK, имея процедуры обеспечения ссылочной целостности, описанные для базы данных View Ridge. 49. Что такое хранимая процедура? Чем она отличается от триггера? 50. Опишите способы вызова хранимой процедуры. 51. Перечислите ключевые преимущества хранимых процедур. 52. Объясните в общих чертах, что должна сделать прикладная программа для материализации формы на рис. 7.3. 53. Может ли форма на рис. 7.3 быть выражена одиночным представлением? Обоснуйте свой ответ. Вопросы группы II Для ответа на следующие вопросы используйте модель данных на рис. 7.5 и реля- ционную схему на рис. 7.6. 54. Измените реляционную схему на рис. 7.6, чтобы она использовала сурро- гатные ключи. Является ли эта схема улучшением по сравнению с рис. 7.5? Обоснуйте свой ответ. 55. Используя реляционную схему на рис. 7.6 и имея в виду кардинальности связей в модели данных, объясните ограничение на удаление из таблицы СОТРУДНИК в связи с таблицей НАЗНАЧЕНИЕ. Что в данном случае означает ограничение? Аналогичным образом, что означают ограничения на вставку и обновление строк в таблице НАЗНАЧЕНИЕ в связи с таблицей СОТРУДНИК? 56. Используя реляционную схему на рис. 7.6 и имея в виду кардинальности связей в модели данных, объясните ограничение на вставку строк в таблицы КОМПЬЮТЕР в связи с таблицей! НАЗНАЧЕНИЕ. Что в данном случае означает ограничение? Аналогичным образом, что означают ограничения на вставку и обновление строк в таблице НАЗНАЧЕНИЕ в связи с таблицей КОМПЬЮТЕР?
350 Глава7.Использование SQL в приложениях СОТРУДНИК КОМПЬЮТЕР Рис. 7.5. Модель данных СОТРУДНИК КОМПЬЮТЕР Рис. 7.6. Реляционная схема 57’ пые иГ"е С7Тл °"ераТОрОВ CREATE TABLE- издающих таблицы, нзображен- тр ™ к Добавьте °фаничения CHECK, указывающие, что Производи- огпят °'1ЖеН ыть одпим 113 набора (Dell, IBM, Compaq). Также добавьте меж-nv ус™нанд,1Вающие> что ТактоваяЧастота должна находиться между и.о н 2.5 ГГц. моп ЛНПТе да,,ными созданные таблицы. У вас должно быть по меньшей лоГ СеТ сотруднико1!> ТРИ компьютера и семь назначений. Обязательно нииЖе1,«)Ь1ТЬ ми1,имум одип компьютер фирмы IBM, минимум три сотруд- а в ухгалтерии и минимум два назначения, где в поле КемНазначен стоит «Иванов». Создайте представление Сотрудник_ПР, включающее столбцы СОТРУДНИК.Имя и СОТРУДНИК.Отдел. Покажите, как с помощью этого представления вывес- ти список сотрудников, отсортированный по именам. Приведите результа 59. ты для ваших данных. 60. Создайте представление под названием СотрудникБухгалтерии, нспольз) ющее представление из вашего ответа на вопрос 59 для отображения епи ска сотрудников бухгалтерии. Приведите результаты для ваших дапвы*-
Вопросы к проекту FiredUp 351 61. Создайте представление таблицы КОМПЬЮТЕР под названием Компьютеры, содержащее столбцы СерийныйНомер, Производитель и Модель в виде одного атрибута под названием ТипКомпьютера. Поместите двоеточие и пробел по- сле названия производителя, чтобы результат выглядел так: «Dell: Ноут- бук 6200». Приведите результаты для ваших данных. 62. Создайте представление под названием ПроизводителиКомпьютеров, отобра- жающее производителей и среднюю тактовую частоту для всех компьюте- ров. Приведите результаты для ваших данных. 63. Создайте представление под названием ИспользованиеКомпьютера, содер- жащее данные из таблиц КОМПЬЮТЕР и НАЗНАЧЕНИЕ. Приведите результаты для ваших данных. 64. С помощью представления, созданного вами в ответе на вопрос 63, создай- те представление ИспользованиеКомпьютераСотрудником, отображающее все данные из таблиц КОМПЬЮТЕР и НАЗНАЧЕНИЕ, сгруппированные по значе- нию столбца КемНазначен. Приведите результаты для ваших данных. 65. Используя созданное вами представление Компьютеры, выведите серийные номера и типы всех компьютеров, а также имена их пользователей. Приве- дите результаты для ваших данных. 66. Объясните, как вы использовали бы триггер для реализации ограничения, согласно которому сотрудник может иметь максимум один компьютер. Какой тип триггера вы использовали бы? Опишите логику работы такого триггера. 67. Объясните потенциальную проблему, которая может возникнуть при уда- лении строки из таблицы КОМПЬЮТЕР. Как можно преодолеть эту про- блему с помощью триггера? Какой таблице принадлежал бы этот триггер, к какому типу он принадлежал бы, какова была бы логика его работы (в общих чертах)? 68. Допустим, вы хотите использовать хранимую процедуру для вставки но- вой строки в таблицу КОМПЬЮТЕР. Приведите минимальный список вход- ных параметров, которые должна иметь эта процедура. Опишите (в общих чертах) логику работы такого триггера. Вопросы к проекту FiredUp Предположим, что фирма FiredUp создала базу данных со следующими таблицами: КЛИЕНТ (КлиентСК, Имя, Телефон, АдресЭлПочты) ГОРЕЛКА (СерийныйНомер, Тип, Версия, ДатаВыпуска) РЕГИСТРАЦИЯ (КлиентСК, Серийнь/йНомеп, Дата) РЕМОНТ ГОРЕЛКИ (НомеиСчеи. СерийныйНомер, Дата, Описание, Стоимость, Всего- Уплачено, КлиентСК) 1 Создайте представление ОбщиеСведенияОРемонте, содержащее только столб- цы НомерСчета, Стоимость и ВсегоУплачено. 2 Напишите SQL от разор, отображающий данные из представления Общие- Св'ДенияОРемонте, отсортированные по шачспию столбца Стоимость.
352 Г лава 7. Использование SQL в приложениях 3. Создайте представление ЗадолженностьПоРемонту, отображающее столбец НомерСчета, а также разницу между значениями столбцов Стоимость и Все гоУплачено в виде столбца ВсегоКУплате. 4. Напишите SQL-оператор, отображающий данные из представления Задол- женностьПоРемонту, отсортированные по значению столбца ВсегоКУплате 5. Создайте представление РемонтДляКлиента, содержащее столбцы КЛИЕНТ.Имя РЕМОНТ_ГОРЕЛКИ.СерийныйНомер, Дата, Описание и ВсегоКУплате, где Всегс КУплате — это разница между значениями столбцов Стоимость и ВсегоУплачено 6. Создайте представление БалансКлиента, использующее представление Ремонт- ДляКлиента и показывающее столбец КЛИЕНТ.Имя и сумму значений столбца ВсегоКУплате в виде столбца КУплатеПоУчетнойЗаписи. 7. Пускать у фирмы FiredUp имеется правило, согласно которому запись о клиенте может быть удалена только в том случае, если для всех ремонтов, выполненных для данного клиента, значение столбца Стоимость равняется значению столбца ВсегоУплачено. Объясните, как вы реализовали бы это правило с помощью триггера. Какой тип триггера вы использовали бы? Для какой таблицы вы его определили бы? Приведите SQL-операторы, которые вы использовали бы, но оставшуюся часть триггера напишите в ви- де обобщенного кода, как в листинге 7.10. 8. Предположим, что каждой строке в таблице КЛИЕНТ должна соответство- вать по меньшей мере одна строка в таблице РЕГИСТРАЦИЯ. Объясните, как вы реализовали бы это правило с помощью триггера. Какой тип триггера вы использовали бы? Для какой таблицы вы его определили бы? На какие события реагировал бы этот триггер? Приведите SQL-операторы, которые вы использовали бы, но оставшуюся часть триггера напишите в виде обоо- щенного кода, как в листинге 7.10. Вопросы к проекту Twigs Tree Предположим, что фирма Twigs Tree создала базу данных со следующими табли нами: ВЛАДЕЛЕЦ (ИмяВладельца, Телефон, Дом, Улица, Город, Штат, Индекс) РАБОТА (ДатаВыпол нения, ИмяВладельца, Описание, Стоимость, Уплачено, Дата ы платы) п Ла- ДОСТАВКА_СТРУЖКИ (ИмяКлиента, ДатаДоставки, Объем, Стоимость, Уплачен , та Вы платы) 1. Создайте представление ОбщиеСведенияОКлиенте, содержащее только сто. цы ИмяВладельца, Телефон и Город. 2. Напишите SQL-оператор, отображающий данные из представления СведенияОКлиенте, отсортированные по значению столбца ИмяВладе 3. Создайте представление ВыручкаОтДоставкиСтружки, содержащее ст° ДОСТАВКА-СТРУЖКИ.ИмяКлиента, и ДОСТАВКА_СТРУЖКИ.ДатаДоставки, а
Вопросы к проекту Twigs Tree 353 разницу между значениями столбцов Стоимость и Уплачено в виде столбца ВсегоКУплате. 4. Напишите SQL-оператор, отображающий все данные из представления Вы- ручкаОтДоставкиСтружки, отсортированные по значению столбца ВсегоКУплате. 5 Создайте представление РаботыДляКлиента, содержащее столбцы ВЛАДЕЛЕЦ. ИмяВладельца, РАБОТА.ДатаВыполнения, РАБОТА.Описание и ВсегоКУплате, где ВсегоКУплате — это разница между значениями столбцов Стоимость и Упла- чено. 6. Создайте представление БалансКлиента, использующее представление Ра- ботыДляКлиента и показывающее столбец ИмяВладельца и сумму значений столбца ВсегоКУплате в виде столбца КУплатеПоУчетнойЗаписи. 7. Пускать у фирмы Twigs Tree имеется правило, согласно которому запись о клиенте может быть удалена только в том случае, если у него нет задол- женности по выполненным работам, то есть для всех связанных с ним строк таблиц РАБОТА и ДОСТАВКА_СТРУЖКИ значение столбца Стоимость рав- няется значению столбца Уплачено. Объясните, как вы реализовали бы это правило с помощью триггера. Какой тип триггера вы использовали бы? Для какой таблицы вы его определили бы? Приведите SQL-операторы, которые вы использовали бы, но оставшуюся часть триггера напишите в ви- де обобщенного кода, как в листинге 7.10. 8. Предположим, что каждой строке в таблице ВЛАДЕЛЕЦ должна соответ- ствовать по меньшей мере одна строка в таблицах РАБОТА или ДОСТАВКА_ СТРУЖКИ. Объясните, как вы реализовали бы это правило с помощью триг- гера. Сколько триггеров вам потребовалось бы? Для каких таблиц? На ка- кие события? Приведите SQL-операторы, которые вы использовали бы, но оставшуюся часть триггера напишите в виде обобщенного кода, как в листинге 7.10.
Глава 8 Перепроектирование баз данных Эта глава обращается к важной теме — перепроектированию баз данных. До сих пор наше обсуждение шло так, как если бы все базы данных создавались с нуля. На самом же деле в большинстве случаев работа по проектированию базы данных включает в себя перепроектирование уже существующей базы. Сначала мы обсу- дим, зачем нужно перепроектировать базы данных, а затем познакомимся с двумя новыми конструкциями SQL: коррелированными подзапросами и условием EXISTS Эти конструкции играют важную роль при анализе данных в ходе подготовки к перепроектированию. Кроме того, их можно использовать для составления сложных запросов, так что они имеют и самостоятельное значение. В заключение мы рассмотрим ряд задач, которые приходится решать при перепроектировании баз данных. Зачем перепроектировать базы данных? У вас, возможно, возникнет вопрос: а зачем вообще может понадобиться перепро- ектпровагь базу данных? Если база изначально была построена верно, для чего ее переделывать? На это вопрос есть два ответа. Во-первых, не так-то просто с само- го начала правильно спроектировать базу данных. Даже если мы сможем собрать все требования ^пользователей, перед нами будут стоять нелегкие задачи построе- ния адекватной модели данных и преобразования этой модели в корректную структуру базы данных. В случае больших баз данных эти задачи приобретают поистине грандиозный масштаб и могут потребовать разработки в несколько эта- пов. На протяжении этих этапов может возникнуть необходимость в переработке некоторых аспектов базы данных. Кроме того, неизбежно появляются ошибки, которые необходимо исправлять. Второй ответ на этот вопрос представляет собой более сильный и важный ар гумент. Поразмыслите немного над сутью взаимоотношении между информапи онными системами и организациями, которые их используют. Первым побужде нием будет сказать, что они влияют друг па друга, то есть информационные системы влияют на организации, а те, в свою очередь, влияют на ннформаш101 иые системы.
Другие SQL-операторы 355 Однако в действительности их взаимоотношения являются намного более тесными. Информационные системы и организации не просто влияют друг на друга, а буквально создают друг друга. Когда в организации внедряется новая нф< рмационная система, у пользователей возникают новые шаблоны поведе- ния. По мере освоения новой системы пользователи предлагают внести в нее те ИЛИ иные усовершенствования, с тем чтобы лучше приспособить ее к этим новым шаблонам. Модификация системы в соответствии с предложениями пользова- телей опять приводит к возникновению новых шаблонов поведения, вследствие чего пользователи предлагают дальнейшие модификации, и т. д. Получается не- скончаемый цикл. Этот кругообразный процесс означает, что изменения, вносимые в инфор- мационную систему, являются не досадным следствием неудачной реализации, а скорее естественным результатом эксплуатации информационных систем. По- этому потребность в модификации информационных систем никогда не исчеза- ет; она не может и не должна быть устранена путем более четкого определения требований, более качественного проектирования, более удачной реализации или чего бы то ни было еще. Напротив, изменение представляет собой неотъем- лемый атрибут использования информационных систем. Следовательно, его не- обходимо планировать. В контексте построения баз данных это означает, что нам нужно знать, как осуществлять перепроектирование баз данных. Другие SQL-операторы Перепроектирование базы данных не представляет больших проблем, если база не содержит данных. Серьезные трудности возникают тогда, когда требуется из- менить базу данных, в которой имеется информация, причем сделать это с мини- мальными последствиями для существующих данных. Если сообщить пользова- телям, что теперь система работает так, как им нужно, но, к сожалению, в ходе модификации все их данные были потеряны, — это вряд ли будет приемлемым ДЛЯ кого бы то ни было. Зачастую прежде чем вносить изменения, необходимо бывает знать, спра- ведливы ли определенные предположения относи гельно данных. Например, из Требований пользователей нам может быть известно, что атрибут Отдел функ- ционально определяет атрибут БюджетныйКод, но мы можем не знать, во всех ли данных на функциональная зависимость представлен т корректно. Вспомните из главы 4, что если атрибут Отдел функционально определяет ат- рибут БюджетныйКод, каждому значению атрибута Отдел должно соответствовать одно и то же определенное значение атрибута БюджетныйКод Если, папр гмер. в од- ной строке бухгалтерия имеет бюджетный код ООО.тООэ, то и во вих остальных строках, где фигурирует бухгал терия, бюджетный код также должен быть равен «ЖЙООб Диалоги шым образом, если в одной строке финансовый отдел имеет '-мтжетимй ход (ИЮ ИЮ7 то и во всех остальных строках, где фигурирует фннансо иый отдел. бюджетный код должен иметь то же самое значение. В табл. 8.1 прнведе мы дмштде, царушахяцти ',о предположение В последней строке для бухгалтерии
356 Глава 8- Перепроектирование баз данных указан иной бюджетный код, чем в других строках: в нем имеется на один и больше. Скорее всего, пользователь ошибся при вводе значения столбца Бю ныйКод. Такие ошибки являются типичными Таблица 8.1. Таблица, которая нарушает подразумеваемое ограничение НомерСотрудника Имя Отдел БюджетныйКод 100 Джонс Бухгалтерия 0005005 ~ 200 Грин Финансы 0005007 300 Абернати Финансы 0005007 400 Паркс Бухгалтерия 0005005 500 Каваи Производство 0005009 600 Лопес Финансы 0005007 700 Грин Бухгалтерия 00050005 Теперь, прежде чем мы приступим к изменению базы данных, нам, возможно, потребуется найти все такие нарушения и исправить их. В такой маленькой таб- лице, как табл. 8.1, достаточно просто внимательно посмотреть на данные, но что, если таблица СОТРУДНИК имеет 4000 строк? Особенно полезными в этой связи являются две конструкции SQL: коррелированные подзапросы и сходное по на- значению условие EXISTS/NOT EXISTS. Рассмотрим эти конструкции. Коррелированные подзапросы Коррелированный подзапрос (correlated subquery) по виду весьма похож на подза- просы, которые мы обсуждали в главе 6, но в действительности существенно от- личается от них по своим функциям. Чтобы уяснить себе эту разницу, рассмот- рим следующий запрос, напоминающий примеры из главы 6: SELECT A.Name FROM ARTIST А WHERE A.ArtiStID IN (SELECT W.ArtiStID FROM WORK W WHERE W.Title = ’Mystic Fabric'): Такие запросы СУБД может обрабатывать снизу вверх. Иными словами, она может сначала найти все строки таблицы WORK, где столбец Title имеет значение 'Mystic Fabric1, взять из этих строк значения ArtistlD и, используя эти значения, работать верхний запрос. Нет необходимости постоянно переходить от од запроса к другому. Поиск копий одного и того же произведения Теперь перейдем собственно к коррелированным запросам. Допустим, к * трудник галереи View Ridge предлагает сделать столбец Title таблицы W тернативным ключом. Если вы посмотрите на данные в табл. 7.2, то увиди имеется две копии работы 'Mystic Fabric’, поэтому столбец Title не може
Другие SQL-операторы 357 альтернативным ключом. Но если в таблице WORK тысяча или более строк, опре- делить это будет гораздо труднее. Для этого нам нужно запросить из таблицы WORK названия и номера копий произведений, существующих в нескольких эк- земплярах. Если бы нас попросили написать программу, выполняющую этот запрос, ло- гика ее работы была бы такой: берем значение столбца Title из первой строки таблицы WORK и перебираем все остальные строки таблицы. Если мы находим строку с таким же значением столбца Title, значит, данное произведение суще- ствует в галерее в нескольких экземплярах, и мы выводим название произведе- ния и номер копии. Затем мы берем значение столбца Title из второй строки таблицы WORK и ищем такое же значение во всех остальных строках, в случае совпадения выводя назва- ние произведения и номер копии, и т. д. Эта процедура повторяется до тех пор, пока таким образом не будут пройдены все строки таблицы WORK. Те же самые действия выполнит коррелированный подзапрос следующего пиля- SELECT Wl.Title. Wl.Copy FROM WORK Wl WHERE Wl.Title IN (SELECT W2.Title FROM WORK W2 WHERE Wl.Title = W2. Title AND Wl.WorkID <> W2.WorkID) Результат этого запроса для данных, представленных в табл. 7.2, будет таким: Mystic Fabric 99/135 Mystic Fabric 105/135 Этот запрос обманчиво похож на обыкновенный подзапрос. Тем не менее, к удивлению многих студентов, он коренным образом отличается от последнего. Сходство их лишь поверхностное. Прежде чем мы объясним, почему это так, обратите внимание на то, как запи- сан коррелированный подзапрос. Как во внешнем, так и во внутреннем операто- ре SELECT используется таблица WORK. Во внешнем операторе ей присвоен псев- доним W1, а во внутреннем — W2. По сути, это равносильно созданию двух копий таблицы WORK, одна из кото- рых называется W1, а другая W2. Таким образом, в последних двух строчках кор- релированного подзапроса данные из одной копии таблицы WORK под названием W1 сравниваются с данными из другой копии таблицы WORK под названием W2. Теперь посмотрим, что отличает данный подзапрос. В отличие от обычного подзапроса, здесь СУБД не может отдельно выполнить внутренний оператор SELECT, получить набор значений столбца Title и использовать его в качестве иходных данных для внешнею оператора SELECT. Причина этого содержится в двух последних строчках запроса: WHERE wi. Title - W2 Title Wl WorkID о W2 WorkID);
358 Глава 8. Перепроектирование баз данных В этих выражениях Wl.Title (из внешнего оператора SELECT) сравнивает с W2.Title (из внутреннего оператора SELECT). То же самое верно и для Wl Woridfi и W2.WorkID. Из-за этого СУБД не может обрабатывать внутренний запро не висимо от внешнего. Данный оператор СУБД должна обрабатывать как подзапрос, который жен в основной запрос. Логика работы такова: берем первую строку W1 Исполь- зуя эту строку, обрабатываем внутренний запрос. Для этого берем первую строку W2 и сравниваем Wl.Title с W2.Title, а также Wl.WorkID с W2.WorkID. Если названия одинаковы, а идентификаторы произведений не совпадают, возвращаем вне- шнему запросу значение W2.Title. Эта процедура выполняется для каждой строки таблицы W2. Перебрав все строки таблицы W2, переходим к следующей строке в таблице W1 и сравниваем ее со всеми строками таблицы W2. Повторяем эту процедуру до тех пор, пока не сравним все строки таблицы W1 со всеми строками таблицы W2. Если этот алгоритм вам непонятен, нарисуйте на бумаге две копии таблицы WORK, используя данные из табл. 7.2. Обозначьте одну из них как W1, а другую как W2, а затем выполните описанную выше процедуру. Тогда вы сможете убе- диться, что коррелированные подзапросы всегда требуют циклической обработки. Между прочим, не следует попадаться в следующую распространенную ло- вушку: SELECT Wl Title. Wl Copy FROM WORK Wl WHERE Wl.WorkID IN (SELECT W2.Work ID FROM WORK W2 WHERE Wl.Title = W2.Title AND Wl WorkID <> W2.WorkID); На первый взгляд, логика верна, но это лишь иллюзия. Этот запрос не воз- вратит ни единой строки, какие бы данные ни содержались в таблице Прежде чем читать дальше, попробуйте самостоятельно сообразить, почему это так. Внутренний запрос действительно найдет все строки, содержащие произведе- ния с одинаковыми названиями, ио различными идентификаторами, и для каж- дой такой строки возвратит значение W2.WorkID. Но затем W2.WorkID будет срав- ниваться с Wl.WorkID, а эти два значения всегда будут разными из-за условия Wl.WorkID <> W2.WorkID. Запрос не возвратит ни одной строки, поскольку в кон струкции IN используются два неравных значения столбца WorkID вместо двух равных значений столбца Title. Использование коррелированных подзапросов для проверки функциональных зависимостей Коррелированные подзапросы можно удачно использовать при перепроекпй^ вании баз данных. Как уже говорилось, одним из возможных применен»! * них является проверка функциональных зависимостей. Предположим, у на^т)1М ется таблица СОТРУДНИК с данными, которые приведены в табл. 8.1, и мы х
Другие SQL-операторы 359 знать, удовлетворяют ли данные функциональной зависимости Отдел-»Бюджет- НЫ1 Код. Если да, то всякий раз, когда в таблице встречается определенное зна- чение столбца Отдел, ему будет соответствовать одно и то же значение столбца БюджетныйКод. Следующий коррелированный подзапрос найдет все строки, нарушающие это предположение: SELECT Cl.Отдел Cl БюджетныйКод FROM СОТРУДНИК Cl WHERE Cl.Отдел IN (SELECT С2.0тдел FROM СОТРУДНИК C2 WHERE Cl.Отдел = С2.0тдел AND Cl.БюджетныйКод <> C2.БюджетныйКод); Результат этого запроса для данных, представленных в табл. 8.1, будет таким: Бухгалтерия 0005005 Бухгалтерия 0005005 Бухгалтерия 00050005 Такая распечатка поможет быстро найти строки, нарушающие функциональ- ную зависимость, и исправить эти нарушения. Условия EXISTS и NOT EXISTS Условия EXISTS и NOT EXISTS представляют собой еще одну форму коррелирован- ного подзапроса. Предыдущий запрос можно переписать с использованием усло- вия WHERE следующим образом: SELECT Cl.Отдел, Cl БюджетныйКод FROM СОТРУДНИК Cl WHERE EXISTS (SELECT * FROM СОТРУДНИК C2 WHERE Cl.Отдел = С2.0тдел ANO Cl, БюджетныйКод <> C2.БюджетныйКод); Поскольку условие EXISTS является разновидностью коррелированного под- запроса, обработка операторов SELECT носит циклический характер. Сначала внутреннему запросу передается первая строка таблицы С1. Если виутреннш загцхю находит в таблице С2 строки, в которых название отдела совпадает, а бюд- жетный код различается, тогда условие EXISTS испито и выводятся столбцы Отдел и БюджетныйКод для цервой строки Затем внутреннему запросу переда- ется втирая строка таблицы С1, обрабатывается оператор SELECT и определя- ется истинность условия EXISTS. Если условие истинно, выводятся столбцы Отдел и БюджетныйКод для второй строки. Этот процесс повторяется для всех строк в С1
360 Глава 8. Перепроектирование баз данных Ключевое слово EXISTS будет истинным, если хотя бы одна строка в подза- просе удовлетворяет заданному условию. Ключевое слово NOT EXISTS будет ис- тинным, если ни одна строка в подзапросе не удовлетворяет заданному условию Следовательно, используя ключевое слово NOT EXISTS дважды, можно найти строки, удовлетворяющие заданному условию по отношению ко всем строкам таблицы. Предположим, например, что сотрудники галереи View Ridge хотят знать, произведениями каких художников интересуются все без исключения клиенты. Чтобы это определить, можно действовать следующим образом. Сначала соста- вим список клиентов, интересующихся определенным художником. Затем возь- мем дополнение полученного множества, то есть список клиентов, не интересу- ющихся этим художником. Если этот список пуст, значит, данным художником интересуются все клиенты. Прежде чем мы продолжим, следует отметить, что данный конкретный шаблон использования условия NOT EXISTS в том или ином его обличье является весьма популярным среди профессионалов SQL. Его часто используют в качестве теста на знание SQL при приеме на работу, а кроме того, с его помощью можно эффек- тивно оценить желательность определенных вариантов переконструирования базы данных, как вы увидите в последнем разделе этой главы. Поэтому, хотя по- нимание этого примера требует значительных усилий, он того стоит. Описанную только что стратегию реализует следующий SQL-оператор: SELECT A.Name FROM ARTIST А WHERE NOT EXISTS (SELECT C.CustomerlD FROM CUSTOMER C WHERE NOT EXISTS (SELECT CI.CustomerlD FROM CUSTOMER_ARTIST_INT CI WHERE C.CustomerlD = CI.CustomerlD AND A.ArtistID = CI.ArtistID)); Последний оператор SELECT находит всех клиентов, интересующихся конкрет- ным художником. Имейте в виду, что данный оператор SELECT представляет со- бой коррелированный подзапрос: он вложен в запрос из таблицы CUSTOMER, кото- рый, в свою очередь, вложен в запрос из таблицы ARTIST. Столбец C.CustomerlD берется из второго запроса, а столбец A.ArtistlD — из первого. Условие NOT EXISTS в шестой строке запроса отбирает клиентов, не интере- сующихся данным художником. Если указанный художник интересует всех кли- ентов, то второй оператор SELECT не возвратит ни одной строки, вследствие чего условие NOT EXISTS в третьей строке запроса окажется истинным, и имя этого ху- дожника будет возвращено первым запросом, чего мы и добивались. Посмотрим, что произойдет в случае, если художник не удовлетворяет наше- му критерию отбора. Допустим, что художником Miro интересуются все клиен- ты, кроме Tiffany Twilight (это неверно для данных, представленных в табл. 7.5. но сейчас предположим, что это так). Теперь, рассматривая строку этого худо*'
Анализ существующей базы данных 361 HJHCX нижний оператор SELECT возвратит имена всех клиентов, кроме Tiffany Т» litghfc Благодаря условию NOT EXISTS в шестой строке запроса второй оператор SELKT возвратит столбец CustomerlD клиента Tiffany Twilight (поскольку только ее строка вошла в результат выполнения нижнего оператора SELECT). Посколь- ку средний оператор SELECT возвратил непустое множество строк, условие NOT EXISTS верхнем операторе SELECT окажется ложным, и имя Miro не будет вклю- чено в результаты запроса. Это правильно, поскольку существует клиент, кото- рый не интересуется художником Miro. Си* ® ркнем. н пожалейте времени на изучение этого шаблона. Он ис- ключительно важен, и если вы будете работать с базами данных, вы определенно буяете сталкиваться с ним в той или иной форме. Анализ существующей базы данных Прежде чем мы приступим к обсуждению аспектов перепроектирования баз лян- ных. поразмыслите немного над тем, что значит эта задача для реальной компа- нм которая в своей деятельности зависит от базы данных. Представьте, что вы работаете на компанию Amazon.com и вам было поручено важное задание в рам- ках проекта по перепроектированию базы данных — например, изменение пер- вичного ключа таблицы поставщиков. Прежде всего, у вас может возникнуть вопрос: а зачем вообще это делать? Воомааюю. на заре существования компании Amazon.com, когда она торговала только книгами, в качестве первичных ключей использовались названия компаний. Одмш> до мере расширения ассортимента продаваемых товаров одних названии яомцаиий стало уже недостаточно. Появилось слишком много дубликатов, и ком- амия решила перейти к использованию суррогатного ключа ИдПоставщика. Итак, что же означает изменение первичного ключа, кроме очевидной необхо- димости записи новых данных в правильные строки? Понятно, что если старым Вфмичямй ключ использовался в качестве внешнего ключа, то внешние ключи пкк придется менять. Таким образом, нам необходимо знать все связи, в которых учвютвом старый первичный ключ Но как быть с представлениями? Исполь- «у»т' -л хи старый первичный ключ в каких-либо подставлениях? Если да, то со- представления необходимо будет модифицировать. Но и это еще «мы» есть таг/»< триггеры и хранимые процедуры Возможно, какие-то из них *т мям,, старый первичный ключ Наконец, не следует забыты ц ри Чме программы фуимщоиироваиие которых может нарушиться при удалении А Геперь чтобы получился настоящий кошмар, предстаньте, что вы уже час- ♦теми» ко фщяршали баз* данных и что то у вас работает не так наир Р — мт,- то и>ь неожиданные данные, и при иопытк. добавить новый иервич «ыа «квет СУБД моим» ошибку Amazon com нс может позволить себе поместить •• иптю прминр < мот» еайт» роибщение «Извините, мы шиытъшасм щюблсмы мм"** ЪЙЛИГ ММО'И'Г’1»
362 Глава 8 Пер&проик1ири«мниеба > даннь*> Этот сценарий ставит не|н*д нами мнижеаии проблем, большая чаль и рых относится к системному анализу н ироскi приватно 11о с точки зрения пп. ектпрования баз данных становятся ясны три главных принципа, «семь раз отмерь — одни оцюжь» Прежде чем пытаться вносить кикие-тр «гщ нения в структуру базы данных, необходимо яс 1ю представлять себе ее текущую структуру и содержимое, а также все зависимости Во вторых, перед тем какам* поднять структурную модификацию рабочей базы данных, необходимо прме* рить планируемые изменения па реалистичной по размеру тестовой базе линии» содержимое которой моделирует все важные ситуации, могущие встретиться на практике. Наконец, если это возможно, до внесения изменений следует амать полную резервную копню рабочей базы данных. Если все пойдет не так, как за- думано, из этой копии можно будет восстановить базу данных, пока идет j стра- дание проблем. Каждый из этих принципов мы подробно рассмотрим ниже. Реконструкция Реконструкцией (reverse engineering) называется процесс восстановления модели данных по известной схеме базы данных. Полученная таким образом модель дан- ных не является в действительности ни концептуальной, ни внутренней схемой. Она не является концептуальной схемой, потому что каждой таблице в ней соот- ветствует отдельная сущность: например, таблицы пересечения, не содержащие неключевых данных, будут, тем не менее, представлены в виде сущностей. Нель- зя ее назвать и внутренней схемой, поскольку она не содержит всей информации, которую должна включать в себя внутренняя схема (например, процедуры обес- печения ссылочной целостности). Это скорее «вещь в себе» — диаграмма таб- лиц и связей между ними, выряженная в одежды диаграммы «сущность—связь». В этой книге мы будем называть такую модель реконструированной моделью дан- ных (reverse engineered data model). На рис. 8.1, а и б показана реконструированная модель данных, созданная про- граммой ERWin из версии базы данных View Ridge для SQL Server (см главу 7). На рис. 8.1, а показано то, что в терминах ERWin называется логической моделью (logical model). Если вы сравните это с логической моделью на рис. 7 3, а, вы увидите, что программа сумела воспроизвести ее очень близко к оригиналу. Про грамма корректно указала типы всех связей, а также определила, что мнннмаль ное кардинальное число связи между сущностями TRANSACTION и CUSTOMER с° стороны последней равно нулю. Есть только две проблемы. Во-первых, программа смоделировала таблицу пер^ сечения в виде отдельной сущности, каковой она в действительности не Я|С!Я<\ ся. Это типично для реконструированных моделей данных. Кроме того, 1,РОГ*М ма не сумела определить, что каждому произведению должна соответствовать меньшей мере одна транзакция. Кардинальное число связи между суШ'кК1^м WORK и TRANSACTION со стороны последней должно быть указано как Р- В ц^аде. однако, мы получили довольно адекватное представление модели данных реи View Ridge.
Анализ существующей базы данных 363 4 На рис. 8,1, б изображено то, что в терминах программы ERWin называется моделью (physical model). Эта модель оказывается весьма точной Свойства обязательности и необязательности, первичные ключи, альтернативный КЛЮЧ ARTIST.Name и все внешние ключи определены верно. Не указано только кардинальное число Р для таблицы TRANSACTION, а кроме того, неправильно опре- делены процедуры обеспечения ссылочной целостности. Это неудивительно, по- скольку такие вещи невозможно вывести из самой модели данных, и их должен задавать вручную разработчик при перепроектировании. Кроме таблиц и представлений, некоторые средства моделирования данных могут извлекать из базы данных ограничения, триггеры и хранимые процедуры. Эти конструкции не интерпретируются, по их текст включается в модель дан- ных; некоторые программы способны также распознавать в тексте ссылки на элементы данных. Перепроектирование ограничений, триггеров и хранимых процедур выходит за рамки нашего обсуждения. Однако вам следует пони- мать. что они тоже являются частью базы данных и, следовательно, подлежат модификации. Реконструированная модель данных представляет собой основу, с которой можно начинать перепроектирование базы данных. Мы будем использовать ее далее в этой главе. Графы зависимостей Прежде чем вносить изменения в структуру базы данных, жизненно важно опреде- лить, какие зависимости имеются между ее элементами. Рассмотрим, например, задачу изменения имени таблицы. Где используется имя этой таблицы? В каких триггерах, хранимых процедурах, связях? Из-за необходимости знать ответ ы на эти вопросы большинство проектов по перепроектированию баз данных начина- ется с построения графа зависимостей (dependency graph). Термин граф имеет корни в математической теории графов. Графы зависимо- стей не являются графическими отображениями, как, например, столбиковые Анаграммы Они состоят из узлов и дуг (или линий), соединяющих узлы. На рис 8.2, а изображен Граф зависимое ген, построенный программок Он показывает, что представления BasicCustornerData и BasicCustornerData. А завн сят от таблицы CUSTOMER. II.» рис. 8.2, б изображен аналогичный граф для таблиц ARTIST, WORK и TRANSACTION, предст.тнлення ArtistWorkNet и других представлении, *а нем основанных Рис 8.2, 6 представляет собой сии* одни хороший пример результатов рс- *«*€Трукции Он бли ЮК К оригиналу, НО не совсем верен. Как уже упомнна ЛОсь, такие результаты следует рассмагршть лишь как удобную отправлю Ючку На рис 8.2.6 проблем» состоит в том, чю ироцгамме не удилось^нтерщх ™ ии«. при помощи «порок, со Transaction Птмюму мяискмги ть этого представления от иблни ARTIST, WORK в TRANSA *г показан •«
ARTIST CUSTOMER ArtistID Customer! D Name Street City State ZipPostal Code Country AreaCode Phone Number Email WORK Name (AK1.1) Nationality Birthdate DeceasedDate WorkID TRANSACTION TransactionlD DateAcquired AcquisitionPrice PurchaseDate SalesPrice AskingPrice Title Description Copy CUSTOMER.ARTISTJNT
б Рис. 8.1. Реконструированная модель данных: а — логическая модель, б — физическая модель
366 Глава 8 Перепроектирование баз данные CUSTOMER о BasicCustomerData о BasicCustomerData WA а ARTIST ^ArtistID WORK • ^WorkID TRANSACTION ^TransacbonlD ArtistWorkNet о ArtistTitleNet о ArtistNet о WorkNet 6 Рис. 8.2. Фрагменты графа зависимостей: а — таблица CUSTOMER и два представления; б — примеры таблиц и представлений На рис. 8.3 изображен частичный граф зависимостей, построенный с исполь- зованием результатов реконструкции, но с ручной интерпретацией представле- ний и триггеров. Для простоты на этом графе не показаны представления табли- цы CUSTOMER, а также таблица CUSTOMER_ARTIST_INT и связанные с ней структуры. Кроме того, в граф не включены ограничения и хранимая процедура Add_Worlc Даже этот неполный граф дает представление о сложности зависимостей между элементами базы данных. Можно видеть, к примеру, что при внесении каких-ли- бо изменении в таблицу TRANSACTION следует быть весьма и весьма аккуратным. Необходимо оценить, как эти изменения отразятся на двух связях, трех тригге- рах и четырех представлениях. Опять-таки: семь раз отмерь — один отрежь! Резервное копирование и тестовые базы данных Из-за опасности нанесения серьезного вреда базе данных при перепроектировани необходимо перед внесением каких-либо изменений создать полную !х’зе!3ннЫе копию рабочей базы данных. Равным образом важно, чтобы все предлож
Анализ существующей базы данных 367 модификации были тщательно протестированы. Мало успешно выполнить струк- турные изменения: необходимо еще, чтобы все триггеры, хранимые процедуры и прикладные программы работали правильно с обновленной базой данных. Рис. 8.3. Пример графа зависимостей (фрагмент) Обычно в процессе перепроектирования используются по крайней мере три копии схемы базы данных. Одна представляет собой небольшую тестовую базу Данных, которую можно использовать для первоначальной проверки. Вторая — это большая тестовая база данных, возможно, даже полная копия рабочей базы данных. Она используется для вторичного тестирования. Наконец, есть еще рабо- чая база данных. Иногда используется несколько больших тестовых баз данных. Необходимо иметь способ, позволяющий восстановить все тестовые базы данных до исходного для процесса тестирования состояния. Это позволяет вы- полнять тест сколько угодно раз от одной и той же исходной точки. В зависимо- сти от возможностей СУБД, для восстановления базы данных после выполнения '•еста может использоваться резервное копирование пли какой-то другой способ. Очевидно, цто предприятия, имеющие базы данных очень большого размера, и»-' могут использовать в качестве кетовой базы данных копию рабочей базы. Ьмссто aioto необходимо создать тестовую базу данных меньшего размера, но содержимое пой базы должно моделирован. все важные характеристики данных, имеющихся в рабочей базе В противном случае не удастся создать реалистичное
368 Глава 8. Перепроектирование баз данных тестовое окружение. Пос i роение таких баз данных сами п<» 1 йе является труд нон и нетривиальной задачей. На самом деле разработка тестовых баз данниц и тестовых наборов несет в себе множество интересных кар1>ерных возможное Наконец, организации, имеющие большие балы данных, могут быть не в со- стоянии создать полную копию рабочей балы данных перед внесением структур, ных изменений. В этом случае база данных копируется по частям и изменения также вносятся по частям. Эта задача чрезвычайно сложна и требует огромных знаний и опыта. Кроме того, она требует нескольких недель или месяцев плани рования. Вы можете участвовать в таких изменениях в качестве младшего члена команды, но прежде чем пытаться самостоятельно осуществлять структурные модификации в базах данных такого размера, вам необходимо иметь многолет- ний опыт работы с базами данных. Даже и тогда сложность этой задачи поистине устрашающая. Изменение имен таблиц и свойств столбцов В этом разделе мы рассмотрим изменение имен таблиц и свойств столбцов. Для выполнения этих модификаций мы будем использовать только операторы стан- дарта SQL-92. Во многих СУБД предусмотрены дополнительные возможности для изменения структуры базы данных — например, в некоторых продуктах име- ются графические средства проектирования. Но эти возможности не стандарти- зированы, и вы не должны от них зависеть. Операторы, используемые в этой гла- ве, должны работать с любой из распространенных СУБД. Изменение имен таблиц На первый взгляд изменение имени таблицы кажется невинной и простой опера- цией. Однако взгляд на рис. 8.3 покажет, что такое изменение влечет за собой го- раздо более серьезные последствия, чем вы могли бы подумать. Если, например, мы хотим поменять имя таблицы WORK на W0RK_VERSI0N2, нам необходимо выпол- нить несколько задач: изменить ограничение, определяющее связь между таблица ми WORK и TRANSACTION, переопределить представление ArtistWorkNet и переписать триггеры WORK_JRANSACTION_Check и WORK_deletion так, чтобы они использовали новое имя. Кроме того, в SQL-92 нет команды, меняющей имя таблицы. Вместо этого не- обходимо воссоздать имеющуюся таблицу под новым именем, а старую удалить. Между прочим, это требование подсказывает нам хорошую стратегию пзмене- ния имен таблиц: сначала следует создать новую таблицу со всеми соготств) ющими структурами, а затем, когда все будет правильно работать с новой та цей, удалить старую таблицу. Если таблица, подвергающаяся переимено слишком велика для того, чтобы ее копировать, придется использовать стратегии, но они выходят за рамки нашего обсуждения.
Изменение имен таблиц и свойств столбцов 369 Сначала создадим таблицу с помощью оператора CREATE TABLE WORK_VERSION2. Он может быть точно таким же, как оператор CREATE TABLE WORK в листинге 7.1. Добавим оператор ALTER, который определяет внешний ключ, указывающий на таблицу ARTIST. После этого скопируем данные в новую таблицу с помощью сле- дующего SQL-оператора: INSERT INTO W0RK_VERSI0N2 (Copy. Title. Description. ArtistID) SELECT (Copy. Title. Description. ArtistID) FROM WORK; Обратите внимание, что в этом операторе INSERT отсутствует выражение VALUES. Столбцы сопоставляются по их положению в списке (в данном случае у них ока- зываются одинаковые имена), и значения их записываются в новую таблицу. Теперь остается только определить два триггера. Это можно сделать, скопи- ровав текст из старых триггеров и заменив в нем имя WORK на WORK_VERSION2. Затем необходимо проверить базу данных с помощью тестового набора, что- бы убедиться, что все изменения были сделаны правильно. После этого можно заменить имя таблицы в хранимых процедурах и прикладных программах'. Если все было выполнено правильно, можно удалить ограничение внешнего ключа WorkFK и таблицу WORK при помощи следующих двух операторов: ALTER TABLE WORK DROP CONSTRAINT WorkFK; DROP TABLE WORK; Итак, изменение имени таблицы влечет за собой больше последствий, чем может показаться на первый взгляд. Теперь вы понимаете, почему некоторые ор- ганизации настаивают на том, чтобы ни одно приложение и ни один пользователь не использовали реальные имена таблиц. Вместо этого, как описывалось в главе 7, создаются представления, служащие псевдонимами таблиц. Если бы это было сделано, то при изменении имени исходной таблицы нам потребовалось бы из- менить только представления, являющиеся ее псевдонимами. Добавление и удаление столбцов Добавление необязательных столбцов к таблице производится элементарно. На- пример, чтобы добавить в таблицу WORK столбец DateCreated (дата создания), можно использовать оператор ALTER ALTER table work ADD COLUMN DateCreated Date NULL; Если на столбец имеются другие ограничения, например, DEFAULT или UNIQUE, включите их в определение столбца точно так же, как вы бы их включили в опе- ратор CREATE TABLE. Имейте в виду, однако, что при использовании ограничения Последовательность здесь имеет значение. Таблица WORK.VERSION2 была создана из таблицы WORK. Ксли триггеры, хранимые процедуры п прикладные программы будут продолжать работать с таблицей WORK, пока будет П|юхоли п. проперка таблицы WORK VERSION?, то таблица W0RK_VERSI0N2 устареет. Не- обходимо будет предпринять некоторые дейстиия, чтобы синхронизировать ее со старой таблицей, прежде чем переключать хранимые процедуры и прикладные программы на таблицу W0RK_VERSI0N2.
370 Глава 8. Перепроектирование баз данных DEFAULT значение но умолчанию записывается только во вновь создаваем строки, а в существующих строках данный сюлбсц останется пустым. Допустим, мы хотим задать для столбца DateCreated по умолчанию значени 1/1/1900, которое указывало бы на то, что данные в этот столбец еще не вводе, ны. Для этого мы использовали бы оператор ALTER TABLE следующего вида: ALTER TABLE WORK ADD COLUMN DateCreated Date NULL DEFAULT '1/1/1900': Этот оператор приведет к тому, что столбец DateCreated в новых строках таб- лицы WORK будет устанавливаться равным 1/1/1900. Чтобы присвоить это значе- ние существующим строкам, необходимо выполнить следующий запрос: UPDATE WORK SET WHERE DateCreated = '1/1/1900' DateCreated IS NULL: Добавление обязательных столбцов Чтобы создать новый обязательный (NOT NULL) столбец, сперва следует доба- вить его как необязательный (NULL). Затем, используя оператор UPDATE, подоб- ный приведенному выше, нужно присвоить этому столбцу значение во всех стро- ках. После этого можно поменять ограничение NULL на NOT NULL с помощью следующего оператора: ALTER TABLE WORK ALTER COLUMN DateCreated Date NOT NULL: СУБД откажется выполнять данный оператор, если хотя бы в одной строке столбец DateCreated будет пуст. Удаление столбцов Удаление неключевых столбцов производится элементарно. Например, следу- ющий оператор удалит столбец DateCreated из таблицы WORK: ALTER TABLE WORK DROP COLUMN DateCreated: Чтобы удалить столбец, являющийся внешним ключом, сначала необходимо удалить ограничение, которое определяет его как таковой. Такое изменение рав посильно удалению связи; эта тема обсуждается далее в этой главе. Для удаления столбца, являющегося первичным ключом, необходимо снача ла удалить ограничение первичного ключа. Однако для этого потребуется У лить все внешние ключи, использующие этот первичный ключ. Так, напри*' чтобы удалить первичный ключ таблицы WORK и заменить его композит ключом {Title, Copy, ArtistID}, необходимо будет сделать следующие шаги: ♦ удалить ограничение WorkFK из таблицы TRANSACTION; ♦ удалить ограничение WorkPK из таблицы WORK; . ♦ создать новое ограничение WorkPK, использующее ключ {Title, Copy, Arti
Изменение имен таблиц и свойств столбцов 371 ♦ создать в таблице TRANSACTION новое ограничение WorkFK, ссылающееся на ключ {Title, Copy, ArtistID}; > удалить столбец WorkID. Прежде чем удалять столбец WorkID, важно убедиться, что все изменения были выполнены правильно. После того как данный столбец будет удален, восстановить его будет невозможно, иначе как воссоздав таблицу WORK из резервной копии ч Изменение типа данных столбца или ограничений Чтобы изменить тип данных столбца или наложенные на него ограничения, нуж- но просто переопределить столбец с помощью команды ALTER TABLE ALTER COLUMN. Однако если столбец из необязательного делается обязательным, то для успеш- ного выполнения этой модификации необходимо, чтобы ни в одной строке этот столбец не был пустым. Кроме того, в ряде случаев изменение типа данных может привести к потере информации. Например, если поменять тип CHAR(50) на Date, то потеряны будут все текстовые поля, которые СУБД не сумеет преобразовать к типу «дата». Может также случиться, что СУБД просто откажет в таком изменении столбца. Кон- кретный исход зависит от используемой СУБД. В общем случае преобразование типа Numeric к типу Varchar пройдет успешно. Преобразование типов Date, Money и других конкретных типов данных к типам Char или Varchar также, как правило, будет успешным. Обратное преобразование типов Char или Varchar к типам Money, Date или Numeric является рискованным и в некоторых ситуациях может оказаться невозможным. Если бы столбец ARTIST. Birth Date в схеме базы данных галерее View Ridge был определен как char(4), то рискованным, но разумным изменением было бы приведе- ние этого столбца к типу Numeric(4,0). Разумным это изменение было бы потому, что все значения в этом столбце являются числовыми. Вспомните ограничение CHECK, которое использовалось при определении столбца Birth Date (см. листинг 7.1). Данное изменение может быть выполнено при помощи следующего оператора. ALTER TABLE ARTIST ALTER COLUMN BirthDate numeric(4.0) NULL. ALTER TABLE WORK ADD CONSTRAINT NumericBirthYearCheck CHECK (BirthDate > 1900 AND BirthDate < 2100); Теперь следует удалить старые ограничения на столбец BirthDate. Добавление и удаление ограничений (/миляп, и удалять oi раиичепия можно с помощью операторов AL R TABLE ADD CONSTRAIN Г и ALTER TABLE DROP CONSTRAINT, описанных в главах 6 и 7. Разумеется. чт<>бы удалить ограничение, необходимо знать его имя, п это является одной
372 Глава 8. Перепроектированиебаз данных из причин, по которым вам лучше самостоятельно давать имена ограничения чем поручать это СУБД. Изменение кардинальности и свойств связей Часто в процессе перепроектирования баз данных приходится менять кардиналь- ности связен. Иногда бывает необходимо поменять минимальное кардинальное число с нуля на единицу или с единицы на нуль. Еще одна распространенная за- дача — поменять максимальную кардинальность с 1:1 на 1:N или с 1:N наЫ:М. Ре- же возникает необходимость поменять максимальную кардинальность с N:M на 1.N или с 1:N на 1:1. Последнее изменение, как вы увидите далее, может быть вы- полнено только с потерей данных. Изменение минимальной кардинальности Действия, которые необходимо предпринять при изменении минимальной кар- динальности, зависят от того, на какой стороне происходят изменения, — роди- тельской или дочерней. Изменение минимальной кардинальности на стороне родителя Если изменение происходит на родительской стороне связи и заключается в уста- новлении обязательности или необязательности родителя, то все сводится к то- му, чтобы внешнему ключу, представляющему связь, запретить или разрешить иметь пустое значение. Пусть, например, связь 1:N между таблицами СОТРУДНИК и ОТДЕЛ определяется внешним ключом НомерОтдела, содержащимся в таблице СОТРУДНИК. Чтобы установить или снять требование об обязательной принадлеж- ности каждого сотрудника к какому-либо отделу, достаточно изменить статус обязательности столбца НомерОтдела. Чтобы поменять минимальное кардинальное число с нуля на единицу, необ- ходимо внешний ключ, который до того был необязательным, определить как обязательный. Сделать столбец обязательным можно только в том случае, если ни в одной строке таблицы он не является пустым. В случае внешнего ключа это означает, что каждая запись должна уже иметь связь. Если это не так, то необхо дпмо создать связи для всех записей, прежде чем столбец внешнего ключа мож ио будет сделать обязательным. В предыдущем примере каждый сотрудник дол жен принадлежать какому-либо отделу, прежде чем столбец НомерОтдела мо будет сделать обязательным. В зависимости от используемой СУБД, может возникнуть необходим удалить ограничение, определяющее связь, прежде чем изменять внешний
Изменение кардинальности и свойств связей 373 яполнив данное изменение, можно заново создать ограничение. Для приведен- ного выше примера эти действия выполнит следующий SQL-оператор- ALTER TABLE ОТДЕЛ DROP CONSTRAINT ОтделВК: ALTER TABLE DEPARTMENT ALTER COLUMN НомерОтдела Int NOT NULL- ALTER TABLE DEPARTMENT ADD CONSTRAINT ОтделВК FOREIGN KEY (НомерОтдела) REFERENCES ОТДЕЛ(НомерОтдела) ON UPDATE CASCADE Поменять минимальное кардинальное число с единицы на нуль просто. До- статочно сделать столбец НомерОтдела необязательным. Изменение минимальной кардинальности на стороне потомка Как говорилось в главе 7, единственный способ реализовать ненулевую мини- мальную кардинальность на дочерней стороне связи — это написать триггеры, следящие за соблюдением данного ограничения. Поэтому, чтобы поменять мини- мальное кардинальное число с нуля на единицу, необходимо написать соответ- ствующие триггеры. Чтобы поменять минимальное кардинальное число с едини- цы на нуль, достаточно удалить триггеры. В примере с таблицами ОТДЕЛ и СОТРУДНИК, чтобы в каждом отделе был по крайней мере один сотрудник, необходимо написать триггер вставки для табли- цы ОТДЕЛ и триггеры обновления и удаления для таблицы СОТРУДНИК. Триггер таблицы ОТДЕЛ гарантирует назначение сотрудника во вновь созданный отдел, а триггеры таблицы СОТРУДНИК следят за тем, чтобы сотрудник, перемещаемый в другой отдел или удаляемый из отдела, не был последним в связи с родитель- ской таблицей. Данное обсуждение подразумевает, что ограничение обязательного родителя реализуется при помощи триггеров. Если оно реализуется прикладными програм- мами, то эти программы также необходимо изменить. Это еще один аргумент в пользу того, чтобы соблюдение подобных ограничении обеспечивали триггеры, а не прикладные программы. Изменение максимальной кардинальности Единств'-ниая сложшх гь при увеличении кардинальности с 1:1 до 1.N или с N AON М заключается в сохранении существующих связен. Это выполнимо, но, как вы увидите, требует некоторых манипуляций. При уменьшении кардинальности происходит потеря данных. В этом случае необходимо установить политику, определяющую, какие < няэи можно терять.
374 Глава 8 Перепроектирование баз данным Увеличение кардинальности с 1:1 до 1:Ы На рис. 8,4 показана связь 1:1 между таблицами СОТРУДНИК и РАЗРЕШЕНИЕ, НЛ ПАРКОВКУ. Как вы знаете из главы 5. внешний ключ в сия щ вида 1 1 мчжнпц,.^ тнть в любую из таблиц. Однако, куда бы он ни был помещен, его необходим^ определить как уникальный, чтобы реализовать кардинальность 11. Для таблиц изображенных па рис. 8.4, действие, которое требуется предпринять, зависит от того, какая из двух таблиц является родителем, — СОТРУДНИК или РАЗРЕШЕНИЕ НАЛАРКОВКУ. _________СОТРУДНИК_________ ^НомерСотрудника: NOT NULL Имя: NOT NULL Телефон NOT NULL АдресЭлПочты NOT NULL РАЗРЕШЕНИЕ_НА_ПАРКОВКУ «\,НомерРазрешения NOT NULL ДатаВыдачи- NOT NULL -< МестоНомер NOT NULL 1 НомерСотрудника NOT NULL (FK) (AK11) Рис. 8.4. Пример срязи 1:1 Если на роль родителя выбрана таблица СОТРУДНИК (у сотрудника может быть несколько разрешений на парковку), то единственное изменение, которое необходимо произвести, — это удалить ограничение, согласно которому столбец РАЗРЕШЕНИЕ_НА_ПАРКОВКУ.НомерСотрудника является уникальным. Тогда связь примет вид 1:N. Если же родителем становится таблица РАЗРЕШЕНИЕ_НА_ПАРКОВКУ (разреше- ние на парковку распространяется на нескольких сотрудников), то внешний ключ и соответствующие значения должны быть перемещены из таблицы РАЗРЕШЕНИЕ. НА_ПАРКОВКУ в таблицу СОТРУДНИК. Эти действия выполнит следующая последо- вательность операторов: ALTER TABLE СОТРУДНИК ADD COLUMN НонерРазрешения int NULL: UPDATE СОТРУДНИК SET СОТРУДНИК.НонерРазрешения = (SELECT РЛ.НонерРазрешения FROM РАЗРЕШЕНИЕ_НА_ПАРК0ВКУ РП WHERE РП.НомерСотрудника = Сотрудник.НомерСотрудника): После этого необходимо создать новое ограничение внешнего ключа, опреде- ляющее связь. После того как внешний ключ перемещен в таблицу СОТРУДН столбец НомерСотрудника таблицы РАЗРЕШЕНИЕ_НА_ПАРКОВКУ следует Удал‘’^ Обратите внимание, что новый столбец НонерРазрешения таблицы СОТРУД должен иметь ограничение уникальности, чтобы с одним и тем же разрешение** на парковку могли быть связаны несколько сотрудников, как это требуется Увеличение кардинальности с 1:N до N:M Предположим, владельцы галереи View Ridge решили, что им нужна в03М^) ность записывать нескольких покупателей в одной транзакции обусловлено гем, что некоторые произведения находятся в совместной соос
Изменение кардинальности и свойств связей 375 ности клиента и его банка или доверительного счета, или тем, что владельцы хо- тят записывать имена обоих супругов в случае покупки произведения семейной парой. Как бы то ни было, для этого потребуется поменять кардинальность связи между таблицами КЛИЕНТ и ТРАНЗАКЦИЯ с 1:N на N:M. CUSTOMER-TRANSACTION JNT ^kcustomerlD (FK) -« ^TransactionlD (FK) н CUSTOMER «^CustomerlD Name Street City State ZipPostalCode Country AreaCode Phone Number Email TRANSACTION ^TransactionlD DateAcquired AcquisitionPrice PurchaseDate SalesPrice AskingPrice WorkID (FK) WORK ^.WorkID Title Description Copy ArtistID (FK) ARTIST 4 ArtistID Name Nationality Birthdate DeceasedDate CUSTOMER ARTIST INT Рис. 8.5. Схема базы данных View Ridge с новой связью N:M Изменить связь вида 1:N удивительно просто1: достаточно создать новую таб- лицу пересечения, заполнить ее данными и удалить старый столбец внешнего ключа. На рис. 8.5 показана схема базы данных галереи View Ridge с новой табли- цей пересечения, представляющей связь N:M. Нам необходимо создать эту таблицу и скопировать в нее значения столбцов TransactionlD и CustomerlD из тех строк таблицы TRANSACTION, где столбец CustomerlD не является пустым. Сначала созда- дим таблицу пересечения: CREATE TABLE CUSTOMER_TRANSACTION_INT( CustomerID int NOT NULL. TransactionlD int NOT NULL. CONSTRAINT CustomerTransactionPK PRIMARY KEY (CistomerlD. TransactionlD). CONSTRAINT Customer_Transaction_Int_TransactionFK FOREIGN KEY (TransactionlD) REFERENCES 1 По крайней мере, изменить сами данные будет просто. Сложнее будет с последствиями .ттнх изме- нений в представлениях, т рип ерах, хранимых процедурах и прикладных программах. Их при тется переписать, чтобы они осуществляли соединение через новую таблицу пересечения. Необходимо '•улет также модифицировать в< с формы н отчеты, чтобы в них можно было отображать данные о нескольких клиентах в одной гран нкцнн, .ио означает например, что вместо текстовых нолей нужно будет исцотьаовагь таблицы (giкК) Это трудоемкая и потому дорогая работа.
ЗТ®Глава 8. Прр^проектиро—нм» баэ данным TRANSACTION (TransactionlD) ON UPDATE CASCADE CONSTRAINT Customer Transaction Int Customers FOREIGN KEY (CustomerlD) REFERENCES CUSTOMER (CustomerlD) ON UPDATE CASCADE Теперь заполним новую таблиц} данными из таблицы TRANSACTION INSERT INTO CUSTOMER_TRANSACTION_INT(CustomerlD. TransactfonlDJ SELECT CustomerlD. TransactionlD FROM TRANSACTION WHERE CustomerlD IS NOT NULL. Прежде чем выполнять эти изменения, разработчики обратятся к графу зави- симостей. Из него они определят, что у таблицы TRANSACTION имеется триглу (не показанный на частичном графе на рис. 8.3), который необходимо будет переписать. Этот триггер следит за тем, чтобы единственным изменением, произ- водимым со столбцом TRANSACTION.CustomerlD, было присвоение значения пусто- му столбцу. Аналогичный триггер необходимо будет написать для новой таблицы пересечения. Могут быть также представления, использующие таблицы CUSTOMER и TRANSACTION, и их нужно будет также переписать. После выполнения всех этих изменений столбец CustomerlD можно будет удалить. Уменьшение кардинальности (с потерей данных) Уменьшить кардинальность связи легко. Чтобы поменять кардинальность с N:M на 1:N, достаточно создать новый внешний ключ в отношении, которое будет по- томком, и заполнить его данными из таблицы пересечения. Чтобы превратить связь 1.N в 1:1, нужно сделать значения внешнего ключа связи 1.N уникатьными и затем ввести для него ограничение уникальности. В обоих случаях самое слож- ное — это решить, какие данные можно терять. Рассмотрим сначала уменьшение кардинальности с N:M до 1:N. Предположим, что галерея решает ограничить список художников, которыми интересуется кли- ент, одной фамилией. Тогда связь между таблицами ARTIST и CUSTOMER примет вид 1:N. Для этого мы добавляем в таблицу CUSTOMER новый внешний ключ ArtistID и определяем соответствующее ограничение внешнего ключа. Эти Де^' ствия выполняет следующая последовательность операторов: ALTER TABLE CUSTOMER ADD COLUMN ArtistID int NULL: ALTER TABLE CUSTOMER ADD CONSTRAINT ArtistlnterestFK FOREIGN KEY ArtistID REFERENCES ARTIST (ArtistID) ON UPDATE CASCADE ON DELETE CASCADE:
Добавление и удаление связей 377 Теперь необходимо решить: какого из потенциально многих художников, которыми интересуется клиент, оставить в новой связи? Ответ зависит от по- литики галереи. Здесь мы предположим, что решено было оставить первого художника: UPDATE CUSTOMER SET ArtistID = (SELECT Top 1 ArtistID FROM CUSTOMER_ARTIST_INT CI WHERE CUSTOMER CustomerlD = CI.CustomerlD): Фраза Top 1 означает, что следует возвратить первую строку, удовлетворя- ющую условию. Все представления, триггеры, хранимые процедуры и прикладные программы необходимо будет модифицировать в соответствии с изменившейся связью. После этого можно будет удалить ограничения, определенные для таблицы CUSTOMER- ARTIST—INT, а затем и саму эту таблицу. Чтобы превратить связь 1.N в 1:1, достаточно удалить дублирующиеся зна- чения внешнего ключа связи и ввести ограничение уникальности па внешний ключ (вопрос 57). Добавление и удаление связей Добавление новых таблиц и связей производится элементарно, с помощью опера торов CREATE TABLE с ограничениями FOREIGN KEY, как показано выше. Если суще- ствующая таблица выступает для новой таблицы в роли потомка, го следует вве- сти ограничение FOREIGN KEY для существующей таблицы. Например, если нужно добавить в базу данных View Ridge таблицу COUNTRY (страна) с первичным ключом Name (название), и если столбец CUSTOMER.Country является внешним ключом, указывающим па новую таблицу, то для таблицы CUSTOMER следует определить следующее ограничение внешнего ключа: ALTER TABLE CUSTOMER ADD CONSTRAINT CountryFK FOREIGN KEY Country REFERENCES COUNTRY(Name) ON UPDATE CASCADE: Удаление связей и таблиц сводится к тому, чтобы удалить ограничения впешне- ю ключа, а зач ем удалить таблицу. Разумеется, прежде чем это делать, необходи- мо построить граф зависимостей и с его помощью определить, какие представле- ния, Триперы, хранимые процедуры и прикладные программы будут затронуты При удалении, Все эти действия просты потому, что не преобразуют существующие данные Иногда, однако, появление новых таблиц н связей бывает обусловлено псоохо- Аимостью нормализации или денормалн i.mnu. Рассмотрим ин случаи
378 Глава 8. Перепроектирование баз данных Добавление таблиц и связей с целью нормализации Мы начали эту главу с обсуждения таблицы СОТРУДНИК (см. табл. 8.1). Эта табли- ца имеет следующий формат: СОТРУДНИК (НомерСотрудника, Имя, Отдел, БюджетныйКод) Опа не нормализована, поскольку содержит функциональную зависимость Отдел-> Бюджетный Код, где Отдел не является ключом-кандидатом. Ранее вы на- учились использовать коррелированный подзапрос для проверки этой функцио- нальной зависимости. Этот запрос указал нам па строку, в которой необходимо было исправить значение столбца БюджетныйКод. Допустим, что соответству- ющее исправление было внесено и таблица СОТРУДНИК готова к нормализации. Нормализация таблицы СОТРУДНИК Чтобы нормализовать таблицу СОТРУДНИК, необходимо выполнить несколько дей- ствий: создать новую таблицу ОТДЕЛ, создать связь вида 1:N между таблицами ОТДЕЛ и СОТРУДНИК, скопировать данные из таблицы СОТРУДНИК в таблицу ОТДЕЛ и, наконец, удалить из таблицы СОТРУДНИК столбец БюджетныйКод. Процедура создания таблицы и связи аналогична тому, что мы делали ранее, пол ому здесь мы не будем ее рассматривать. Пусть новая таблица была опреде- лена следующим образом: ОТДЕЛ (Название. БюджетныйКод) Предположим также, что столбец Отдел таблицы СОТРУДНИК был переимено- ван в НазваниеОтдела и определен как внешний ключ, указывающий на столбец Название таблицы ОТДЕЛ. Следующий SQL-оператор скопирует данные из таблицы СОТРУДНИК в табли- цу ОТДЕЛ: INSERT INTO ОТДЕГЦНазвание. БюджетныйКод) SELECT 015Т^СТ(Название0тдела. БюджетныйКод) FROM СОТРУДНИК; После того как все предст авления, т риггеры, хранимые процедуры и приклад пые программы будут изменены так, чтобы в них использовалась новая таблица ОТДЕЛ, столбец БюджетныйКод можно удалить из таблицы СОТРУДНИК. Нормализация таблицы WORK из базы данных View Rid9e Рассмотрим теперь таблицу WORK из базы данных галереи View Ridge. Она co/tf-T жнт столбцы WorkID, Title, Copy, Description и ArtistID. Ключей-кандидатов име€*т0 два: WorkID и группа {ArtistID, Title, Сору}. Предположим, что возникает вопрос.^ содержит столбец Description - описание самого произведения или ко11К.|*^р1 его коппп? В нервом случае мы имеем функциональную зависимость (А ’ Title)-description, в последнем — (ArtistID, Title, Copy)->Description. Более того, в^^ вом случае таблица оказывается ненормализованной, поскольку ограни (ArtistID, Title)-description не следует из определения ключа {ArtistID, Тт е>
Добавление и удаление связей 379 Для ответа на этот вопрос мы можем использовать коррелированные подза- просы. В частности, с помощью такого запроса можно выяснить, существуют ли строки, в которых значения комбинации {ArtistID, Title} совпадают, а значения столбца Description - нет. Если да, то группа {ArtistID, Title} не может быть ключом. Следующий SQL-оператор возвратит все строки, имеющие различные значе- ния Description при одном и том же значении комбинации {ArtistID, Title}: SELECT ArtistID. Title. Copy, Description FROM WORK Wl WHERE Wl. Artist ID IN (SELECT ArtistID FROM WORK W2 WHERE Wl.Description <> W2. Description AND Wl.ArtistID = W2.ArtistID AND Wl.Title = W2.Title); Результат этого запроса выглядит так: 14 Mystic Fabric 99/135 One of the only privately held copies m excellent condition1 14 Mystic Fabric 105/135 Some water damage, but a great image! Исходя из этого результата, наше предположение о том, что комбинация {ArtistID, Сору} может быть ключом-кандидатом, неверно. {ArtistID, Сору} не опре- деляет однозначно Description, а следовательно, и не может быть ключом. Теперь можно задаться вопросом, подтверждают ли данные наше представле- ние о том, что комбинация {ArtistID, Title, Сору} является ключом. Если да, то ни одной строки не должен возвратить следующий запрос: SELECT ArtistID. Title. Copy. Description FROM WORK Wl WHERE Wl.ArtistID IN (SELECT ArtistID FROM WORK W2 WHERE Wl.Description <> W2.Description AND Wl ArtistID = W2 ArtistID AND Wl.Title = W2.Title AND Wl.Copy » W2 Copy): И действительно, выполнив этот запрос, мы не получим в результате ни од- ной строки. Таким образом, согласно имеющимся данным, комбинация {ArtistID, Title, Copy может быть ключом таблицы WORK. Однако последней инстанцией в вопросе о Функциональных зависимостях являются все же пользователи. А они могут сказать, например, следующее: «Да, мы вводили данные так. как если бы столбец Description относился к отдельной копии произведения, а не к самому произведе- нию Но было бы неплохо, если бы можно было также ввести описание пропзве Деиия как таковою, независимо ог копии. Иаиример, мы бы хотели иметь в базе Данных описание как самой литографин Mystic Fabric, так и всех ее копий, кото- рые есть в галерее».
380 Глава 8. Перепроектирование баз данных На рис. 8.6 изображен новый вариант схемы базы данных View Ridge, coot ветствующий этим новым требованиям. II таблица WORK, и новая таблица WORK COPY (копия работы) имеют столбец, содержащий описание в таблице WORK^ столбец TitleDescription (описание работы), а в таблице WORK_COPY — WorkDescription (описание копии). CUSTOMER ^.CustomerlD Name Street City State ZipPostalCode Country AreaCode PhoneNumber Email TRANSACTION ^TransactionlD DateAcquired AcquisitionPrice PurchaseDate SalesPrice AskingPrice CustomerlD (FK) WorkCopylD (FK) WORK_COPY ^WorkCopylD ,- Copy [ WorkDescription - WorkID (FK) WORK 4 WorkID Title ! TitleDescription и ArtistID (FK) ARTIST 4 ArtistID Name Nationality Birthdate DeceasedDate CUSTOMER-ARTISTJNT Рис. 8.6. Схема базы данных View Ridge с таблицей WORK_COPY Производя эти изменения, мы, в сущности, нормализуем таблицу WORK. Мы соз- даем новый атрибут TitleDescription, для которого имеет место зависимость (ArtistID, Title)—>TitleDescription. Следовательно, необходимо создать таблицу, в которой ком- бинация {ArtistID, Title} будет ключом-кандидатом. Такой таблицей и будет WORK_COPY. Создадим ее с помощью оператора CREATE TABLE и введем ограничение, определяющее связь таблицы WORK_COPY с табли- цей WORK. Кроме того, необходимо переместить в новую таблицу столбцы Сору, Description и WorkID. Эту последнюю задачу выполнит следующий оператор: INSERT INTO WORK_COPY(Copy. WorkDescription. WorkID) (SELECT Copy. Description. WorkID FROM WORK): После того как все представления, триггеры, хранимые процедуры и приклад* ные программы будут изменены гак, чтобы в них использовалась новая таблица, можно оудет удалить из таблицы WORK столбцы Сору и Description. Помимо этого, необходимо будет добавить в таблицу WORK столбец TitleDescription, а столбец WorkID в таблице TRANSACTION переименовать в WorkCopylD. Разумеется, внешние ключи также нужно будет изменить. Удаление связей с целью денормализации В некоторых случаях бывает желательно денормалнзовать существующие дан ные. В галер View Ridge такая ситуация может возникнуть, если обнару*'11 ся, что большую часть времени в галерее имеется не более одной работы кажД
Добавление и удаление связей 381 художника. В этом случае объединение таблиц ARTIST и WORK в одну таблицу при- вело бы к удалению связи между ними, тем самым облегчая обработку. Далее бу- дем предполагать, что мы работаем с первоначальной схемой базы данных View Ridge, изображенной на рис. 7.3, б, а не с теми ее модифицированными варианта- ми, которые описывались в предыдущих разделах этой главы. Если объединить таблицы ARTIST и WORK в одну таблицу, она будет иметь сле- дующую структуру: ARTIST_WORK (ArtistWorklD, Name, Nationality, BirthDate, DeceasedDate, Title. Copy Description) Эта таблица не нормализована, и данные о художнике будут дублироваться для каждого произведения этого художника, имеющегося в галерее. Но если обычно в галерее имеется не более одной работы каждого художника, это не будет проблемой. Для создания новой таблицы используется оператор CREATE TABLE. В нем нет ничего нового, поэтому мы не будем приводить его здесь. Теперь для заполнения новой таблицы мы соединим существующие таблицы ARTIST и WORK при помощи следующего оператора: INSERT INTO ARTIST_WORK (Name. Nationality. BirthDate. DeceasedDate. Title Copy. Description) SELECT Name. Nationality. BirthDate. DeceasedDate. Title, Copy. Description FROM ARTIST JOIN WORK ON ARTIST ArtistID = WORK.ArtistID: Необходимо также будет изменить таблицу TRANSACTION, чтобы ее внешний ключ указывал на ARTIST_WORK, а не на WORK. Написание SQL-оператора, запол- няющего данными новый столбец внешнего ключа, мы оставим читателю в ка- честве упражнения (вопрос 58). После того как все представления, триггеры, хранимые процедуры и прикладные программы будут изменены так, чтобы в них использовалась новая таблица, можно будет удалить таблицы WORK и ARTIST. Удаление таблицы CUSTOMER.ARTISTJNT Еще одна возможность денормализации в базе данных View Ridge заключается Удалении таблицы CUSTOMER_ARTIST_INT Как вам известно, наличие такой таблицы усложняет все SQL-операторы, манипулирующие таблицами CUSTOMER и ARTIST, так что н ее удалении есть свои преимущества. нованием такого решения может быть то, что, по мнению сот] у талерси каждый клиент Ттнтсресуегся всеми художниками, и таолнца CUSTOMER- ARTIST- INT h‘- дает никакою выигрыша Пли наоборот, возможно, все клнен ы ^тересукугся одним, максимум двумя художниками, поэтому не мнотое будет потеряно, если удалить таблицу пересечения и вместо лого добавить в таблицу CUSTOMER (толбтец FavonteArtist (любимый художник). Э101 столбец можс1 быть ппршним Ключом, указывающим на таблицу ARTIST Таким образом, связь между афишами ARTIST и CUSTOMER принимает вид 1 N вместо N М
382 Глава 8. Перепроектирование баз данных Проверка предположений пользователей относительно имеющихся данных и бизнес-процедур Для проверки предположений пользователей относительно имеющихся данцц и б из нес-процедур можно использовать изученные вами в этой главе конструк. цип языка SQL. В разделе, посвященном условиям EXISTS/NOT EXISTS, был показан способ создания запроса, выдающего художников, которыми интересуются все без исключения клиенты. В наших данных такой художник был всего один, по- этому первое обоснование удаления таблицы пересечений (якобы каждый кли- ент интересуется всеми художниками) неверно. Предположим, мы хотим знать, сколькими художниками интересуется каж- дый клиент. Простой запрос, позволяющий это определит, выглядит так: SELECT С.Name. Count(*) as Numinterests FROM CUSTOMER C JOIN CUSTOMER_ARTIST_INT CI ON C.CustomerlD = CI.CustomerlD GROUP BY C.Name: Результат этого запроса для наших данных будет иметь следующий вид: Chris Wilkens David Smith Donald G. Gray Fred Smathers Jeffrey Janes Lynda Johnson Mary Beth Frederickson Selma Warning Susan Wu Tiffany Twilight 2 1 1 1 1 3 3 2 1 3 Если эти данные являются типичными, они поддерживают предположение что один или два столбца для любимых художников будут разумным решением. Еще один способ уменьшить размер базы данных — удалить художников, ко- торыми не интересуется ни один клиент. Следующий запрос возвращает имена художников и количество клиентов, не интересующихся ими: SELECT A.Name. Count!*) as NumCustNotinterested FROM ARTIST AS A. CUSTOMER AS C WHERE EXISTS (SELECT C.CustomerlD FROM CUSTOMER WHERE NOT EXISTS (SELECT CI.CustomerlD FROM CUSTOMER_ARTIST_INT CI WHERE C.CustomerlD = CI.CustomerlD AND A.ArtistID = CI.rtistID)) GROUP BY A.Name:
Добавление и удаление связей 383 Этот запрос использует то, что называется декартовым соединением: обратите внимание, что в верхнем операторе SELECT отсутствуют условия ON и WHERE. В нем каждая строка таблицы ARTIST соединяется с каждой строкой таблицы CUSTOMER. Это необходимо нам, чтобы получить все возможные комбинации художников и клиентов; из них мы выбираем те, что отсутствуют в таблице пересечения. Заметьте, что если первая таблица имеет п строк, а вторая т строк, то резуль- тат декартова соединения будет содержатьпхт строк. Таким образом, этот вид соединения способен создавать огромные таблицы, поэтому следует пользовать- ся им с осторожностью. Если мы определим этот запрос как представление (пусть у него будет имя ArtistNoInterestCount), то, выполнив левое соединение с таблицей ARTIST, мы смо- жем увидеть всех художников: SELECT A.Name NumCustNotlnterest FROM ARTIST A LEFT JOIN ArtistNoInterestCount Al ON A.Name = Al Name; Результат выполнения этого запроса для наших данных будет выглядеть так: Chagall 9 Frings 6 Kandinsky 10 Klee 10 Matisse 10 Miro 9 Moos 8 Tobey Null Обратите внимание, что для художника Tobey результат подсчета нуст, по- скольку им интересуются все клиенты. Мы можем заменить пустое значение ну- лем, используя функцию COALESCE: SELECT A.Name Coalesce (NumCustNotlnterest. 0) FROM ARTIST A LEFT JOIN ArtistNoInterestCount Al ON A.Name = Al.Name; Функция COALESCE просто выбирает первый непустой элемент в переданных ей аргументах. Если все аргументы пустые, она возвращает пустое значение. В дан- ном случае функция возвратит либо ненулевое значение NumCustNotlnterested, либо 0. Результаты будут такими: Chagall 9 Frings 6 Kandinsky 10 Klee ю Matisse 10 Miro 9 Moos g Tobey о
384 Глава8. Пвр< провюировзни. (изданных На оеновапин .них результатов сотрудники галереи View Ridge мшут при пять решение обойтись без тполицы пересечения I к> если мы aw Сделаем, у 6\ дет меньше возможностей научиться работать с таблицей пересечения так иго мы воздержимся от итого шага, 1т ш персонал галереи псе ж< решит удалить таблицу пересечения, он сможет сделать это. как пока iaiio ранее в этой главе Из приведенных примеров вы можете получить представление о том, как можно использовать SQL для анализа данных перед перепроектированием базы данных. К сожалению. сейчас нам придется оставить тему SQL и перейти к обсуждению других вопросов. Если вы хотите узнать больше, читайте специализированные книги, посвященные расширенным возможностям SQL. Автоматическое конструирование Многие программы моделирования данных позволяют выполнять изменения в базе данных автоматически. Для этого нужно сначала реконструировать модель данных, внести в нее необходимые изменения, а затем запустить процедуру авто- матического конструирования (forward engineering). Здесь мы не будем рассматривать автоматическое конструирование, посколь- ку оно скрывало бы от вас SQL, который вам необходимо выучить. Кроме того, специфика процесса автоматического конструирования зависит от используемо- го программного продукта. По причине важности корректного изменения модели данных многие профес- сионалы скептически относятся к автоматизации процесса перепроектирования базы данных. Без сомнения, необходимо тщательно протестировать результаты, прежде чем использовать автоматическое конструирование для перепроектиро- вания рабочей базы данных. Некоторые программы позволяют просмотреть SQL-операторы, которые они собираются выполнить, прежде чем вносить изме- нения в базу данных. Перепроектирование баз данных — одна из областей, в которых автомати- зация может оказаться не самой лучшей идеей. Многое зависит or природы про- изводимых изменений и качества процедур автоматического проектирования, имеющихся в программе моделирования данных. Обладая знаниями, которые вы приобрели в этой главе, вы должны быть способны выполнись большую часть модификации, связанных с перепроектированием, самостоятельно с ломоты0 SQL В этом подходе пег ничего неправильного! Резюме В большинстве случаев проектирование баз данных включает в себя работу по перепроектированию существующей базы данных. Перепроектирование шюбха’Ш- мо для исправления ошибок, сделанных на этапе первоначального ироекгнр01'3 пня, а также для адаптации оазы данных к изменениям в системных требованиях. Такие изменения неизбежны, поскольку информационные системы ц оргавнза
Резюме 385 цин не просто влияют друг па друга, а буквально создают друг друга. Таким обра- зом, внедрение новых информационных систем приводит к изменению систем- ных требований. Важными конструкциями языка SQL являются коррелированные подзапро- сы и условия EXISTS/NOT EXISTS. Их можно использовать для создания сложных запросов, а также для проверки некоторых предположений относительно данных в процессе перепроектирования баз данных. Например, с их помощью можно определить, согласуются ли данные с определенными для них функциональными зависимостями. Коррелированный подзапрос обманчиво похож на обыкновенный подзапрос. Разница между ними состоит в том, что обычный подзапрос выполняется снизу вверх. В обычном подзапросе результаты нижнего запроса можно определить не- зависимо и затем использовать для выполнения верхнего запроса. В отличие от этого, в коррелированном подзапросе обработка имеет челночный характер: одна строка из верхнего запроса сравнивается со всеми строками нижнего запроса. Ключевым отличием коррелированного подзапроса является то, что запросы более низкого уровня используют столбцы из запросов более высокого уровня. Запросы с условиями EXISTS и NOT EXISTS представляют собой особые случаи коррелированных подзапросов. В них верхний запрос выдает результат в зависи- мости от существования строк в запросах более низкого уровня. Ключевое слово EXISTS является истинным, если хотя бы одна строка подзапроса отвечает задан- ным условиям; условие NOT EXISTS является истинным, если ни одна строка под- запроса не отвечает заданным условиям. Ключевое слово NOT EXISTS полезно для создания запросов с условиями, которые должны выполняться для всех строк, — например, «клиент, купивший все продукты». Двойное использование условия NOT EXISTS — широко известный шаблон, который используется для проверки знания SQL. Прежде чем перепроектировать базу данных, необходимо сначала тщательно ее проанализировать, чтобы избежать повреждения базы при частичном выпол- нении изменений. Здесь действует правило «семь раз отмерь — один отрежь». Для восстановления модели данных по существующей базе данных используется процесс реконструкции. Это делается для того, чтобы приобрести лучшее пони- мание структуры базы данных, прежде чем вносить какие-либо изменения. По- лученная модель, называемая реконструированной моделью данных, не является ни концептуальной, ни внутренней схемой: она имеет характеристики, присущие »боим типам схем. Большинство средств моделирования данных способны вы- П(У1нять реконструкцию. В реконструированной модели данных всегда отсут- ствует какая-го информация; такие модели необходимо тщательно исследовать. Все элементы базы данных взаимосвязаны I рафпческпм представлением этих взаимосвязей служи!' граф зависимостей Например, изменение в таблице потен- циально может затронуть связи, представления, индексы, триггеры, хранимые ’•Илн’дуры и прикладные нренраммы. Об этих эффектах необходимо знать и учи тмяать их при внесении Изменений Пр-ждечем делать какие-либо модификации в рабочей базе данных, необхо- димо создать «<• полную резервную копию Кроме юго, все изменения должны
386 Глава 8. Перепроектирование баз данных быть тщательно проверены, сначала на тестовых базах данных небольшого раз- мера. затем на более объемных базах, которые даже могут быть полными копия хш рабочей базы данных Только успешно выполнив эгн проверки, можно вно- сить изменения в рабочую базу данных Модификации, выполняемые в процессе перепроектирования базы данных, можно разделить на несколько групп. Одна из групп — это изменение имен таб- лиц и свойств столбцов. Изменение имени таблицы может повлечь за собой уди- вительно много последствий. Для выявления этих последствий следует проана- лизировать граф зависимое гей. Неключевые столбцы можно беспрепятственно добавлять и удалять. Вставка обязательного столбца выполняется в три этапа сначала этот столбец добавляется как необязательный, затем в каждую строку записываются данные, после чего вводится ограничение, определяющее этот столбец как обязательный. Чтобы удалить столбец, являющийся внешним клю- чом, необходимо сначала удалить ограничение, определяющее его как таковой. Ограничения и тип данных столбца можно менять с помощью оператора ALTER TABLE ALTER COLUMN. Преобразование данных конкретных типов (например, Date) к типам Char или Varchar обычно не представляет проблемы. В некоторых случаях при этом будут потеряны данные, а может случиться, что СУБД отка- жет в изменении. Добавлять и удалять ограничения можно с помощью операто- ра ALTER TABLE ADD/DROP CONSTRAINT. Пользоваться этим оператором будет легче, если разработчик самостоятельно присвоил имена всем ограничениям. Изменение минимальной кардинальности на родительской стороне связи сво- дится к изменению ограничения, определяющего статус обязательности внешне- го ключа. Изменение минимальной кардинальности на стороне потомка можно осуществить, только создав или удалив триггер, реализующий соответствующее ограничение. Поменять максимальную кардинальность с 1:1 на 1:N легко, если внешний ключ находится в таблице, которой предстоит стать потомком. В этом случае достаточно удалить ограничение, определяющее уникальность внешнего ключа. Если внешний ключ находится не в той таблице, необходимо перенести его в таб- лицу-потомок, не вводя для него ограничение уникальности. Чтобы превратить связь 1.N в N:M, требуется построить новую таблицу пересе- чения и переместить в нее первичный и внешний ключи. Эти изменения относи- тельно просты. Сложнее будет изменить все представления, триггеры, хранимые процедуры, прикладные программы, формы и отчеты, чтобы они использовали новую таблицу пересечения. Уменьшение кардинальности осуществить легко, но эта модификация связа- на с потерей данных. Прежде чем делать такое изменение, необходимо вырабо тать политику, определяющую, какие данные будут сохранены. Чтобы поменять кардинальность cNM па 1:N, необходимо создать в родительской таблице стол бец внешнего ключа и переместить в него один из столбцов таблицы пересечения- Чтобы поменять кардинальность с N:M на 1:N, нужно сначала удалить дубли- рующиеся значения внешнего ключа, а затем ввести ограничение уникальвост на этот ключ. Связи добавляются и удаляются путем определения новых ограни- чений внешнего ключа или удаления существующих ограничений.
Вопросы группы I 387 Добавление таблиц и связен с целью нормализации необходимо производить в несколько этапов. Сначала при помощи коррелированных запросов следует выяснить, справедливы ли предположения, обуславливающие возможность нор- мализации. Если нет, необходимо исправить данные, прежде чем осуществлять изменения. Далее нужно создать новую таблицу и перенести в нее нормализо- ванные данные. После этого остается определить подходящий внешний ключ. Удаление таблиц и связей с целью денормализации сводится к добавлению новых столбцов в депормализуемую таблицу и заполнению их существующими данными. После этого дочернюю таблицу и связь .можно удалить. В большинстве средств моделирования данных предусмотрена возможность автоматического конструирования — изменения существующей базы данных в соответствии с модификациями, сделанными разработчиком в модели данных. Результаты автоматического конструирования необходимо тщательно проверять, прежде чем применять этот процесс к рабочей базе данных. Некоторые програм- мы позволяют просмотреть SQL-операторы, которые они собираются выпол- нить, прежде чем вносить изменения в базу данных. В случае наличия такой воз- можности следует непременно ей воспользоваться. В конце концов, нет ничего плохого в том, чтобы вручную писать SQL-операторы, производящие изменения в базе данных. Вопросы группы I 1 . В чем разница между проектированием и переп[юектированием базы данных? 2 . Почему необходимо перепроектировать базы данных? 3 . Объясните собственными словами смысл следующего высказывания: «Ин- формационные системы и организации создают друг друга». Как это свя- зано с перепроектированием баз данных? 4 . Допустим, таблица содержит два неключевых столбца: ИмяРуководителя и ТелефонРуководителя, причем вы подозреваете, что имеет место зависи- мость ТелефонРуководителя—>ИмяРуководителя. Опишите, что вы сделали бы, чтобы проверить это предположение. 5 Напишите подзапрос (отличный от приведенного в тексте), коюрый не является коррелированным подзапросом. 6 Объясните, почему обработка коррелированных запросов носит цикличе- ский характер, а обычных — нет. 7 Напишите коррелированный подзапрос (отличный от приведенного в тексте) 8 Обьяс ните, чем запрос из вашего ответа на вопрос 5 отличается от запроса из вашею ответа на предыдущий вопрос. 9 Объясните, что неверно в коррелированном подзапросе на стр. 358. 10 Напишите коррелированный подзапрос, определяющий, подтверждают ли Данные предположение из вопроса 4
388 Глава 8 Перепроектирование ба данных 11. Для чего служит ключевое слово EXISTS? 12. Ответьте на вопрос 10, используя условие EXISTS. 13. Объясните разницу между условиями EXISTS и NOT EXISTS 14. Опишите логику обработки запроса на с i p. 3G0. 15. Напишите запрос, выдающий имена клиентов, интересующихся всеми ху- дожниками. 16. Объясните, как работает запрос из вашего ответа на вопрос 15. 17. Почему важно проанализировать базу данных, прежде чем выполнять за- дачи по ее перепроектированию? Что может случиться, если этого ие сде- лать? 18. Опишите процесс реконструкции. 19. Почему модель данных, созданная, путем реконструкции, не является кон- цептуальной схемой? 20. Что такое граф зависимостей? В чем его назначение? 21. Объясните зависимости таблицы WORK на рис. 8.3. 22. Какие источники используются при построении графа зависимостей? 23. Опишите два типа тестовых баз данных, которые следует использовать для тестирования предложенных изменений при перепроектировании баз данных 24. Опишите проблемы, которые могут возникнуть вследствие изменения име- ни таблицы. 25. Опишите процесс изменения имени таблицы. 26. В соответствии с рис. 8.3 опишите задачи, которые нужно выполнить, что- бы поменять имя таблицы WORK на W0RK_VERSI0N2. 27. Объясните, как представления могут упростить процесс изменения имени таблицы 28. При каких условиях будет правильным следующий SQL-оператор: INSERT INTO Т1(А В) SELECT (C.D) FROM Т2: 29. Напишите SQL-оператор, добавляющий целочисленный столбец С1 в таб- лицу Т2 (пусть С1 будет необязательным). 30. Ответьте па вопрос 29, но теперь пусть столбец С1 является обязательным- 31. Напишите SQL-оператор, удаляющий столбец С1 из таблицы Т2. 32. Опишите процесс удаления первичного ключа С1 и создания нового пер вичного ключа С2. 33. Какие изменения типа данных наименее рискованны? 34. Какие изменения типа данных наиболее рискованны? 35. Напишите SQL-оператор, меняющий тип данных столбца С1 на NOT NULL. Каким условиям должны удовлетворять данные, чтобы это из пение было произведено успешно? М 39 4L 42 43. 44. 45. 46. «г 1 I я ’
Вопросы Группы I 389 36, Объясните, как изменить минимальную кардинальность в случае когда родитель из обязательного становится необязательным. 37. Объясните, как изменить минимальную кардинальность в случае когда родитель из необязательного становится обязательным. Каким условиям должны удовлетворять данные, чтобы это изменение было произведено успешно? 38. Объясните, как изменить минимальную кардинальность в случае, когда потомок из обязательного становится необязательным. 39. Объясните, как изменить минимальную кардинальность в случае, когда потомок из необязательного становится обязательным. 40. Опишите, как поменять максимальную кардинальность с 1:1 на 1:N. Пусть внешний ключ находится в таблице, которая будет потомком в создава- емой связи 1:N. 41. Опишите, как поменять максимальную кардинальность с 1:1 па LN. Пусть внешний ключ находится в таблице, которая будет родителем в создава- емой связи 1:N. 42. Допустим, таблицы Т1 и Т2 имеют связь 1:1. Пусть таблица Т2 имеет внеш- ний ключ. Напишите SQL-операторы, перемещающие внешний ключ в Т1. Дайте имена ключам и внешним ключам самостоятельно. 43. Объясните, как преобразовать связь вида LN в N:M. 44. Допустим, таблицы Т1 и Т2 имеют связь 1:N. Напишите SQL-операторы, заполняющие таблицу пересечения T1_T2_INT. Дайте имена ключам и внеш- ним ключам самостоятельно. 45. Объясните, как уменьшение максимальной кардинальности приводит к по- тере данных. 46. Используя таблицы из вашего ответа па вопрос 44, напишите SQL-опера- торы, меняющие тип связи обратно на 1:N. Пусть внешний ключ образует первая строка таблицы пересечения, удовлетворяющая условию. Данте имена ключам и внешним ключам самостоятельно. 47 Используя ваш ответ на вопрос 46, объясните, что необходимо сделать, чтобы превратить эту связь в связь вида Г.1. Дайте имена ключам и внеш- ним ключам самостоятельно. 48 Опишите в общих чертах, что необходимо сделать, что ы до авпг х 4» Пусть таблицы Г1 и Т2 имеют связь 1.N, причем Т2 является потомком. Напишите SQL операторы, удаляющие таблицу 2. Данге имена ключам и внешним ключам самостоятельно 50 Опишите изменения, необходимые для .ото. чтобы нормализовать табли- цу, содержащую какие то данные 51 Пусть таблица С1 имеет два неключеных столбца. С1 и С2, н предположи ГСЛЫ1О С1^С2 Напишите SQL-опсраюры. необходимые для того, чтобы нормали ютмть эти столбцы в виде отдельной таблицы
390 Глава 8. Перепроектирование баз данных 52. Чем отличаются ио своим следствиям приведенные ниже два утвержден^ относительно столбцов таблицы. WORK i.uiepeu View Ridge? (ArtistID. Title)-»Description (ArtistID, Title, Copy)->Description 53. Опишите в общих чертах, что требуется сделать для денормализации двух таблиц. 54. Пусть таблицы Т1 и Т2 имеют связь 1:N, причем Т2 является потомком Напишите SQL-операторы, денормализующие их в одну таблицу. Дайте имена ключам и внешним ключам самостоятельно. 55. Некоторая организация ставит под вопрос необходимость в таблице пересе- чения. Опишите два различных способа, позволяющих обосновать устра- нение или сохранение таблицы пересечения с помощью коррелированных запросов. 56. Каковы проблемы и риски, связанные с автоматическим конструированием? Вопросы группы II 57. Пусть таблица СОТРУДНИК имеет связь вида LN с таблицей НОМЕР_ТЕЛЕФОНА. Ключом таблицы СОТРУДНИК является столбец ИдСотрудника, а таблица НОМЕР_ТЕЛЕФОНА имеет столбцы ИдНТ (суррогатный ключ), КодРегиона, МестныйНомер и НомерСотрудника (внешний ключ, указывающий на таблицу СОТРУДНИК). Измените эту структуру так, чтобы таблица СОТРУДНИК имела связь 1:1 с таблицей НОМЕР_ТЕЛЕФОНА. Для сотрудников, имеющих несколь- ко номеров телефонов, оставьте первый. 58. Допустим, что таблица WORK базы данных View Ridge была заменена табли- цей ARTIST_WORK, как описано в этой главе. Напишите SQL-операторы, пере- мещающие внешний ключ связи WORK-CUSTOMER в связь ARTIST_WORK- CUSTOMER. Предполагая, что в таблицу ARTIST_WORK необходимо добавить столбец внешнего ключа, определите связь и переместите соответствующие данные. Сделав это, удалите из таблицы WORK внешний ключ, указываю- щий на таблицу CUSTOMER. 59. Рассмотрим следующую таблицу: ЗАДАЧА (ИдСотрудника, Имя, Телефон, НомерОфиса, НазваниеПроекта, Спонсор, Дата. ФактТрудозатраты) со следующими возможными функциональными зависимостями: ИдСотрудника—>(Имя, Телефон, НомерОфиса) НазваниеПроекта—>Спонсор 1) Напишите SQL-операторы, выдающие все строки, которые нарУ1иаК)Т эти функциональные зависимости. 2) Если данные не нарушают указанных функциональных зависимостей’ можно ли считать их корректными? Обоснуйте свой ответ.
Вопросы к проекту FiredUp 391 3) Допустим, что функциональные зависимости верны и что при необхо- димости данные были соответствующим образом исправлены. Напиши- те SQL-операторы, необходимые, чтобы привести эту таблицу к домен- но-ключевой нормальной форме. Предположим, что таблица содержит данные, которые необходимо сохранить. 60. Пусть таблица СОТРУДНИК имеет связь вида 1:N с таблицей НОМЕР_ТЕЛЕФОНА. Ключом таблицы СОТРУДНИК является столбец ИдСотрудника, а таблица НОМЕР_ТЕЛЕФОНА имеет столбцы ИдНТ (суррогатный ключ), КодРегиона, МестныйНомер и НомерСотрудника (внешний ключ, указывающий на табли- цу СОТРУДНИК). Напишите SQL-операторы, необходимые для того, чтобы перепроектировать эту базу данных так, что она будет состоять всего из одной таблицы. Объясните различия между полученными здесь результа- тами и вашим ответом на вопрос 57. Вопросы к проекту FiredUp Предположим, что фирма FiredUp создала базу данных со следующими таблицами: КЛИЕНТ (КлиентСК, Имя, Телефон, АдресЭлПочты) ГОРЕЛКА (СерийныйНомер, Тип, Версия, ДатаВыпуска) РЕГИСТРАЦИЯ (КлиентСК, СерийныйНомер, Дата) РЕМОНТ_ГОРЕЛКИ (НомерСчета, СерийныйНомер, Дата, Описание, Стоимость, Всего- Упяачено, КлиентСК) Допустим, что связи определены в соответствии с тем, как обозначены внеш- ние ключи в приведенном выше списке таблиц (то есть определены ограничения внешнего ключа вроде таких: «РЕГИСТРАЦИЯ.КлиентВК является внешним ключом в таблице КЛИЕНТ (КлиентВК)»). 1. Постройте граф зависимостей между этими таблицами. Объясните, как не- обходимо будет расширить этот граф, чтобы включить в него представления и другие конструкции базы данных — например, хранимые процедуры. 2 Используя построенный граф зависимое гей, опишите, что необходимо бу- дет сделать, чтобы поменять имя таблицы РЕГИСТРАЦИЯ на РЕГ. 3. Напишите последовав ел ьноегь SQL-операгоров, выполняющих изменение имени, которое описано в вопросе 2. 4 Допустим, согрудники фирмы FiredUp решают, что для каждой горелки следует хранить не более одной регистрационной записи. Измените соот- ветствующим образом схему базы данных. Напишите SQL операторы, выполняющие изменение, которое описано в вашем ответе на вопрос 4. Для горелок, имеющих несколько регистраци- онных записей, оставьте самую последнюю по времени. 6 Допустим. сотрудники фирмы I ned Up решают сделать первичным клю- чом таблицы КЛИЕНТ столбец АдресЭлПочты Напишите коррелированные подзапросы. результаты которых могут показать, что такое изменение ямлмгтся неоправданным
392 Глава 8. Перепроектировании баз данных 7. Предположим, столбец АдресЭлПочты может быть сделан первичным клю- чом таблицы КЛИЕНТ, Внесите соответствующие изменения в схему данных. 8. Напишите SQL-операторы, выполняющие изменение, которое описано в ва- шем ответе на вопрос 7. Вопросы к проекту Twigs Tree Предположим, что фирма Twigs Tree создала базу данных со следующими табли- цами: ВЛАДЕЛЕЦ (ИмяВладельца, Телефон, Дом, Улица, Город, Штат, Индекс) РАБОТА (ДатаВыполнения, ИмяВладельца, Описание, Стоимость, Уплачено, ДатаВыплаты) ДОСТАВКА_СТРУЖКИ (ИмяКлиента, ДатаДоставки, Объем, Стоимость, Уплачено, ДатаВыплаты) Допустим, что все связи определены, как следует из внешних ключей в спи- ске таблиц (то есть определены ограничения внешнего ключа вроде «ДОСТАВКА_ СТРУЖКИ.ИмяКлиента является внешним ключом в таблице ВЛАДЕЛЕЦ (ИмяВла- дельца)»). 1. Постройте граф зависимостей между этими таблицами. Объясните, как необ- ходимо будет расширить этот граф, чтобы включить в него представления и другие конструкции базы данных — например, хранимые процедуры. 2. Используя построенный граф зависимостей, опишите, что необходимо бу- дет сделать, чтобы поменять имя таблицы ВЛАДЕЛЕЦ на КЛИЕНТ. 3. Напишите последовательность SQL-операторов, выполняющих изменение имени, которое описано в вопросе 2. 4. Допустим, Саманта выяснила, что некоторые клиенты владеют нескольки- ми участками. Измените модель данных в соответствии с этим фактом. Пусть Телефон является атрибутом сущности ВЛАДЕЛЕЦ, а не УЧАСТОК. 5. Напишите SQL-операторы, выполняющие изменение, которое описано в вашем ответе на вопрос 4. 6. Допустим, Саманта решает сделать первичным ключом таблицы КЛИЕНТ столбец Телефон. Напишите коррелированные подзапросы, результаты ко- торых могут показать, что такое изменение является неоправданным. 7. Предположим, столбец АдресЭлПочты может быть сделай первичным клю чом таблицы КЛИЕНТ. Внесите соответствующие изменения в схему базы данных. 8. Напишите SQL-операторы, выполняющие изменение, которое описан0 в вашем ответе на вопрос 7.
Часть IV Обработка многопользовательских баз данных В части IV данной книги рассматриваются вопросы обработки многопользова- тельских баз данных и различные подходы к этому в двух наиболее популярных СУБД. Глава 9 посвящена администрированию и основным приемам управления многопользовательскими базами данных. Следующие две главы иллюстрируют воплощение этих идей с использованием Oracle 9i (глава 10) и SQL Server 2000 (глава И).
Глава 9 Многопользовательские базы данных Многопользовательские базы данных, являясь весьма ценным инструментом для организаций, которые их создают и используют, в то же время вызывают у них ряд трудностей. Во-первых, они сложны в проектировании и разработке, по- скольку предполагают наличие множества перекрывающихся пользовательских представлений. Кроме того, из предыдущей главы вы знаете, что требования со временем меняются, а изменение требований порождает необходимость измене- ний в структуре базы данных. Такие структурные изменения должны тщательно планироваться и контролироваться, чтобы изменение, сделанное для одной группы пользователей, не вызвало проблем у другой. Вдобавок при параллельной обра- ботке запросов от нескольких пользователей необходимо принимать специаль- ные меры, чтобы действия одного пользователя не оказывали непредусмотренно- го влияния на действия другого пользователя. Как вы увидите, это весьма важная и сложная тема. В больших организациях должны быть определены права и обязанности по обработке. Что происходит, например, когда сотрудник покидает фирму? Когда ею записи можно удалить? Для обработки информации по выплате заработной платы — по окончании последнего оплаченного периода. Для квартальной отчет- ности в конце квартала. Для подсчета налоговых отчислений — в конце года. И 1ак далее. Ясно, что ни один отдел не может в одностороннем порядке опреде- лить, когда можно удалять данные. Аналогичные рассуждения справедливы О1носительно вставки новых данных и изменения существующих. Эти и други® соображения указывают на необходимость разработки системы безопасности, коюрая позволит выполнять только строго определенные действия в строго определенное время и только пользователям, имеющим для этого достаточные полномочия. Базы данных стали ключевым компонентом функционирования организаций и даже основной составляющей их стоимости. К сожалению, базы данных не застрахованы от сбоев и разрушений. Следовательно, жизненно необходимы эффективные планы, методики и процедуры резервного копирования и восста новлеиия. Наконец, со временем потребуются изменения в самой СУБД с целью повы- шения производительное™, внедрения новых возможностей и версий программ
Администрирование баз данных 395 ного обеспечения и учета модификации в операционной системе, под управлени- ем которой она работает. Все это требует хорошего руководства. Для решения этих задач в большинстве организаций были созданы отделы администрирования баз данных. Сначала мы рассмотрим, что входит в их функ- ции, а затем опишем методики, процедуры и программное обеспечение, исполь- зуемые для выполнения этих функций. В следующих двух главах мы обсудим и продемонстрируем в действии средства администрирования баз данных, имею- щиеся в СУБД Oracle 9i и SQL Server 2000. Администрирование баз данных В промышленности используются два термина: администрирование данных (data administration) и администрирование базы данных (database administration). В од- них случаях эти термины являются синонимичными, а в других они имеют раз- ные значения. В данной книге под администрированием базы данных мы будем понимать функцию, относящуюся к конкретной базе данных, включая ее прило- жения. Настоящая глава посвящена администрированию баз данных. Админи- стрирование данных обсуждается в главе 15. Базы данных значительно различаются по своему размеру и широте охвата — от персональных однопользовательских баз данных до больших межорганизаци- онных баз данных, таких как система предварительного заказа авиабилетов. Все они нуждаются в администрировании, хотя задачи, которые в этой связи пред- стоит решать, различны по степени сложности. Например, пользователи персо- нальных баз данных выполняют простые процедурь резервного копирования данных и хранят для документирования минимальное количество записей. В этом случае пользователь базы данных одновременно выполняет функции ее адм! ни- стратора, хотя, возможно, и не подозревает об этом. В приложениях многопользовательских баз данных администрирование ста- новится как более важной, так и более сложной задачей. Поэтому данная задача, как правило, выделяется формально. Иногда эта функция поручается одному или двум сотрудникам, работающим на неполную ставку. В случае больших баз данных, использующих Ишерпег пли интрасеть, администрирование зачастую оказывается слишком затратной по времени и разноплановой задачей, чтобы можно были поручить се одному сотруднику, даже занятому полный рабочий День, Поддержание базы данных с десятками пли сотнями пол ювателей треоу- ет значительных временных aaipar, наряду с техническими знаниями и дипло- матическими навыками, и обычно ocymcciBгяется специальным отделом. В общую компетенцию dAMiiimcipaio] а базы данных входит упрощение раз- работки и использования базы данных. Обычно это означает поддержание ба- йта между противоречащими друг другу установками - па защиту базы данных и на максимизацию re nociviiiiociii и выгоды от се использования. Лдмпннора Тор бйэм данных Отвечает за р* »р «бот ку, функционирование и обслуживание Оа- йМ Данных И ее приложений. 11грсчсп1» конкретных функций приведен во врезкт ид этих функций мы рассмот рим в последующих разделах.
396 Глава 9 Многопользовательские базы данных ФУНКЦИИ АДМИНИСТРАТОРА БАЗЫ ДАННЫХ -------------" ♦ Управление структурой базы данных. ♦ Управление параллельной обработкой. ♦ Распределение прав и обязанностей по обработке. ♦ Обеспечение безопасности базы данных. ♦ Восстановление базы данных. ♦ Управление СУБД. ♦ Поддержание репозитория данных Управление структурой базы данных Управление структурой базы данных включает в себя участие в первоначальном проектировании и реализации базы данных, а также руководство и контроль в про- цессе внесения в нее изменений. В идеальном случае администратор привлекается к работе на ранней стадии разработки базы данных и ее приложений и принимает участие в изучении требований, оценке альтернатив, включая то, какую СУБД предпочтительнее использовать, и разработке структуры базы данных. Для боль- ших организационных приложений администратор базы данных — это обычно менеджер, который руководит работой технически ориентированного персонала по проектированию базы данных. Процесс создания базы данных состоит из нескольких этапов. Прежде всего создается пустая база данных и выделяется место на физическом носителе под саму базу и ее журналы. Затем создаются таблицы, индексы, хранимые проце- дуры и триггеры. Примеры этого вы увидите в следующих двух главах. Когда структуры базы данных сформированы, база заполняется информацией. В боль- шинстве СУБД предусмотрены утилиты для записи больших объемов данных. Конфигурирование После внедрения новой базы данных и ее приложений неизбежно будут меняться требования. Эго может быть обусловлено новыми потребностями, изменениями в бизнес-окруженпи, сменой политики компании и т. д. Когда изменение требо- ваний вызывает необходимость изменения структуры базы данных, следует дей* ствовать с большой осторожностью, потому что структурные изменения редко за- трагивают только одно приложение. Следовательно, для эффекта иного администрирования базы данных нужны процедуры, с помощью которых пользователи могли бы документально фикси решать свои предложения по изменению базы данных, а все сообщество пользе вателен — высказывать свое мнение по поводу этих предложений, чтобы можно было принять глобальное решение о том, стоит ли их воплощать. Из-за больших размеров и сложности базы данных п ее приложений измене пня иногда приводят к неожиданным результатам. Поэтому администратор базы данных должен быть готов к тому, что базу данных придется восстанавливать, и должен иметь достаточное количество информации для диагностики и устра нения проблемы, вызвавшей сбой. База данных наиболее подвержена сбоям по еле внесения изменений в ее структуру.
Администрирование баз данных 397 Документирование в число обязанностей администратора, связанных с управлением структурой базы данных, входит также ведение документации. Исключительно важно знать, какие модификации были произведены, когда и каким образом. Изменение в струк- туре базы данных может повлечь за собой ошибку, которая не будет проявляться в течение полугода. При отсутствии должного документирования изменений диа- гностика такой проблемы становится почти невозможной. Значительная работа может потреооваться для того, чтобы выявить момент, когда начали появляться первые симптомы, и по этой причине важно также вести запись тестовых про- цедур и прогонов, сделанных для проверки произведенной модификации. Если используются стандартизированные тестовые процедуры, тестовые формы и ме- тоды ведения записей, документирование результатов тестов не должно занимать много времени. Хотя ведение документации — процесс утомительный и бесконечный, за- траченные на него усилия окупаются, когда приходит беда и документация оказывается тем, без чего невозможно решить серьезную (и дорогую) проблему. В настоящее время появляется много продуктов, облегчающих ведение доку- ментации. Многие CASE-средства, например, можно использовать для докумен- тирования логической структуры базы данных. Для отслеживания изменений можно использовать программы контроля версий. Словари данных предостав- ляют отчеты и другие средства, содержащие сведения о структуре информации в базе данных. ОБЯЗАННОСТИ АДМИНИСТРАТОРА ПО УПРАВЛЕНИЮ -------------- СТРУКТУРОЙ БАЗЫ ДАННЫХ Участие в разработке базы данных и приложений: ♦ помощь на стадии определения требований и создания модели данных; ♦ активная роль в проектировании и создании базы данных. Помощь в изменении структуры базы данных: ♦ поиск решений во взаимодействии с пользователями; * оценка того, как планируемое изменение отразится на каждом пользователе, ♦ организация форума по вопросам конфигурирования; ♦ готовность к устранению проблем, возникающих после внесения изменений, ♦ ведение документации_____ Еще одна причина для тщательного документирования изменений в структу- ре базы данных заключается в необходимости правильно интерпретировать исторические данные. Если, например, маркетологи захотят проанализировать Данные о продажах трехле гней данное т и, находившиеся в архивах в течение двух им необходимо будет знать, какова была структура базы данных перед тем, «а* Ланны- были отнра.тлсиы в архив. В ответе па этот вопрос могут помочь„за писи, отражающие изменения в структуре базы данных. Аналитичная un, . i вникает, когда для ни<становления поврежденной базы данных приходится ис польэовцп, рс.ерпную копню ще< шмесячноп давности (хотя такого происходить
398 Глава 9. Многопользовательские базы данных не должно, иногда это случается). Резервную копию можно использовать для конструкции базы данных до того состояния, в котором она находилась на мг> мент снятия этой копии. Затем можно в хроиоло! ическом порядке Ьоспроизв^» сти транзакции и структурные изменения, чтобы восстановить базу данных до текущего состояния. Во врезке на предыдущей странице приведен перечень обя- занностей администратора, связанных с управлением структурой базы данных Управление параллельной обработкой Меры по управлению параллельной обработкой нацелены на предотвращение не- предусмотренного влияния действии одного пользователя на действия другого. Иногда цель состоит в том, чтобы в условиях параллельной обработки пользователь получил такой же результат, как и в случае, если бы он был единственным поль- зователем В других случаях подразумевается, что действия различных пользова- телей будут влиять друг на друга, но ожидаемым образом. Например, пользователь, который ввел свой заказ в компьютерную систему должен получить один и тот же результат, независимо от того, сколько еще есть пользователей, кроме него — ни одного или сотни. С другой стороны, пользова- тель, запрашивающий отчет о состоянии склада на самый последний момент, возможно, захочет получить информацию о незавершенных изменениях, нача- тых другими пользователями, даже если существует риск, что эти изменения впоследствии будут отменены. К сожалению, не существует способа управления параллельной обработкой, который одинаково хорошо подходил бы для всех ситуаций. Все эти способы предполагают некоторый компромисс. Например, пользователь может весьма же- стко управлять параллельной обработкой, заблокировав всю базу данных, но пока будут обрабатываться данные для него, ни один другой пользователь не сможет ничего сделать. Такая защита надежна, но дорога. Как вы увидите, существуют и другие меры, которые труднее запрограммировать или реализовать, зато они повышают производительность. Есть также меры, максимизирующие производи- гельность при низком уровне управления параллельной обработкой. При проек- тировании многопользовательских баз данных вам придется делать выбор среди этих компромиссов. Необходимость в атомарных транзакциях В большинстве приложений баз данных работа пользователей организована в фор ме транзакций (transactions), известных также как логические единицы работ** (logical units of work, LUW). Транзакция — это последовательность действШ с базой данных, в которой либо все действия выполняются успешно, либо не вы полняется ни одно из них (в последнем случае база данных остается без измене ний). Такая транзакция иногда называется атомарной (atomic), поскольку она выполняется как единое целое.
Управление параллельной обработкой 399 Рассмотрим следующую последовательность действий с базой данных, кото- рые могут потребоваться при регистрации нового заказа. 1. Изменить запись данного покупателя, увеличив сумму к оплате. 2. Изменить запись продавца, увеличив сумму комиссионных. Вставить в базу данных запись о новом заказе. Предположим, что на последнем шаге нас постигла неудача — например, из- за недостатка файлового пространства. Представьте себе недоразумение, которое тзникло бы. если бы выполнены были только первые два действия, но не третье. Покупателю был бы выставлен счет за заказ, который он не получал, а продавец получил бы комиссионные за товар, который он не отправлял покупателю. Ясно, что эти три действия должны выполняться как единое целое: либо все сразу, ли- бо ни одного. На рис. 9.1 приведено сравнение результатов этих действий в виде после- довательности независимых шагов (рис. 9.1, а) и в виде атомарной транзакции (рис. 9.1, б). Обратите внимание, что когда терпит неудачу одно из действий, со- ставляющих атомарную транзакцию, то изменения в базе данных не производят- ся. Также обратите внимание, что для указания рамок транзакции прикладная программа должна дать команды на начало транзакции (Start Transaction), сохра- нение транзакции (Commit Transaction) и откат транзакции (Rollback Transaction). К нкрстная форма этих команд различается в разных СУБД. Параллельная обработка транзакций Когда в одно и то же время происходит обработка двух транзакций с базой данных, эти транзакции называются параллельными транзакциями (concurrent transactions). Хотя у пользователей может создаваться впечатление, что их транзакции обраба- тываются одновременно, это не может быть так, ибо процессор машины, обраба- тывающей базу данных, способен выполнять только одну инструкцию в каждый момент времени Обычно транзакции выполняются попеременно, то есть опера- ционная система переключает процессор между несколькими задачами, так что эа заданный промежуток времени выполняется некоторая часть каждой из них. Это переключение между задачами происходит столь быстро, что два человека, СЯДящие бок о бок перед двумя компьютерами и работающие с одной и той же базой данных, могут подумать, что их транзакции выполняются одновременно. • реальности же они перемежаются. На рис 9,2 показаны дне параллельные транзакции. Транзакция пользовате- ля * считывает элемент 100. изменяет его и записывает обратно в базу данных. Трпизакция пользователя В выполняет тс же самые действия, ио с элементом 200. Ироиессор обрабатывает граи «акцию пользователя А, пока не произойдет прерыва- Ввода-вывода или какая либо иная задержка пользователя А. Тогда процес- сор иерешпоЧастся на пользователя В и обрабатывает его транзакцию до прихо- да прерывания После Чего операционная система передает управление обратно ?Р<М1ы»ции Первого польэовате 1М. Пользователям обработка кажется одноврс ***ниой но на самом деле она попеременная, или параллельная
КЛИЕНТ Номер Номер клиента заказа______Описание Стоимость 123 1000 400 бейсбольных мячей $2400 ПРОДАВЕЦ LZfc> Г~КЛИЕНТ Транз«кц.ип noew КГ1И1 111
Транзакция После КЛИЕНТ Номер Номер клиента мкзза______Описание Стоимость 123 1000 400 бейсбольных мячей $2400 ПРОДАВЕЦ Начать транзакцию. Добавить данные в таблицу КЛИЕНТ. Добавить данные в таблицу ПРОДАВЕЦ. Добавить данные в таблицу ЗАКАЗ. Если нет ошибок, сохранить транзакцию, иначе — отменить транзакцию. КЛИЕНТ Номер Номер клиента заказа Описание Стоимость 123 1000 400 бейсбольных мячей $2400 ПРОДАВЕЦ б Рис. 9.1. Потребность в транзакциях: а — ошибки, возникшие без использования транзакции; б — атомарная транзакция предотвращает ошибки
402 ГИМ9 Пользователь А Пользователь В 1. Считать элемент 100. 2. Изменить элемент 100. 3. Записать элемент 100. 1. Считать элемент 200 2. Изменить элемент 200 3. Записать элемент 200 Попяпок обработки на сервере базы денных 1. Считать элемент 100 для А. 2. Считать элемент 200 для В 3. Изменить элемент 100 для А. 4. Записать элемент 100 для А. 5. Изменить элемент 200 для В 6. Записать элемент 200 для В. Рис. 9.2. Пример параллельной обработки запросов двух пользователей Проблема потерянного обновления Параллельная обработка, изображенная на рис. 9.2, не вызывает проблем, посколь- ку пользователи обрабатывают различные данные. Но предположим, что оба поль- зователя хотят обратиться к элементу 100. Например, пользователь А хочет зака- зать пять единиц товара 100, а пользователь В — три единицы этого же товара. Рисунок 9.3 иллюстрирует возникающую проблему. Пользователь А считыва- ет запись о товаре 100 в свою рабочую область. В соответствии с этой записью, в наличии имеется 10 единиц товара. Затем пользователь В читает запись о това- ре 0 в свою рабочую область. Опять-таки, согласно этой записи, в наличии имеется единиц товара. Теперь пользователь А берет пять единиц товара, умень- шает количество единиц товара в своей рабочей области до пяти и обновляет 'СЬ ДЛЯ T0B<)Pd 00’ После этого пользователь В берет три единицы товара, количество товара в своей рабочей области до семи единиц и запи- ет что n J КОЛИЧеСГВо В базУ Данных. Теперь база данных ошибочно показыва- в наличии "Г ИМеется семь единиц товара 100. Итак: мы начали с 10 единиц зывает что остат^376411 ВаЯЛ ПЯТЬ’ польз°ватель В взял три, а база данных пока- ди,™ Т СеМК ЯСН0’ что это 1!е так. пользователь g1'^ ™льзователей были верными на момент считывания. Но когда »> "Мьзмате™ * Уже boa ее копия когоря иого обновления dost ппЯ , ’ ситУацня носит название проблемы потерян (concurrent update пгоЫрп f Prob em)’ или проблемы параллельного обновления проблемой несогласован л' УВДествует другая, схожая проблема, называемая нользовательТХ = <lncon« read problem). В этом случае том транзакции пользоватета^к^’1''16 бЫЛ” обРаботаны некоторым ФР^” ошибочные данные. ^ак слеДствие, у пользователя А оказываю боткой, состоит в robtlleC0I7IaC°naini0CTeiUl’ вызванных параллельной обра ТОМ, ггобы не давать нескольким приложениям получать коп»»
У п ра в л е ние параллельной обработкой 403 ной и той же записи, когда предполагается скорое изменение данной записи. дт0 средство называется блокировкой ресурсов (resource locking). Пользователь А 1. Считать элемент 100 (пусть количество элементов равно 10). 2. Уменьшить количество элементов на 5. 3. Записать элемент 100. Пользоввтель В 1. Считать элемент 100 (пусть количество элементов равно 10). 2. Уменьшить количество элементов на 3. 3. Записать элемент 100. Порядок обработки на сервере базы данных 1. Считать элемент 100 (для А) 2. Считать элемент 100 (для В). 3. Установить количество элементов равным 5 (для А). 4. Записать элемент 100 для А. 5. Установить количество элементов равным 7 (для В). 6. Записать элемент 100 для В. Обратите внимание: изменение и запись на шагах 3 и 4 оказываются потерянными Рис. 9.3. Проблема потерянного обновления Блокировка ресурсов Один из способов предотвратить проблемы при параллельной обработке — за- претить совместное использование ресурсов путем блокировки данных, которые считываются для обновления. На рис. 9.4 изображен порядок обработки при ис- пользовании команды lock. Из-за блокировки транзакция пользователя В должна ждать, пока пользователь А не закончит работу с данными по товару 100. При та- кой стратегии пользователь В сможет прочесть запись о товаре 100 только после того, как пользователь А завершит ее модификацию. В этом случае результиру- ющее количество единиц товара в базе данных будет равно двум, как и должно быть. (Было десять, А взял пять, В взял три, осталось два.) Блокировочная терминология Блокировка может налагаться либо автоматически, по инициативе СУБД, либо по команде, которая передается СУБД прикладной программой или запросом пользователя. Блокировка, налагаемая СУБД, называется неявной блокиров- ки (implicit locks), а блокировка, налагаемая по команде, — явной блокировкой (explicit locks). Б предыдущем примере блокировка налагалась па строки данных. Однако не все типы блокировки налагаются па этом уровне. Одни СУБД предусматривают бло- кировку па уровне страницы, другие — на уровне таблицы, а третьи — на уровне ,азы Данных, Размер блокируемого ресурса называется глубиной детализации
404 Глава 9. Многопользовательские базы нны блокировки Jock granularity). При малой глубине детализации СУБД легче г лается с адмпнисгрпров.ншс.м блокировки, но lairuc блокировки идею иш ** причиной конфликтов. Блокировки с большой глубиной детализации с ю мнннстрнронать (СУБД приходи гея отслеживать и проверять гораздо &• деталей), но конфликты при этом менее час гы. Пользователь А 1. Заблокировать элемент 100. 2. Считать элемент 100. 3. Уменьшить количество элементов на 5. 4. Записать элемент 100. Пользователь В 1 Заблокировать элемент 100 2. Считать элемент 100. 3. Уменьшить количество элементов на 3 4. Записать элемент 100. Транзакция А Порядок обработки на сервере базы данных [1. Заблокировать элемент 100 для А. 2. Считать элемент 100 для А. 3. Заблокировать элемент 100 для В -» неудача -г В переводится в состояние ожидания J ' 4. Установить количество элементов равным 5 для А. 5. Записать элемент 100 для А. . 6. Снять блокировку А с элемента 100. 7. Заблокировать элемент 100 для В. 8. Считать элемент 100 для В 9. Установить количество элементов равным 2 для В. 10. Записать элемент 100 для В. 11. Снять блокировку В с элемента 100. Транзакция В Рис. 9.4. Параллельная обработка с явными блокировками lock) блокирую^™ ™ ™ПУ’ Пр" мопо,юльиой блокировке (exclusive может читать или изменять данные ** ЭЛементу‘ Ь*п °лна ДРУгая транзакция не тает элемент от изменении ’в' Коллектив,1(>я блокировка (shared lock) заши- свободно читать данный элемент Т° еСТЬ ДРУ™е тРанзакЦ1Ш МОГуТ > е ли они не пытаются изменить его. Сериализуемые транзакции ixoi да две или более транзакции лА й храняемые в базе данных‘ ло пж раЬатыва1°тся параллельно, их результаты, со- которые получились бы, если 6i л Ы ЫТЬ логически согласованы с результатами* последовательным способом ТДПП11ые фанзакции обрабатывались произвольным называется сериализуемой (serialize тСма Сработки параллельных трапзакш11 Сериализуемость может Гит ' е способов — обработка rnamav.' Л0Ст,,п,Ута несколькими способами. Один из 1 * акции с использованием двухфазной блокировки
Управление параллельной обработкой 405 two-phase locking). При этой стратегии транзакциям позволяется налагать блоки- ровки по мере необходимости, но как только первая блокировка снимается, данная транзакция уже не может наложить никаких других блокировок. Таким образом, транзакции имеют фазу нарастания (growing phase), на которой блокировки на- лагаются. и фазу сжатия (shrinking phase), на которой блокировки снимаются. В ряде СУБД используется особая разновидность двухфазной блокировки. В этом случае блокировки налагаются на всем протяжении транзакции, но ни одна блокировка не освобождается, пока не будет выдана команда COMMIT (со- хранение) или ROLLBACK (откат, возврат к предыдущему состоянию). Эта страте- гия имеет более ограничительный характер, чем требуется для двухфазной бло- кировки, зато ее легче реализовать. Вообще говоря, рамки транзакции должны соответствовать границам пред- ставления базы данных, которое она обрабатывает. В двухфазной стратегии строки каждого отношения в представлении блокируются по мере необходимо- сти. Изменения производятся, но информация не записывается в базу данных, пока представление не будет полностью обработано. После этого изменения со- храняются в базе данных, и все блокировки снимаются. Рассмотрим ввод заказа с помощью представления ЗАКАЗ—ПОКУПАТЕЛЬ, бази- рующегося на таблицах ПОКУПАТЕЛЬ, ПРОДАВЕЦ и ЗАКАЗ. Чтобы гарантировать, что база данных не пострадает от аномалий, вызванных параллельной обработкой, транзакция ввода заказа налагает блокировки на таблицы ПОКУПАТЕЛЬ, ПРОДАВЕЦ и ЗАКАЗ по мере необходимости, производит все необходимые изменения в базе данных, а затем снимает блокировки. Взаимная блокировка Решая одну проблему, блокировка способна вызвать другую. Посмотрим, что может произойти, когда два пользователя хотят заказать две единицы товара. Предполо- жим, что пользователь А хочет заказать бумагу, и если он сможет получить ее, то хочет заказать и карандаши. Теперь предположим, что пользователь В хочет зака- зать карандаши, а если удастся достать их, то он закажет еще и бумагу. Возмож- ный порядок обработки показан на рис. 9.5. На этом рисунке пользователи А и В оказываются в ситуации, которая носит название взаимной блокировки (deadlock), или «смертельного объятия» (deadly embrace). Каждый из них ожидает освобождения ресурса, заблокированного дру- гим пользователем. Есть два распространенных способа решения этой проблемы: не допускать возникновения взаимных блокировок либо позволять нм возникать, азатем распутывать их. Предотвратить возникновение взаимной блокировки можно несколькими спо- собами Первый из них — заставлять пользователей блокировать все требуемые ресурсы (разу Если бы, например, пользователь А па рисунке с самого начала заблокировал и карандаши, и бумагу, взаимная блокировка не возникла бы. Второй пособ предотвратить взаимную блокировку — потребовать от всех прикладных ирсярамм блокировать ресурсы в одном и том же порядке. Даже если не все прн- л« еиия будут налаыть блокировки таким образом, вероятность возникновения взаимной блокировки сии инея хотя бы для тех приложений, которые используют Данную стратегию Эту философию можно распространить на организационные
406 Глава 9. Многопользовательские базы данных „пплнпя следующим образом: «При обработке строк таГ> стандарты программирован блоКируй сначала родителя, затем Пот<)м. лиц в связи родитель пото‘ вероятность взаимной блокировки, а может ка». Это, по крайней мере, сни и вовсе исключить ее. Пользователь А 1. Заблокировать бумагу. 2. Взять бумагу. 3. Заблокировать карандаши. Пользователь В 1. Заблокировать карандаши. 2. Взять карандаши. 3. Заблокировать бумагу. Порядок обработки на сервере базы данных 1. Заблокировать бумагу для А. 2. Заблокировать карандаши для В. 3. Обработать запрос А, обновить данные о бумаге. 4. Обработать запрос В, обновить данные о карандашах. 5. Перевести А в состояние ожидания (карандашей). 6. Перевести В в состояние ожидания (бумаги). “Блокировка** Рис. 9.5. Взаимная блокировка Почти в каждой СУБД имеются алгоритмы обнаружения взаимной блоки- ровки. Когда происходит взаимная блокировка, обычное решение состоит в том, чтобы отменить одну из транзакций, тем самым удалив из базы данных произве- денные ею изменения. Варианты того, как это делается в Oracle и SQL Server, вы увидите в следующих двух главах. Оптимистическая и пессимистическая блокировки Блокировки могут налагаться двумя основными стилями. При оптимистической мокировке (optimistic locking) делается предположение, что конфликта не про- изопдет Данные считываются, транзакция обрабатывается, производятся обнов- ления, а после этого проверяется, не возник ли конфликт. Если нет, транзакция завершается. Если да, транзакция повторяется до тех пор, пока не сможет успешно •завершиться, ри пессимистической блокировке (pessimistic locking) предполага шея, по конфликт обязательно произойдет. Сначала налагаются блокировки’ загем )Ра штывается транзакция, а после этого блокировки снимаются. листинги J.1 и 9.2 демонстрируют оба стиля наложения блокировок для КОТора„ Уменьшает количество карандашей в таблице ТОВАР на пять листинге изображена оптимистическая блокировка. Сначала ДаН ные считываются, и текущее количество карандашей сохраняется в переменной Й£- 1 4*
Управление параллельной обработкой 407 СтароеКоличество. Затем обрабатывается транзакция, и в предположении, что все прошло успешно, налагается блокировка на таблицу ТОВАР. Эта блокировка мо- жет затрагивать только строку карандашей, а может быть, глубина детализации будет и меньшей. В любом случае, выполняется SQL-оператор, обновляющий строку карандашей, с условием WHERE Количество = СтароеКоличество Если ника- кая другая транзакция не изменила атрибут Количество в строке карандашей, то- гда результат оператора UPDATE будет успешным. Если какая-то другая транзак- ция изменила значения атрибута Количество в строке карандашей, выполнение оператора UPDATE бущет неудачным, и транзакцию придется повторить. Листинг 9.1. Оптимистическая блокировка SELECT ТОВАР.Название. ТОВАР.Количество FROM ТОВАР WHERE ТОВАР.Название ='Карандаш' СтароеКоличество = ТОВАР.Количество Set НовоеКоличество = ТОВАР.Количество - 5 {обработка транзакции - если НовоеКоличество < 0, генерируется исключение и т д Если „се в порядке:} LOCK ТОВАР UPDATE ТОВАР SET ТОВАР.Количество = НовоеКоличество WHERE ТОВАР.Название = ’Карандаш AND ТОВАР.Количество = СтароеКоличество UNLOCK ТОВАР {проверяем, было ли обновление успешным если нет. повторяем транзакцию} В листинге 9.2 изображена логика той же самой транзакции, но с использова- нием пессимистической блокировки. Здесь еще до начала работы на таблицу ТОВАР налагается блокировка (с некоторой глубиной детализации). Затем счи- тываются значения, обрабатывается транзакция, выполняется оператор UPDATE, и таблица ТОВАР разблокируется. Преимущество оптимистической блокировки состоит в том, что она налагается только после обработки транзакции. Таким образом, блокировка удерживается в течение более короткого времени, чем при пессимистической стратегии. Если транзакция является сложной или клиент — медлительным (например, имеются задержки при передаче, клиент занят другой работой, пользователь уходит опить кофе или выключает компьютер, не выйдя из браузера), то блокировка будет удерживаться в течение значительно меньшего промежутка времени. Это преимущество будет еще более важно, если глубина детализации блокировки ма- ла — скажем, вся таблица ПРОДУКТ.
403 1 многопользо»—и » Листинг 9.2. Пессимистическая блокировка LOCK ТОВАР SELECT ТОВАР.Название. ТОВАР.Количество FROM ТОВАР WHERE ТОВАР.Название -‘Карандаш set НиоеКо»«чкт,о - ТОВАР Количество - 5 {овраоо-пя транзжии - если новоеКоличество < 0. гсчадега ис«л««.е , , , Если все в порядке;} UPDATE ТОВАР SET ТОВАР.Количество = НовоеКоличество WHERE ТОВАР.Название = 'Карандаш' UNLOCK ТОВАР {проверка на успешность обновления не требуется} Недостаток оптимистической блокировки заключается в том, что если со стро- кой карандашей происходит много активных действий, транзакцию, возможно, придется повторить многократно. Таким образом, транзакции, которые связаны с большой активностью по отношению к конкретной строке (например, покупка популярного товара), плохо приспособлены для оптимистической блокировки. Вообще говоря, Интернет — место дикое и непредсказуемое, и пользователи часто предпринимают неожиданные действия вроде прерывания транзакций на середине. Поэтому, если только пользователи Интернета не были предваритель- но отобраны (например, путем записи в план интерактивных покупок), оптими- стическая блокировка являет собой более удачный выбор. В интрасетях, однако, принять решение сложнее. Возможно, оптимистическая блокировка и здесь окажется предпочтительнее, если нет какой-либо характеристики приложения, которая вызывала бы значительную активность по отношению к отдельным строкам, или если требования приложения почему-либо делают повторную об- работку транзакций особенно нежелательной. °б^ВЛеНИ|е, *аРаКТеристи'< блокировки ный; некоторые решения о₽типяу11е параллельной обработкой - предмет слож- тодом проб и ошибок. По этой й Стратегиях блокировки должны делаться же- ланных обычно не налагают явш' Д^-У™м пРичинам прикладные программы базы ки транзакций, а затем объявляю? кака™^’ ВМеСТ° ЭТОГ° °"И Указыва“1^' I аким образом, если поведение пп' г ° ^°да поведеП|,е им требуется от СУ БД, мости переписывать приложение локиР0Вке нужно изменить, то нет необходи- транзакции. Вместо этого просто меГ° налагать блокировки на других участках В листинге 9.3 изображена тпяи- *Яется объявление характеристик блокировки- чены с помощью операторов BFGTN tpakif С каРандашамп, рамки которой обозна* TRANSACTION. Рамки транзакции ” JRANSACTI°N- COMMIT TRANSACTION и ROLLBACK ю та информация, которая жизненно несю
Управление параллельной обработкой 409 ходима СУБД, чтобы реализовывать различные стратегии блокировки. Если разработчик объявит теперь (через системный параметр или каким-либо дру- гим способом), что ему нужна оптимистическая блокировка, СУБД неявным образом наложит блокировки, соответствующие этой стратегии, в правильном месте. Если после этого разработчик сменит тактику и запросит пессимистиче- скую блокировку, СУБД неявно наложит свои блокировки в другом месте. Листинг 9.3. Указание рамок транзакции BEGIN TRANSACTION: SELECT ТОВАР.Название. ТОВАР.Количество FROM ТОВАР WHERE ТОВАР Название ='Карандаш' СтароеКоличество = ТОВАР.Количество Set НовоеКоличество = ТОВАР.Количество - 5 UPDATE ТОВАР SET ТОВАР Количество = НовоеКоличество WHERE ТОВАР.Название = 'Карандаш' {продолжение обработки транзакции}... IF транзакция выполнена успешно THEN COMMIT TRANSACTION ELSE ROLLBACK TRANSACTION END IF Далее выполняются другие действия, не входящие в эту транзакцию... Согласованность транзакций Иногда встречается аббревиатура ACID, относящаяся к транзакциям. Опа рас- шифровывается так: «atomicity, consistency, isolation, durability», что в переводе с английского означает «атомарность, согласованность, изолированность и устой- чивость». Таким образом, ACID-транзакция — это транзакция, обладающая все- ми перечисленными свойствами. Как вы только что узнали, атомарная тран- закция гто такая транзакция, в которой либо выполняются все содержащиеся В ней действия с базой данных, либо не выполняется ни одно из них. Устойчивая транзакция — это транзакция, в которой все сохраненные изменения остаются а базе данных. СУБД не будет удалять эти н щенения даже в случае ошибки. Если транзакция устойчивая, СУБД при необходимости предоставит возможность для восстановления изменений, произведенных всеми выполненными действиями. Термины согласованная п изолированная не являются столь же определенны- ми, как термины атомарная и устойчивая. Рассмотрим следующий обновля- ющий SQL оператор
410 Глава 9. Многопользовательские базы данных UPDATE SET WHERE КЛИЕНТ КодРегиона = '425' Индекс = '9В050' Предположим, что в таблице КЛИЕНТ имеется 500 000 ст,юк и в 50V и, них», рпбут Индекс имеет значение «98050». Чтобы найти все эти 500 строк, СУБД по- требуется некоторое время. Будет ли на протяжении этого времени разрешу другим транзакциям обновлять поля КодРегиона и Индекс таблицы КЛИЕНТ? Если SQL-оператор является согласованным, такие обновления будут запрещены Об- новление будет применено к набору строк в том виде, в каком они существовали в момент запуска SQL-оператора. Такая согласованность называется согласован- ностью на уровне оператора (statement level consistency). Теперь рассмотрим транзакцию, которая содержит два оператора обновления: BEGIN TRANSACTION UPDATE КЛИЕНТ SET КодРегиона = '425' WHERE Индекс = '98050' (прочие действия этой транзакции} UPDATE КЛИЕНТ SET Скидка = 0.05 ИНЕЛЕКодРегиона = '425' (прочие действия этой транзакции} COMMIT TRANSACTION Что в данном контексте означает термин согласованность? Согласованность на уровне оператора означает, что каждый из двух операторов обрабатывает стро- ки согласованно, но в интервале между ними указанные строки могут изменять- ся другими пользователями. Согласованность на уровне транзакции (transaction level consistency) означает, что все строки, затронутые любым из SQL-операто- ров, защищены от изменений на протяжении всей транзакции. Обратите внимание: согласованность на уровне транзакции является настоль- ко сильным средством, что в некоторых его реализациях транзакция не будет видеть свои же собственные изменения. В данном примере второй оператор не oy.iei видеть строк, измененных первым оператором. аким образом, koi да вы слышите термин согласованность, следуют выяснить, <ои тип со1ласоваиности имеется в виду. Следует также знать и о ловушке, ко В Се^е соглас°ванность на уровне транзакции. пнм cm п сложиои является ситуация с термином изолированность. Рассмот- рим его в следующем разделе. 7 Уровень изоляции транзакции ме меД. ““™™1’й при параллельной обработке. Те» Одной из таких проблем является ’ которые 01111 предотвратить не в состоянии- акцией записи, которая изменена *грязиое>:> чтение (dirty read) - чтение транз- произойти, например, когда однч -т-> ° СЩе Не Записа11а в базу данных. Это мо»е незавершенной транзакцией а чтя *!3акция считывает строку, измененную ДРУ14” ’ й ЭТа др*гая транзакция впоследствии отменяете*
Управление параллельной обработкой_____411 Невоспроизводимое чтение (nonrepeatable reads) — это ситуация, когда при повторном чтении данных, уже считанных ранее, транзакция обнаруживает мо- дификации или удаления, вызванные другой завершенной транзакцией. Нако- нец, фантомное чтение (phantom reads) — это ситуация, когда при повторном чтении данных транзакция обнаруживает новые строки, вставленные другой за- вершенной транзакцией после предыдущего чтения. В стандарте SQL 1992 года определены четыре уровня изоляции транзакций (transaction isolation levels), которые определяют допустимость перечисленных выше проблем. Цель состоит в том, чтобы разработчик прикладной программы мог указать желаемый уровень изоляции, а СУБД осуществляла управление блокировками в соответствии с этим указанием. Как можно видеть из табл. 9.1, уровень изоляции под названием «незавершен- ное чтение» (read uncommitted) допускает «грязное» чтение, невоспроизводимое уГВИЕг |(СЭВХО1! яи чтение и фантомное чтение. Уровень изоляции «завершенное чтение» (read committed) предотвращает «грязное» чтение. Уровень изоляции «воспроизводи- мое чтение» (repeatable reads) предотвращает «грязное» чтение и невоспроизво- димое чтение. Уровень изоляции «сериализуемость» (serializable) не допускает возникновения ни одной из этих трех проблем. Таблица 9.1. Уровни изоляции транзакций Тип проблемы Незавершенное чтение Уровень изоляции Сериализуемость Завершенное чтение Воспроизводимое чтение «Г рязное» чтение Возможно Невозможно Невозможно Невозможно Невоспроиз- водимое Возможно Возможно Невозможно Невозможно чтение «Фантомное» чтение Возможно Возможно Возможно Невозможно Вообще говоря, чем большие ограничения предусматривает уровень изоля- ции, тем меньше пропускная способность базы данных, хотя многое зависит от нагрузки и от того, как написаны прикладные программы. Кроме того, не всеми СУБД поддерживаются все четыре уровня изоляции. Могут также различаться способы поддержки и степень нагрузки, которую они возлагают на программи- ста. О том, как уровни изоляциц поддерживаются в Oracle и SQL Server, вы узнаете из следующих двух глав. Тип курсора Курсор это указателе па набор строк. Обычно курсоры определяются с по- мощью операторов SELECT. Например, оператор DECLARE CURSOR TransCursor AS SELECT ROM WHERE. TRANSACTION PurchdsePfTce > ’10000’
412 Главе! 9. Многопользовательские базы данных нпк-м TransCursor, действующий на наборе строк, определяет курсор под иазгиш п 1адпая про)|>амма открывает курсор исчи занном в операторе StLtLi по» цт0 О11 «указывает на первую строку» тывает первую строку, о кур I псскодьК() курсорОв - как последовательно, так Транзакция может гкр^ * же та6лнце или ее SQL-предстадле. п одновременно, крои • ора Поскольку курсоры потребляют значи „ни можно открыть дв ™ открытие нескольких курсоров, к примеру, Мя тельное каличест < - оказаться накладным в отношении па- °™ ” — "отре6”"” •«*- "6о” г ку к»га..« - использовать курсоры с ограниченными возможно. ™случаях когда полнофункциональный курсор не требуется. В табл 9 2 перечислены четыре типа курсоров, используемых в среде Win- dows (В других системах типы курсоров аналогичны.) Простейший тип курсо- ра -последовательный (forward only cursor). Он позволяет приложению пере- двигаться по набору строк только вперед. Изменения, произведенные другими курсорами в данной транзакции, а также другими транзакциями, будут видны только в том случае, если затронутые ими строки находятся впереди курсора. Таблица 9.2. Типы курсоров Тип курсора Описание Свойства Последова- Приложение может тельный перебирать набор записей только в одном направлении — вперед Статический Приложение видит данные в том состоянии, в каком они были на момент открытия курсора Ключевой При открытии курсора для каждой строки набора записей сохраняется значение первичного ключа. Обращаясь к строке, приложение использует этот ключ для получения текущего значения строки Динамиче- Приложение видит ский любые изменения, вызванные любым ИСТОЧНИКОМ Изменения, производимые другими курсорами в данной транзакции или другими транзакциями, будут видимы только в том случае, если они затрагивают строки, находящиеся перед курсором Изменения, производимые данным курсором, являются видимыми. Изменения, инициированные другими источниками, не видны. Перемещение курсора возможно в обоих направлениях Обновления, вызванные любым источником, являются видимыми. Вставки из других источников не видны (в наборе записей для них нет ключей). Строки, вставляемые данным курсором, добавляются в конец набора записей. Изменения, вызванные любым источником, являются видимыми. Изменения в порядке строк не видны. Если выставлен уровень изоляции “незавершенное чтение» (то есть допускается “грязное» чтение), то несохраненные обновления и удаления являются видимыми; в противном случае видны только сохраненные обновления и удаления Все вставки, обновления, удаления и изменения в порядке записей являются видимыми. Если выставлен уровень изоляции «незавершенное чтение» (то есть допускается «грязное» чтение), то несохраненные изменения являются видимыми. В противном случае видны только сохраненные изменения ~~
Безопасность базы данных 413 Остальные три типа курсоров называются двунаправленными курсорами (scroll able cursors), поскольку приложение может передвигат ься по набору записей как вперед, гак и назад. Статический курсор (static cuisor) обрабатывает «снимок» отношения, сделанный в момент открытия курсора. Изменения, сделанные таким курсором, являются видимыми для самого курсора; изменения из любых других источников являются невидимыми. Ключевые курсоры (keyset cursors) соединяют в себе некоторые свойства ста- тических и динамических курсоров. При открытии такого курсора для каждой строки в наборе записей сохраняется значение первичного ключа. Когда прило- жение устанавливает курсор па некоторую строку, СУБД по ключу считывает текущее значение этой строки. Если приложение собирается обновись строку, которая была удалена другим курсором в этой же трапзакции либо другой граи т акцией, СУБД создает новую строку со старым значением ключа и помещает в псе обновленные значения (если, конечно, заполнены все требуемые поля). Новые строки, вставленные другими курсорами дайной транзакции или другими транзакциями, невидимы для ключевого курсора. Данный курсор видит лишь сохраненные обновления и удаления, если только уровень изоляции транзакции не допускает «грязного» чтения Динамический курсор (dynamic cursor) — это полнофункциональный курсор. Все вставки, обновления, удаления и изменения в порядке строк являются види- мыми для динамического курсора. Как и в случае с ключевыми курсорами, если уровень изоляции транзакции нс допускает «грязного» чтения, курсор может ви- деть только сохраненные изменения. Количество потребляемых ресурсов и необходимый объем обработки зависят от тина курсора. В общем случае, чем ниже находится тип курсора в табл. 9.2, тем выше расходы Поэтому, чтобы увеличить производительность СУБД, разра богчик приложения должен создавать курсоры, имеющие ровно столько возмож- ностей, сколько требуется для выполнения поставленной задачи Также весьма важно представлять, каким образом курсоры реализуются в конкретной СУБД и где они размещаются, — па сервере или па клиенте. Иногда бывает выгоднее иметь динамический курсор на клиенте, чем статический — на сервере. Никакое общее правило сформулировать нельзя, поскольку производи гельпость зависит от способа реализации курсора в СУБД и требований приложения. Предостережение: если вы нс укажете уровень изоляции транзакции или тип курсора, СУБД будет использовать уровень или тип, предусмотренный по умол- чанию. Заданные по умолчанию параметры могут идеально подходить для ваше- го приложения, а могут оказаться и совершенно непригодными. Таким образом, хотя эти вопросы можно игнорировать, последст вий избежать все равно не удаст- ся. Изучите возможности вашей СУБД и используйте их рационально. Безопасность базы данных Злщита безопасности базы данных заключается в том, что право выполнять не- которые действия дается только определенным пользователям и в определен- ное время. Эта цель труднодостижима, н чтобы хоть в какой-то степени к пей
414 Глава9. Многопользовательские базыданных - г кпмпнла разработчиков базы дайны? должна и 'адии спред, приблизиться оекту уста11овпть для всех пользователей правд и обй занности по обработке (processing rights and responsibilities). Реализация эц» тоебований безопасности может обеспечиваться сооп.егстпую.цими возмог «СУБД, а при их недостаточности - логикой прикладных программ. Права и обязанности по обработке Рассмотрим для примера потребности галереи View Ridge, описанной в главе 7 У базы данных галереи есть три типа пользователей: продавцы, менеджеры и сис- темные администраторы. Продавцы могут регистрировать новых покупателей и вводить данные транзакций, изменять данные покупателей и запрашивать любые данные. Они не могут ин вводить данные о новых художниках или произ- ведениях, ни удалять данные. Менеджеры имеют все права, которые предоставлены продавцам, но помимо того, им разрешено вводить данные о новых художниках и произведениях, а так- же модифицировать данные транзакций. Хотя менеджеры имеют право удалять данные, в данном приложении им не дается таких полномочий. Это сделано для того, чтобы исключить возможность случайной потери данных. Системный администратор может предоставлять права по обработке другим пользователям и менять структуру элементов базы данных — таблиц, индексов, хранимых процедур и т. п. Эти требования сведены в табл. 9.3. Таблица 9.3. Права и обязанности по обработке в галерее View Ridge CUSTOMER TRANSACTION WORK ARTIST Продавцы Вставка, Изменение, Запрос Запрос изменение, запрос запрос Менеджеры Вставка, Вставка, Вставка, Вставка, изменение, изменение, изменение, изменение, Системный администратор Вставка, изменение, запрос Вставка, запрос Вставка, запрос Вставка, запрос, удаление, предоставление прав, изменение, запрос, удаление, предоставление прав, модификация структуры изменение, запрос, удаление, п ре достав л ен и е изменение, запрос, удаление, предоставление — модификация структуры прав, модификация структуры прав, модификация структуры __ личным типам, или гттплм ™>„ДаЮТСЯ Не пндпвВДуалы1ым пользователям, а Ра3 но нс обязательным. Можно б^ова^1елей (user groups). Это является обычны5*’ имени Бенджамин Франклин „.xff Ы указать> например, что пользователь п также внимание, что при работе •Т Определенные права по обработке. ОбрапП распределения пользователей m г Группами необходимо иметь какой-то сп°с по имени Мэри Смит должен бы₽УППаМ' Когда в систему входит пользовать , Должен быть некоторый способ, позволяющий опр<^
Безопасность базы данных 415 лить, к какой группе или группам относится данный пользователь. Мы обсудим это подробнее в следующем разделе. По ходу изложения мы использовали выражение «права и обязанности ио обра- ботке». Оно подразумевает, что любое право влечет за собой некоторую обязан- ность. Если, например, системный администратор удаляет данные транзакций, он отвечает за то, чтобы эти удаления не оказали неблагоприятного воздействия на функционирование галереи, целостность данных се бухгалтерии и т. д. Обязанности по обработке не могут выполняться СУБД или приложениями базы данных. Эти обязанности возлагаются на пользователей и разъясняются им при обучении работе с системой. Данная тема относится к курсу системной разра- ботки, и мы не будем здесь в нее углубляться. Повторим лишь, что любые права всегда сопровождаются обязанностями. Эти обязанности должны документаль- но фиксироваться и выполняться. В соответствии с врезкой «Функции администратора базы данных», в задачи администратора базы данных входит управление правами и обязанностями по обработке. Это подразумевает, что права и обязанности могут меняться с течени- ем времени. В ходе работы с базой данных по мере внесения изменений в прило- жения и в структуру СУБД возникает потребность во введении новых или изме- нении существующих прав и обязанностей. Администратор базы данных играет ведущую роль в обсуждении и реализации таких изменений. Когда права по обработке определены, необходимо их реализовать. Эта зада- ча может быть возложена на различные элементы: операционную систему, сеть, веб-сервер, СУБД или приложение. В последующих двух разделах мы рассмот- рим реализацию прав по обработке средствами СУБД и приложения. Описание остальных возможностей выходит за рамки данной книги. Обеспечение безопасности средствами СУБД Терминология, возможности и функции безопасности СУБД варьируются от продукта к продукту. В принципе, во всех СУБД существует возможность огра- ничить выполнение некоторых действий определенным временем и кругом поль- зователей. Общая модель безопасности СУБД представлена на рис. 9.8. Пользо- вателю может быть назначена одна или несколько ролей, а каждая роль может принадлежать одному или многим пользователям. Как пользователи, так и роли могут иметь много различных полномочий. С каждым объектом (в широком смысле этого слова) связаны определенные полномочия. Каждое полномочие от- носится к одному пользователю или группе и одному объекту. Когда пользователь входит в базу данных, СУБД ограничивает его действия пол- номочиями, определенными индивидуально для данного пользователя, а также для роли, назначенной ему. Определить, является ли пользователь тем, за кого он себя выдает, - задача, вообще говоря, сложная. Во всех коммерческих СУБД ис- пользуется Toi или иной вариант парольной защиты, несмотря на то, что такой метод обеспечения безопасное i и можно легко обой гн, если пользователи небреж- но относятся к СВОИМ личным идеи I пфикаторам.
416 Глава 9. Многопользовательские базы данных Пользователь Полномочие Бухгалтерия Кассиры Менеджеры Неизвестная публика Рис. 9.6. Модель безопасности СУБД Ричард Энт Элеонор By Джеймс Джонсон Бухгалтерия может обновлять таблицу CUSTOMER Элеонор By может запускать приложение MonthEnd Джеймс Джонсон может менять все таблицы Объект Таблица Представление Процедура Приложение Как правило, пользователи самостоятельно вводят свое имя и пароль, а в не- которых приложениях имя пользователя и пароль вводятся системой от лица пользователя. Например, Windows 2000 может непосредственно передать имя пользователя и пароль для входа в систему СУБД SQL Server. В других случаях имя пользователя и пароль предоставляются прикладной программой. В Интернет-приложениях обычно определяется группа под названием вроде «Unknown Public» (неизвестная публика), и в эту группу записываются анонимные пользователи, входящие в систему. Таким образом компании типа Dell Computer избегают необходимости вводить каждого пользователя в систему под его соб- ственным именем и паролем. Модели систем безопасности, используемые в Oracle и SQL Server, будут об- суждаться в главах 10 и 11 соответственно. Принципы обеспечения безопасности СУБД Во-первых СУБД псрг111еПИЯ ^езопаСиости баз данных перечислены во врезке, защите £оХы п“а Раб°таТЬ ПОД Защитой брандмауэра. При Гтом взломан. Такая стп1трги« 1 ниР°ваться в предположении, что брандмауэр был даже в том случае если бЛ°ЗП°ЛИТ защитить СУБД, базу данных и приложения Добавляют в свои продукты Д’ акие Как Oracle и Microsoft, постоянно и снижающие уязвимост ь >Пп°ПЫе возможнос™, повышающие уровень защиты Дует регулярно посещать caft3™^ °РганизацИям> использующим СУБД, сле- обповлеиий. Все обновления ка Пр0ИЗВ0дителей в поисках исправлений или как можно скорее. ’ каса,011птеся безопасности, следует устанавливать бочих СУБлТ(1’уИКЦИИ’ К0Т0Рые не требуются для работы приложений, в ра с СУБУЛ,™, * <>6ХОДИМО удалить ^и заблокировать. Например, если соединение Д осуществляется по протоколу TCP/IP связь с использованием ДРУпЬ можво'ХшХ,3абЛ0КИрова-. Это уменьшитХичество путей, по которы" можно сове ршить несанкционированные действия с СУБД Кроме того, со всем" СУБД устанавливаются системные хранимые нроцедуры^предоставляюшие Р*3'
Безопасность базы данных 417 личные сервисы, — запуск командного файла, модификацию системного реестра, отправку сообщений по электронной почте и т. д. Все такие процедуры, которые не нужны для функционирования приложений, необходимо удалить. Если все ользователи СУБД известны, стандартные и гостевые учетные записи также следу- ет удалить. Наконец, если это не противоречит системным требованиям, пользова- телям никогда не следует разрешать работать с СУБД в интерактивном режиме. Доступ к СУБД всегда должен производиться через соответствующее приложение. ОБЩИЕ ПРИНЦИПЫ ОБЕСПЕЧЕНИЯ БЕЗОПАСНОСТИ СУБД --------------------------------- ♦ Поставить СУБД под защиту брандмауэра, но планировать меры безопасности в пред- положении, что брандмауэр был обойден. ♦ Своевременно устанавливать пакеты исправлений операционной системы и СУБД. ♦ Использовать как можно меньше функций: • свести к минимуму число поддерживаемых сетевых протоколов; • удалить системные хранимые процедуры, которые не нужны или не используются; • по возможности запретить вход в систему по умолчанию и с гостевыми правами; • не позволять пользователям работать с СУБД в интерактивном режиме (если в этом нет насущной необходимости). ♦ Защита компьютера, на котором работает СУБД: • не позволять никому из пользователей работать за компьютером, на котором ра- ботает СУБД; • компьютер, на котором располагается СУБД, должен находиться в помещении, запираемом на замок; • все визиты в помещение, где находится компьютер с работающей СУБД, должны записываться в журнал. ♦ Управление учетными записями и паролями: • использовать для СУБД учетную запись операционной системы с наименьшими возможными привилегиями; • защищать учетные записи базы данных сильными паролями; • отслеживать неудачные попытки входа в систему; • регулярно проверять членство в группах и роли; • проверять учетные записи без паролей; • назначать учетным записями наименьшие возможные привилегии; • ограничивать привилегии учетной записи администратора базы данных. ♦ Планирование: • разработать план защитных мер для предотвращения и обнаружения проблем в системе безопасности; • разработать процедуры на случай взлома системы и следовать им. Физический доступ к компьютеру, на котором работает СУБД, также должен быть ограничен. Никому, кроме назначенных администраторов базы данных, не следует позволять работать за клавиатурой компьютера, па котором располагает- ся СУБД. Этот компьютер должен находиться в помещении, закрываемом на замок, и доступ к этому помещению должен контролироваться. Все посещения должны записываться в специальный журнал. Учетные записи и пароли следует назначать внимательно и постоянно кон- тролировать их состояние. Учетная запись, под которой работает СУБД, должна
,1В глаза 9. Мнотопользоаатольетие базм данных .......М объемом системных привилегий При таком по*, обладать как можно меч > контроль над СУБД, его полномочия ходе, даже если =‘"пн» «Лее р........ будут данном локальном ко > 1 уГд Д()ЛЖ11ы бы и, защищены сильными тит^ т Т >ГХ”Хт..о”«“—“!«»’ .will. Такне паро регистра, цифры и специальные непечатаемые комби>ш. "ажагоп **) Лминистратор базы данных должен регулярно проверять учетные записи, назначенные группам и ролям, чтобы убедиться, что все учетные записи и роли известны их создание было санкционированным, а полномочия являются аде- кватными Кроме того, администратор должен выявлять учетные записи, незащи- щенные паролем, и требовать от их пользователей защитить эти учетные записи сильными паролями. Следует также соблюдать общее правило, согласно которо- му учетным записям присваиваются наименьшие возможные привилегии. Даже привилегии администратора базы данных должны быть ограничены. Обычно это означает, что администратор базы данных не имеет полномочий обрабатывать данные пользователей. Разумеется, администратор базы данных всегда может дать себе такие полномочия, но такое отклонение от принятой по умолчанию политики можно отследить. Не будь этого ограничения, админи- стратор базы данных мог бы вносить несанкционированные изменения в дан- ные, не рискуя быть обнаруженным. Наконец, администратор базы данных должен принимать участие в планиро- вании защитных мер. Следует разработать процедуры, позволяющие предотвра- щать и обнаруживать проблемы в системе безопасности, а также процедуры на случай взлома системы. Этим процедурам необходимо неуклонно следовать. Эпидемия сетевого червя Slammer в 2003 году продемонстрировала важность обеспечения должной защиты баз данных. Если бы все организации следова- ли принципам, перечисленным во врезке «Общие принципы обеспечения без- опас пости СУБД», они были бы защищены от этой атаки. Соблюдайте эти прин- ципы! ?^ечение безопасности средствами приложения защитных мео что ^Гас^е или Server, предусматривают широкую гамму жению требуются Меры по своеи природе являются весьма общими. Если прпло- “ ьнеЗжет ™ЦИфИЧеСКИе меры ^опасности, например, правило «Полы сотрудника в которых°СМагривать строки таблицы или соединения таблиц, »мЯ „„ еде”ат° ОТ егосо6™1мого.>, то СУБД будет бееел».» часто 0&сп«ишта“ комамтёром”’™ ’2' Иитсрнет-лрп.^^ челне безопасности сервером означает Р“™л0"" „^е ж должны передаваться по сети. ' важные Для безопасности дан»»
Безопасность базы данных 419 Чтобы лучше понять это, представим себе приложение, в котором при нажа- тии пользователем определенной кнопки на странице браузера веб-серверу, а за- тем и СУБД посылается следующий запрос: SELECT * FROM СОТРУДНИК Этот оператор, разумеется, возвратит все строки таблицы СОТРУДНИК. Если же требования безопасности приложения ограничивают доступ сотрудников к дан- ным только их личной информацией, то веб-сервер может добавить к этому за- просу предложение WHERE, как показано ниже: SELECT * FROM СОТРУДНИК WHERE СОТРУДНИК.Имя = *<«=SESSION("ИмяСотрудника")Х>’ Как вы узнаете из главы 12, такое выражение заставит веб-сервер указать в предложении WHERE имя данного сотрудника. Для пользователя, вошедшего в систему под именем Бенджамин Франклин, результирующий SQL-оператор будет выглядеть следующим образом: SELECT * FRO! СОТРУДНИК WHERE СОТРУДНИК.Имя = 'Бенджамин Франклин' Поскольку имя вставляется программой, работающей на веб-сервере, пользо- ватель браузера не знает, что это происходит, а если бы даже и знал, то не смог бы вмешаться в этот процесс. Такая обработка может производиться на веб-сервере, как только что было пока- зано, а может выполняться и самими прикладными программами либо встраивать- ся в хранимые процедуры или триггеры и запускаться СУБД при необходимости. Эту идею можно развить, организовав хранение информации, относящейся к безопасности, в специализированной базе данных, доступ к которой могут осу- ществлять веб-сервер или хранимые процедуры и триггеры. Каждому пользова- тельскому идентификатору в такой базе данных может быть сопоставлен пере- чень значений, которые должны вставляться в предложение WHERE при запросе данных пользователем. Пусть, например, сотрудники отдела кадров могут запра- шивать из базы данных не только свою личную информацию, но и данные о дру- гих сотрудниках. Чтобы организовать такой доступ, можно записать в специали- зированную базу данных соответствующие предикаты для предложения WHERE, Которые будут считываться прикладной программой и в нужный момент присо- единяться к SQL-операторам SELECT. Есть мною друтих способов расширения возможностей СУБД по обеспече- нию безопасности за счет приложения. Однако в первую очередь следует за- действовать СИ' тему безопасности СУБД. Только если ее функций оказывается недостаточно, стоит дополнять их ла счет прикладных программ. Чем ниже уровень, на котором идет обеспечение безопасноетн. гем меньше возможностей Для несанкционированною вторжения Кроме того, система безопасности СУБД работает быстрее, ее использование приводит к меньшим затратам н, возможно. Лает лучшие результаты, чем разработка собственной системы.
420 Глава9 Многопользовательскиебазыданных Атака со вставкой SQL-кода Всякий раз, когда для модификации SQL-оиераторон ит пользуются Данные. w денные пользователем, возникает риск атаки, и местной как атака со SQL-кода (SQL injection attack). Например, если в прсдмдупк м разделе имя со грудника (столбец Name) получено не падежным способом (например, от онера unoHHoii системы), а из веб-формы, есть вероятность, что пользователь сможет вставить в запрос свой SQL-код. Предположим, что пользователи вводят свои имена в текстовое поле форма на веб-странице. Что произойдет, если пользователь в качестве своего имени введет в это поле значение 'Бенджамин Франклин' OR TRUE? SQL-оператор, генери- руемый приложением, примет тогда следующий вид: SELECT * FROM СОТРУДНИК WHERE СОТРУДНИК.Имя = 'Бенджамин Франклин' OR TRUE; Разумеется, значение TRUE является истинным для каждой строки, поэтому данный запрос возвратит все строки таблицы СОТРУДНИК! Поэтому всегда, когда введенные пользователем данные используются для модификации SQL-оператора, эти данные необходимо тщательно проверять и при необходимости исправлять, чтобы иметь гарантию корректности да,иных и от- сутствия в них непредусмотренного SQL-кода. Восстановление баз данных Компьютерные системы порою дают сбои. Причин тому множество: поломки ап- паратного обеспечения, дефекты в программах, неточности в описаниях ручных процедур и ошибочные человеческие действия. Все перечисленные виды ошиоок могут возникать и возникают в приложениях баз данных. Поскольку база данных совместно используется множеством людей и зачастую является ключевым элемен- том функционирования организации, важно как можно быстрее ее восстановить. Это ставит перед нами несколько задач. Во-первых, с точки зрения бизнеса, работа должна продолжаться. Например, выполнение заказов, осуществление финансовых транзакций и составление упаковочных листов должно быть орга низовано вручную. Позже, когда приложение базы данных вновь заработает, можно будет ввести новые данные. Во-вторых, персонал, ответственный за компь- мо?ноУбпиж7еМУ’ Д°ЛЖеН восстановить ее как можно быстрее и привести как должны 3 ™Кчт°МУ С°СТОЯНИЮ- котоРое было до сбоя. В-третьих, пользователя вать Возможно ° Г, е уетСЯ сделать> когда система вновь начнет функнпоннР® Z УзнатьЖ ; ^РИДеТСЯ П0ПТ°РН0 ВВеС™ какис-т° да-ные, и пользователям нужно знать, насколько далеко им „ в,иы "Тти 6,“' нереалисти шое предположение), то синхронизация и планирование обр^^
Восстановление баз данных 421 слишком сложны, чтобы состояние системы можно было воспроизвести в точно- сти. Чтобы продолжить работу точно с того места, где она была прервана, опера- ционной системе потребовалось бы громадное количество избыточных данных и времени на их обработку. Невозможно прокрутить время назад и вернуть все электроны в те же конфигурации, в которых они находились на момент возникно- вения ошибки. Возможны два подхода к восстановлению базы данных: повторная обработка и откат-накат. Восстановление путем повторной обработки Поскольку обработка не может быть возобновлена точно с того места, где она бы- ла прервана, следующая возможность — отойти назад до некоторой известной точки и возобновить обработку с нее. Простейший способ такого восстановле- ния — это периодически делать копию базы данных (называемую снимком базы данных (database save)) и хранить записи обо всех транзакциях, которые были выполнены со времени последнего копирования. Затем при возникновении сбоя персонал может восстановить базу данных по ее снимку и заново произвести все транзакции. К сожалению, эта простая стратегия, как правило, нереализуема. Во-первых, повторное выполнение транзакций занимает столько же времени, сколько оно заняло до возникновения ошибки. Если компьютер имеет напряженный график работы, система может так никогда и не «догнать» свое исходное состояние. Во-вторых, при параллельной обработке транзакций события происходят асинхронно. Небольшие вариации в действиях человека — например, когда поль- зователь чуть медленнее вставляет дискету или читает сообщение электронной почты, прежде чем ответить на запрос приложения, — могут изменить порядок обработки параллельных транзакций. Поэтому может случиться, что хотя из- начально последний билет на данный рейс достался клиенту А, при повторной обработке его получит клиент В. В связи с этим повторная обработка обычно не является реально осуществимой формой восстановления от сбоев в системах па- раллельной обработки. Восстановление через откат-накат Второй подход к восстановлению заключается в том, чтобы периодически делать копии (снимки) базы данных и вести журнал всех изменений, произведенных транзакциями в базе данных со времени последнего копирования. В этом случае, когда происходит сбой, можно использовать один из двух методов. При первом методе, который называется накат (rollforward), база данных восстанавливается ДО сохраненного состояния, после чего выполняются все правильные транзакции. (Мы не обрабатываем транзакции повторно, поскольку прикладные программы не участвуют в процессе восстановления. Все, что мы делаем, — это производим изменения в базе данных согласно записям в журнале ) Второй метод называется откат (rollback). При этом методе мы отменяем изме- нения, прои тнедеипыс в базе данных ошибочными или частично выполненными
422 Глава 9. Многопользовательские базыданных „ Затем повторно запускаются правильные транзакции, котор^ транзакциями, оатем ш i ения сбоя. выполнялись в м0МС,^^“"'™ я журнала (log) результатов транзакций Эм Оба эти метода требуюи.. проИзПедеииых с данными, в хронологий- журнал ^Р’^Х’чем транзакция будет выполнена, ее необходимо записать ском порядке. Прежде I пр(Ж30Йдет в интервале между зацИСМ) в журнал, тогда, есл р непием> то в хуДШем случае у нас будет иметь- транзакции в журнf. закцИИ. Если, напротив, транзакции сначала ся запись о записываются в журнал, то возможен нежелательный “Х"т” № да изменения в базе данных произведены, но запись об этих измене- X "Хствует. В такой ситуации неискушенный пользователь может повторно ввести транзакцию, которая уже выполнена. В случае сбоя журнал используется как для отмены, так и для повторного выполнения транзакций (рис. 9.7). Чтобы была возможна отмена транзакций, журнал должен содержать копию каждой записи (или страницы) базы данных, сделанную перед ее изменением. Такие записи называются исходными образами (before-images). Отмена транзакции производится путем последовательной запи- си в базу данных исходных образов всех произведенных ею изменений. Базе данных с изменениями База данных без изменений Исходные обрезы Рис. 9.7. Откат и накат транзакций- a ° -«змХиптгХьмХт( содержать копию квдойХкп (™ вь“1олнен,|е транзакций, журнал ДО>»» ее изменения. Такие записи пят ” страиицы) базы Данных, сделанную пос. Транзакция выполняется повторно п^ем п с °бра3аМЫ 1 ут ем последовательной записи в базу ЛЛ
Восстановление баз данных 423 ных конечных образов всех произведенных ею изменений. Пример фрагмента журнала транзакций представлен на рис. 9.8, б. В этом примере каждая транзакция имеет уникальное имя для целей иденти- фикации. Все образы каждой транзакции связаны между собой указателями. Один указатель указывает на предыдущее изменение, сделанное данной транз- акцией (обратный указатель), а другой — на следующее изменение, сделанное данной транзакцией (прямой указатель). Нуль в поле указателя означает конец списка. Подсистема восстановления СУБД использует эти указатели для нахож- дения всех записей, относящихся к данной транзакции На рис. 9.8, а приведен пример связи между запи ми в журнале. ---------------- Идентификатор транзакции Тип операции Указатель назад Объект Указатель вперед Исходный образ Время Конечный образ Относительный номер записи 1 2 3 4 5 6 7 8 9 10 ОТ1 0 2 11:42 СТАРТ ОТ1 1 4 11:43 ИЗМЕНИТЬ КЛИЕНТ 100 (старое значение) (новое значение) ОТ2 0 8 11:46 СТАРТ ОТ1 2 5 11:47 ИЗМЕНИТЬ ПРОДАВЕЦ АА (старое значение) (новое значение) ОТ1 4 7 11:47 ВСТАВИТЬ ЗАКАЗ 11 (значение) СТ1 0 9 11:48 СТАРТ ОТ1 5 0 11:49 СОХРАНИТЬ ОТ2 3 0 11:50 СОХРАНИТЬ СТ1 6 10 11:51 ИЗМЕНИТЬ ПРОДАВЕЦ ВВ (старое значение) (новое значение) СТ1 9 0 11:51 СОХРАНИТЬ б Рис. 9.8. Журнал транзакций Остальные элементы данных журнала — это время выполнения действия, тип операции (START обозначает начало транзакции, a COMMIT завершает транзакцию, снимая все наложенные ею блокировки), объект, над которым производилось дейст- вие (например, тип и идентификатор записи), а также исходные и конечные образы. Если есть журнал с исходными и конечными образами, то отмена и повторное выполнение транзакций происходят элементарно (по крайней мере, в описании). Чтобы отменить транзакцию на рис. 9.9, программа восстановления просто за- меняет каждую измененную запись ее исходным образом Когда все исходные образы будут восстановлены, транзакция будет отменена. Чтобы повторно вы- полнить транзакцию, программа восстановления начинает с версии базы данных, существовавшей на момент начала данной транзакции, и записывает в базу все конечные образы Как уже говорилось, это действие подразумевает, что имеется снимок базы данных с более ранней ее версией.
424 Глава 9. Многопользовательские базы денных Восстановление базы данных до ее последнего снимка и повторное выдадне» нпе всех транзакций может потребовать знаки тельного времени Чтобы умедь* шить задержку, в СУБД пно1да используются кош рольные точки. Контрольная точка (checkpoint) — это точка синхронизации ме ду базой данных и журналов транзакций. Для вставки контрольной точки СУБД отклоняет новые запросы, завершает обработку текущих запросов и сбрасывае' свои буферы на диск. Затем СУБД ждет, пока операционная система не сообщит, чго все текущие операции записи на диск и в журнал успешно выполнены. Теперь база данных и журнал синхронизированы. После этого в журнале делается запись о контрольной точ ке. Позже база данных может быть восстановлена с этой точки, и нужно будет записать конечные образы только тех транзакций, которые начались после нее б Рис. 9.9. Пример восстановления: а — транзакция, вызвавшая сбой; б — восстановление Вставка контрольной точки - недорогая операция, и можно выполнять тр < или четыре (а можно и больше) таких операций в час. Таким образом, для вос- становления потребуется не более 15-20 минут работы. Большинство СУБД
Управление СУБД 425 вставляют контрольные точки автоматически, делая человеческое вмешательство ненужным. конкретные примеры приемов резервного копирования и восстановления в Oracle и SQL Server вы увидите в следующих двух главах. На данный момент вам нужно просто понимать основные идеи и сознавать, что разработка адекватных планов резервного копирования и восстановления, а также создание снимков и журналов базы данных являются обязанностью администратора базы данных. Управление СУБД Кроме управления работой с данными и структурой базы данных, администратор обязан управлять самой СУБД. Он должен собирать и анализировать статистику производительности системы и идентифицировать области, чреватые возникно- вением проблем. Вспомните, что база данных обслуживает множество групп пользователей. Администратор базы данных должен рассматривать все жалобы на медленный отклик системы, неточность данных, сложность в использовании и т. п. Если требуются какие-то изменения, администратор должен составить план этих изменений и реализовать их. Администратор должен периодически осуществлять мониторинг пользова- тельской активности при работе с базой данных. Отчеты могут содержать ин- формацию о том, какие пользователи были наиболее активны, какие файлы и, возможно, элементы данных использовались, какие методы доступа были при этом задействованы. Также в отчетах может присутствовать информация о типах и частоте возникновения ошибок. Администратор анализирует эту информацию с целью определить, нужны ли какие-либо изменения в структуре базы данных для повышения производительности или упрощения работы пользователей. Если такие изменения необходимы, администратор обеспечивает их реализацию. Администратор базы данных должен анализировать текущую статистику производительности базы данных и активности пользователей. При обнаруже- нии каких-либо проблем с производительностью (в ходе анализа отчета или по жалобе пользователя) администратор должен определить, требуется ли модифи- кация структуры базы данных пли системы. Примерами возможных структур- ных модификаций являются введение новых ключей, чистка данных, удаление ключей и установление новых связей между объектами. Когда производитель используемой СУБД объявляет о новых возможностях продукта, администратор базы данных должен рассмотреть их в свете потребно- стей сообщества пользователей. Если он решит внедрить эти новые возмож- ности, разработчиков следует уведомить об этом и обучить их использованию. Соответственно, помимо управления структурой базы данных, администратор должен осуществлять управление и контроль над изменениями в СУБД. В обязанности администратора базы данных могут входить и другие измене- ния в системе; какие именно — это зависит от используемой СУБД и другого программного и аппаратного обеспечения. Например, изменения в операци- онной системе или веб-сервере могут повлечь за собой необходимость моди- фикации некоторых возможностей, функций пли параметров СУБД. Поэтому
426 Глава 9. Многопользовательские базы данных администратор базы данных должен также иа< I рай ван, СУБД для совмести^ работы с другим используемым программным обеспечением Первоначальный выбор параметрон СЗ БД (таких как уровень изоляции традз. акций) происходит в момент, когда еще мало известно о том, как система буДег работать в конкретном пользовательском окружении. Следовательно, опытрабд. ты с системой и результаты анализа се производите'iwioci и могут указать на необходимость изменений. Даже если производи (елытость кажется приемлемой возможно, администратор базы данных захочет исс ледовать, как изменение ее параметров будет влиять на производительность. Эго г процесс называется hq стройкой (tuning), или оптимизацией (optimizing) системы. Во врезке приведен перечень обязанностей администратора базы данных по управлению СУБД ОБЯЗАННОСТИ АДМИНИСТРАТОРА БАЗЫ ДАННЫХ ПО УПРАВЛЕНИЮ СУБД --------------— ♦ Подготовка отчетов о работе базы данных ♦ Рассмотрение жалоб пользователей на работу системы ♦ Оценка необходимости изменений в структуре базы данных или приложений. ♦ Модификация структуры базы данных. ♦ Оценка и внедрение новых возможностей и функций СУБД. ♦ Настройка СУБД. Поддержание репозитория данных Представьте себе большое и активное Интернет-приложение базы данных, по- добное тем, что используются компаниями, занимающимися электронной ком- мерцией, — например, продажей музыки в Интернете. Информацию для такой системы могут предоставлять несколько различных баз данных, десятки веб-стра- ниц и сотни, если не тысячи, пользователей. Предположим, что компания, использующая это приложение, желает расши- рить ассортимент предлагаемых товаров, включив в него спортивные товары. Высшее руководство компании может попросить администратора базы данных оценить время и другие ресурсы, необходимые для того, чтобы настроить баз} данных на поддержку новой линии продуктов. Чтобы администратор базы данных смог ответить на этот запрос, ему п0' требуются подробные метаданные, описывающие базу данных, ее приложения и компоненты этих приложений, пользователей и их права и привилегии, а другие элементы системы. Часть этих метаданных хранится в системных таблн цах базы данных, но одной только этой части будет недостаточно, чтобы отве тить на вопросы, задаваемые высшим руководством. Администратору базы ДаН ных требуются дополнительные данные об объектах СОМ и ActiveX, сценар' х процедурах и функциях, ASP-страницах, таблицах стилей, определениях тип документов и т. п. Кроме того, хотя механизмы безопасности СУБД о^еспеЧ„|| вают документирование данных о пользователях, группах и привилегиях, делают это в высокоструктурироваиной и зачастую неудобной форме. По этим причинам многие организации разрабатывают и поддержнва® позитории данных (data repositories), которые представляют собой коЛП^(Х1Ь- метаданных, описывающих базу данных, ее приложения, веб-странииы, п
Резюме 427 зоиателсп и другие компоненты приложений. Репозиторий может быть вирту- альным в том смысле, что составляющие его метаданные собраны из различ- ных источников, в числе которых могут быть СУБД, программное обеспечение контроля версий, библиотеки кода, средства генерации и редактирования веб- страниц и т. д. Репозиторий данных также может быть интегрированным продук- том, который поставляется производителем CASE-средств или другими компа- ниями, например, Microsoft или Oracle. В любом из этих случаев администратор базы данных должен задуматься о по- строении репозитория данных задолго до того, как высшее руководство начнет задавать вопросы. На самом деле репозиторий должен строиться при разработке системы, и его следует рассматривать как важную составляющую часть системы. В противном случае администратор базы данных будет «вечно догоняющим», пытаясь поддерживать существующие приложения, адаптировать их к новым потребностям и каким-то образом собирать метаданные для репозитория. Лучший вид репозиториев — это активные репозитории (active repositories). Они формируются в процессе разработки системы за счет того, что при создании компонентов системы автоматически создаются метаданные. Менее желательным, но все же эффективным вариантом являются пассивные репозитории (passive repositories): заполнение таких репозиториев и создание метаданных для них происходит вручную. Интернет создал невиданные возможности для расширения клиентской базы и увеличения продаж и рентабельности в бизнесе. Базы данных и приложения, используемые компаниями в своей работе, составляют ключевой элемент этого успеха. К сожалению, найдутся такие организации, росту которых будет пре- пятствовать неспособность наращивать свои приложения или адаптировать их к меняющимся потребностям. Зачастую построить новую систему оказывается проще, чем адаптировать уже существующую. Определенно, построение новой системы, которая интегрировалась бы со старой, в то же время заменяя ее, может быть весьма сложной задачей. Резюме Многопользовательские базы данных ставят перед организациями, создающими и использующими их, сложные задачи, и в большинстве организации в этой свя- зи учреждена должность администратора базы данных, который призван обеспе- чить решение этих проблем. В этой книге термином администратор базы данных обозначается человек или группа людей, ответственные за конкретную базу дан- ных. Администратор данных выполняет аналогичные функции, ио они относятся ко всей совокупности информационных активов организации. Администрирова- ние данных обсуждается в главе 15. Основные функции администратора базы данных сформулированы во врезке «Функции администратора базы данных». Администратор базы данных занимается первоначальной разработкой струк- тур базы данных и обеспечивает управление их конфигурацией по мере возник- новения потребное 1 ей в изменениях. Важной функцией администратора базы Данных является подробное документирование структуры и изменений в ней.
428 Глава 9. Многопользовательские базы данных Цель управления параллельной обработкой - пределнратить ненрсЛуемо_ ное влияние действий одного пользователя па действия друтого Несущ^т^у какой-либо одной техники управления параллельной обработкой, кото|>ая гцдд. лась бы па все случаи жи зпп. Приходится находить компромисс между УрОДиец защищенности и пропускной способностью базы данных. Транзакция, или ческая единица обработки, — это последовательность действий с базой Данных, в которой либо выполняются все действия, либо ис выполняется ни одно Дей- ствия параллельных транзакций выполняются па сервере базы данных попереиеи- но. В некоторых случаях при отсутствии управления параллельными транзак- циями может произойти потеря обновлений. Еще одна проблема, возникавши при параллельной обработке, несогласованное чтение. Во избежание проблем, связанных с параллельной обработкой, элементы базы данных блокируются. Неявные блокировки налагаются СУБД, явные блокировки налагаются прикладными программами. Размер блокируемого ресурса называет- ся глубиной детализации блокировки. Монопольная блокировка предотвращает чтение заблокированного ресурса любым другим пользователем; коллективная блокировка позволяет другим пользователям читать заблокированный ресурс, но не позволяет обновлять его. Две параллельные транзакции, результаты выполнения которых совпадают с теми результатами, которые получились бы, если бы эти транзакции выпол- нялись раздельно, называются сериализуемыми транзакциями. Одной из схем достижения сериализуемости является двухфазная блокировка, при которой блокировки налагаются на фазе нарастания и снимаются на фазе сжатия. Особым случаем двухфазной блокировки является стратегия, при которой блокировки налагаются на протяжении всей транзакции, но не снимаются, пока транзакция не будет завершена. Взаимная блокировка, или «смертельное объятие», возникает, когда каждая из двух транзакций ожидает доступа к ресурсу, заблокированному другой транз- акцией. Предотвратить взаимную блокировку можно, обязав транзакции нала- гать блокировки одновременно; если же взаимная блокировка произошла единственный способ снять ее — это прервать одну из транзакций (и отменить частично выполненную работу). При оптимистической блокировке предпола- гается, что конфликта между транзакциями не возникнет, а если он все-таки возникает, то система обрабатывает его последствия. При пессимпстическо блокировке предполагается, что конфликт произойдет, и для его предотврашен,1Я заблаговременно принимаются меры. В общем случае оптимистическая блоки ровка является более предпочтительной для приложений, работающих с Интер" петом, и для многих интрасетевых приложений. Большинство прикладных программ не налагает блокировки явным Вместо этого они помечают рамки транзакции с помощью операторов В COMMIT и ROLLBACK и указывают, какая стратегия управления параллельной битки им требуется. СУБД самостоятельно налагает блокировки в соответст с тем, какого поведения требует приложение. д ACID-транзакция эго транзакция, являющаяся атомарной, изолированпой и устойчивой. Устойчивость означает, что изменения в баз
Вопросы группы I 429 ных являются постоянными. Согласованность может быть на уровне оператора или на уровне транзакции. Транзакция, характеризующаяся согласованностью на уровне транзакции, может не видеть своих собственных результатов. В стандарте SQL 1992 года определены четыре уровня изоляции транзакций, «незавершенное чтение», «завершенное чтение», «воспроизводимое чтение» и «сериализуемость». Характеристики каждого из этих уровней изоляции приведены в табл. 9.1 Курсор — это указатель па набор записей. Наиболее распространены четыре типа курсоров: последовательный, статический, ключевой и динамический. Раз- работчики должны выбирать уровни изоляции и типы курсоров, которые подхо- дят для конкретного приложения и СУБД. Задача системы безопасности базы данных состоит в том, чтобы определенные действия могли выполняться только определенными пользователями и в опре- деленное время. Чтобы разработать эффективную систему безопасности базы данных, необходимо определить для всех пользователей права и обязанности по обработке. СУБД предоставляют некоторые возможности по обеспечению безопасности. Большинство из них включают объявление пользователей, групп, защищаемых объектов и полномочий, или привилегий, по доступу к этим объектам. Почти во всех СУБД используется та или иная разновидность идентификации по имени пользователя и паролю. Рекомендации по обеспечению безопасности СУБД пе- речислены во врезке «Общие принципы обеспечения безопасности СУБД». Воз- можности СУБД по обеспечению безопасности могут быть дополнены функция- ми, реализованными в прикладных программах. В случае сбоя системы база данных должна как можно скорее быть восстанов- лена к работоспособному состоянию. Транзакции, которые выполнялись в мо- мент возникновения сбоя, должны быть повторно сохранены в базе данных или обработаны. Хотя в некоторых случаях восстановление можно осуществить путем повторной обработки, почти всегда предпочтительнее использовать жур- налы и откат-накат. Для уменьшения ’количества работы, необходимой для вос- становления после сбоя, можно устанавливать контрольные точки. В дополнение к перечисленным выше задачам, администратор базы данных управляет самой СУБД, измеряя производительность приложений базы данных и определяя необходимость изменений в структуре базы данных или настройки производительности СУБД. Администратор также знакомится с новыми возмож- ностями СУБД и при необходимости их внедряет. Наконец, администратор базы данных отвечает за поддержание репозитория данных. Вопросы группы I 1. Кратко опишите пять проблем, которые возникают перед организациями, создающими и использующими многопользовательские базы данных. 2. Поясните разницу между администратором базы данных и администрато- ром данных. 3 Перечислите семь важных задач, стоящих перед администратором базы
430 Глава 9 Многопользовательские базы данных 4. Перечислите обязанности администратора базы данных но уиравлевик^ структурой базы данных. 5. Что такое конфигурирование? Почему оно необходимо? 6. Поясните значение слова непредусмотренный во фразе «Действия однзд, пользователя не оказывают непредусмотренного влияния на действия другого пользователя». 7. Объясните, какого рода компромисс возникает при управлении параллель- ной обработкой. 8. Дайте определение атомарной транзакции и объясните, почему важна ато- марность. 9. Объясните, в чем разница между параллельными транзакциями и одно- временными транзакциями. Сколько процессоров требуется для одновре- менной обработки транзакций? 10. Приведите пример потери обновления, отличный от приведенного в тексте. И. Объясните, чем явная блокировка отличается от неявной. 12. Что такое глубина детализации блокировки? • 13. Объясните, в чем разница между монопольной и коллективной блокировкой. 14. Что такое двухфазная блокировка? 15. Как связано снятие всех блокировок в конце транзакции с двухфазной бло- кировкой? 16. Как в общем случае следует определять рамки транзакции? 17. Что такое монопольная блокировка? Как ее можно избежать? Как можно устранить ее, когда она возникает? 18. Объясните, чем оптимистическая блокировка отличается от пессимисти- ческой. 19. Объясните, в чем преимущества подхода, при котором обозначаются рам- ки транзакций и объявляются характеристики блокировок, а само наложе- ние блокировок поручается СУБД. 2Q. Объясните, как используются операторы BEGIN, COMMIT и ROLLBACK TRANSACTION. 21. Расшифруйте термин ACID-транзакция. 22. Объясните, что такое согласованность на уровне оператора. 23. Объясните, что такое согласованность на уровне транзакции. Каким неже- лательным свойством она характеризуется? 24. В чем цель выделения различных уровней изоляции транзакций? 25. Опишите уровень изоляции «незавершенное чтение». Приведите при*11 Р его использования. 26. Опишите уровень изоляции «завершенное чтение». Приведите пример использования. 27. Опишите уровень изоляции «воспроизводимое чтение». Приведите при мер его использования.
Вопросы группы I 431 28. Опишите уровень изоляции «сериализуемость». Приведите пример его использования. 29. Дайте определение термина курсор. 30. Объясните, почему транзакция может иметь много курсоров. Каким обра- зом транзакция может иметь на данной таблице более одного курсора? 31. В чем преимущество использования различных типов курсоров? 32. Опишите последовательные курсоры. Приведите пример их использования. 33. Опишите статические курсоры. Приведите пример их использования. 34. Опишите ключевые курсоры. Приведите пример их использования. 35. Опишите динамические курсоры. Приведите пример их использования. 36. Что произойдет, если вы не объявите СУБД уровень изоляции транзакции и тип курсора? Плохо это или хорошо? 37. Объясните, почему необходимо определять права и обязанности по обра- ботке. Каким образом выполняются эти обязанности? 38. Объясните, как связаны между собой пользователи, группы, полномочия и объекты в системе безопасности типичной базы данных. 39. Должен ли администратор при планировании защитных мер предполагать наличие брандмауэра? 40. Что следует сделать с неиспользуемыми возможностями и функциями ра- бочей СУБД? 41. Опишите меры защиты компьютера, па котором располагается СУБД. 42. Какие меры безопасности должен принимать администратор базы данных в отношении учетных записей и паролей? 43. Назовите два элемента, составляющие план обеспечения безопасности ба- зы данных. 44. Укажите преимущества и недостатки обеспечения безопасности средства- ми СУБД. 45. Укажите преимущества и недостатки обеспечения безопасность средства- ми приложения. 46. Объясните, как можно восстановить базу даннь \ путем повторной обра- ботки. Почему этот метод в общем случае нереализуем на практике? 47 Дайте определение терминам откат и накат. 48. Почему важно делать запись в журнале, перед тем как производить изме- нения в базе данных? 49. Опишите процесс отката При каких условиях он должен использоваться? 50, Опишите процесс наката. При каких условиях он должен использоваться? 51 В чем преимущества частой расстановки контрольных точек в базе данных? 52 Перечислите обязанности администратора базы данных по управлению СУБД,
432 Глава 9. Многопользовательские базы данных 53. Что такое репозитории данных? Что такое пассивный репозиторий? Актив- ный репозиторий? 54. Объясните, в чем важность репозитория данных. 1то может произойти если его не будет? Вопросы группы II 55. Зайдите на сайт www.microsoft.com и поищите на нем информацию о принци- пах обеспечения безопасности в SQL Server (SQL Server security guidelines). Прочтите три из найденных вамп статей и кратко передайте их содержа- ние. Как эта информация соотносится с врезкой «Общие принципы обес- печения безопасности СУБД»? 56. Зайдите на сайт www.oracle.com и поищите на нем информацию о принци- пах обеспечения безопасности в Oracle (Oracle security guidelines). Про- чтите три из найденных вами статей и кратко передайте их содержание. Как эта информация соотносится с врезкой «Общие принципы обеспече- ния безопасности СУБД»? 57. Зайдите на сайт www.google.com и поищите на нем информацию о принци- пах обеспечения безопасности баз данных (database security guidelines). Прочтите три из найденных вами статей и кратко передайте их содержа- ние. Как эта информация соотносится с врезкой «Общие принципы обес- печения безопасности СУБД»? Проект Ответьте на приведенные далее вопросы по базе данных View Ridge, описанной в главе 7, используя данные листинга 7.1 и табл. 7.1-7.5. 1. Представьте, что вам нужно разработать хранимую процедуру, которая за- писывает в базу данных произведение художника, впервые появившегося в галерее, данные об этом художнике, а также дату и стоимость приобрете- ния. Как вы определите границы транзакции? Какой уровень изоляции вы будете использовать? Представьте, что вам нужно разработать хранимую процедуру, которая модифицирует данные в таблице CUSTOMER. Какой уровень изоляции вы будете использовать для этой транзакции? 3. Представьте, что вам нужно разработать хранимую процедуру, которая ре- гисгрирует покупку, сделанную клиентом Пускай клиент будет новым хак вы определите границы транзакции? Какой уровень изоляции вы буде те использовать? 4. Представьте, что вам нужно разработать хранимую процедуру, которая проверяет корректность данных в таблице пересечения. В частности, про цедура должна перебрать все транзакции каждого клиента и определить автора каждого приобретенного клиентом произведения. Затем процедур
Вопросы к проекту FiredUp 433 должна убедиться, что в таблице пересечения имеется запись об интересе клиента к данному художнику. Если соответствующая строка в таблице пересечения отсутствует, процедура должна создать такую строку. Как вы определите границы транзакции? Какой уровень изоляции вы будете ис- пользрват!)? Какие типы курсоров (если таковые будут)? Вопросы к проекту FiredUp 1. Предположим, что фирма FnedUp, Inc. наняла вас в качестве консультанта для разработки базы данных с четырьмя таблицами, описанными в конце главы 6. Допустим, что персонал FiredUp составляют два владельца, адми- нистратор офиса, техник по ремон ту и два работника, занимающихся сбор- кой. Администратор офиса обрабатывает все регистрационные формы. Техник по ремонту вводит все данные о ремонте, а сборщики вводя г данные о горелках, которые они изготовили. Подготовьте записку длиной 3-5 стра- ниц, адресованную менеджерам FiredUp, которая затрагивает следующие вопросы. 1) Потребность в администрировании базы данных в FiredUp. 2) Ваши рекомендации по поводу того, кто мог бы служить в качестве ад- министратора базы данных. Будем считать, что фирма FiredUp имеет недостаточно большие размеры для того, чтобы позволить себе нанять администратора базы данных на полную ставку. 3) Руководствуясь врезкой «Обязанности администратора базы данных по управлению СУБД», опишите, в чем будет заключаться деятельность администратора базы данных в FiredUp. Как энергичный консультант, имейте в виду, что вы можете рекомендовать себя для выполнения неко- торых функций администратора базы данных. 2. Для сотрудников, описанных в вопросе 1, определите пользователей, группы и полномочия относительно данных из четырех таблиц, описанных в конце главы 6. В качестве образца используйте схему обеспечения безопасности, показанную на рис. 9.6. Опять-таки не забудьте включить себя. 3. Представьте, что вам нужно разработать хранимую процедуру, создающую новые записи в таблице ГОРЕЛКА для только что изготовленных горелок. Действуйте в предположении, что во время работы вашей процедуры может выполняться и другая процедура, которая записывает новые или модифи- цирует существующие данные о клиентах и регистрациях. Кроме того, пусть в это же время может выполняться и третья процедура, записываю- щая данные о ремонте горелок. 1) Приведите пример «грязного» чтения, невоспроизводимого чтения и фан- томного чтения при выполнении этих хранимых процедур. 2) Какие меры по управлению параллельной обработкой подойдут для со данной вами хранимой процедуры? 3) Какие меры по управлению параллельной обработкой подойдут для остальных двух хранимых процедур?
434 Глава 9 Многопользовательские базы данных Вопросы к проекту Twigs Tree 1. Предположим, что фирма Twigs Tree наняла нас в качестве консу ьта для разработки базы данных с гремя таблицами, описанными в кош гла* вы 6. Допустим, что персонал фирмы составляют Саманта, адмииистрато] офиса и два садовника, работающих па неполную ставку. Саманта вь сте с администратором офиса обрабатывают данные во всех таблицах Садов- ники вводят данные о выполненных ими работах и доставке стружки Под- готовьте записку длиной 3-5 страниц, адресованную Саманте, которая затрагивает следующие вопросы. 1) Потребность в администрировании базы данных в Twigs Tree. 2) Ваши рекомендации по поводу того, кто мог бы служить в качестве ад- министратора базы данных. Будем считать, что фирма имеет недоста- точно большие размеры для того, чтобы позволить себе нанять админи- стратора базы данных на полную ставку. 3) Руководствуясь врезкой «Функции администратора базы данных» опишите, в чем будет заключаться деятельность администратора базы данных в фирме Twigs Tree. Как энергичный консультант, имейте в ви- ду, что вы можете рекомендовать себя для выполнения некоторых функ- ций администратора базы данных. 2. Для сотрудников, описанных в вопросе 1, определите пользователей, груп- пы и полномочия относительно данных из трех таблиц, описанных в конце главы 6. В качестве образца используйте схему обеспечения безопасности, показанную на рис. 9.6. Опять-таки не забудьте включить себя. 3. Представьте, что вам нужно разработать хранимую процедуру, создающую новые записи в таблице ВЛАДЕЛЕЦ для только что приобретенных клиен- тов. Действуйте в предположении, что во время работы вашей процедуры может выполняться другая процедура, регистрирующая выполняемые ра- боты, а также третья процедура, записывающая данные о доставке струж- ки. В действительности может быть два или даже три экземпляра второй и третьей процедур, работающих параллельно. Это может происходить, когда Саманта или ее садовники одновременно вводят данные о выпол- ненных работах и доставке стружки. 1) Приведите пример «грязного» чтения, невоспроизводимого чтения и фан- томного чтения при выполнении этих хранимых процедур. 2) Какие меры по управлению параллельной обработкой подойдут для созданной вами хранимой процедуры? 3) Какие меры по управлению параллельной обработкой подойдут для двух остальных хранимых процедур?
Глава 10 Работа с базами данных в Oracle 9i Oracle — мощная и надежная СУБД, работающая под управлением различных операционных систем, включая Windows 2000, Windows ХР, несколько вариан- тов UNIX, ряд операционных систем для мейнфреймов и Linux. Она является са- мой популярной СУБД в мире и имеет длительную историю разработки и ис- пользования. Значительная часть технологии Oracle открыта для разработчиков, что обеспечивает большую гибкость при ее конфигурировании и настройке. Однако все это означает, что Oracle может быть непростой в установке, и для работы с ней необходимо многому научиться. О том, насколько широки горизон- ты мира Oracle, можно судить по толщине одной из наиболее популярных книг по этой СУБД: она насчитывает более 1300 страниц и тем не менее не охватывает всех аспектов. Более того, методики, которые работают в версии Oracle, предна- значенной для одной операционной системы, могут потребовать модификации в версии для другой операционной системы. С Oracle вам придется запастись тер- пением и не рассчитывать на то, что вы овладеете этим предметом за одну ночь. Существует много конфигураций программного пакета Oracle. Во-первых, есть две различные версии ядра СУБД Oracle: для индивидуального использова- ния (Personal Oracle) и для организаций (Enterprise Oracle). Кроме того, имеется программа для разработки форм и отчетов (Forms and Reports), программа Oracle Designer и множество средств для публикации баз данных Oracle в Веб. Добавьте к этому необходимость работы в различных операционных системах и поддерж- ки нескольких сетевых протоколов, и вы поймете, почему Oracle представляет такую сложность в изучении. Oracle SQL*Plus — это утилита для обработки запросов на языке SQL и соз- дания таких компонентов, как хранимые процедуры и триггеры. Данная утилита неизменно присутствует во всех вариантах конфигурации продукта. Поэтому на ней мы в основном и сосредоточим наше внимание. С помощью SQL*Plus можно передавать Oracle команды на языках SQL и PL/SQL PL/SQL — это язык, расши- ряющий возможности SQL за счет включения в него конструкций, характерных Для языков программирования. Мы будем использовать PL/SQL для создания таблиц, ограничений, связей, представлений, хранимых процедур И триггеров.
436 Глава 10. Работа с базами данных в Oracle 9i В этой главе будет использоваться пример с базой данных галереи View Ridge из главы 7, а последовательность изложения материала будет в общих чертах по- вторять ход дискуссии об администрировании баз данных в главе 9 Установка Oracle Какую версию Oracle устанавливать, зависит от того, что вы собираетесь делать, пользоваться базами данных, созданными кем-то другим, или создавать собст- венные базы данных. В первом случае достаточно будет установить клиентскую версию СУБД - Oracle 9i Client. Инструкции по установке и соединению с базой данных вам следует получить от того, кто создавал базу данных, с которой вы со- бираетесь работать. Если же вы хотите создавать собственные базы данных, необходимо будет установить полную версию СУБД для персонального использования — Oracle 9i Personal Edition. Более подробную информацию вы найдете по ссылке Installation Guide на странице www.prenhall.com/Kroenke (на английском языке). Создание базы данных Oracle Есть три способа создать базу данных Oracle: посредством мастера Oracle Database Configuration Assistant, с помощью имеющихся в Oracle специальных процедур соз- дания баз данных и с помощью SQL-команды CREATE DATABASE. Первый способ гораздо проще всех остальных, так что им вам и следует воспользоваться. Мастер Database Configuration Assistant можно найти в одном из каталогов, соз- данных при установке Oracle. В зависимости от того, какую операционную сис- тему вы используете, его можно найти в меню Пуск ► Программы ► 0racle-0racle9i Home/Configuration and Migration Tools или в каком-либо подобном месте. Названия каталогов и меню у вас могут различаться; в этом случае мастер следует искать внутри меню Пуск ► Программы. При запуске мастера Database Configuration Assistant вы увидите картинку, изо- браженную на рис. 10.1. Щелкните на кнопке Next (Далее), затем выберите Create a database (Создать базу данных) и General Purpose (Общего назначения). В тек- стовом поле Global Database Name (Глобальное имя базы данных) введите имя, ко- торое вы хотите дать вашей базе данных. В этой главе используется база данных под названием VRG. Далее выберите Dedicated Server Mode (Режим выделенного сервера) и Typical (Обычная). Теперь щелкните на кнопке Finish (Готово), а затем ОК, и Oracle создаст базу данных с заданными по умолчанию размерами и место положением файлов. После создания базы данных Oracle предложит вам ввести пароли для учет пых записей SYS и SYSTEM. Выберите подходящие сильные пароли, которые вы сможете запомнить. Далее в секции Password Management (Управление паролями) можно будет заблокировать или разблокировать учетные записи. На данном этапе вам нет необходимости выполнять какие-либо действия по управлению пароля
Установка Oracle 437 мп, поэтому в этой секции щелкните на кнопке Exit (Выход), и ваша база данных будет готова к использованию. Рис. 10.1. Запуск мастера Oracle Database Configuration Assistant Управлять базой данных Oracle можно из командной оболочки SQL*Plus, а можно использовать для этого программу Oracle Enterprise Manager Console. Мы начнем с SQL*Plus — прежде всего потому, что это классический способ соз- дания баз данных Oracle и управления ими. Кроме того, SQL*Plus присутствует во всех вариантах установки Oracle для всех операционных систем, поэтому, если вы будете знать, как пользоваться этой программой, вы сможете работать с базами данных Oracle в любой операционной системе. После того как вы научи- тесь работе с SQL*Plus, мы обсудим Oracle Enterprise Manager. Работа с SQL*Plus Чтобы запустить SQL*Plus, найдите значок этой программы в меню Пуск ► Про- граммы и щелкните па нем. Войдите в свою базу данных из учетной записи SYSTEM, введя имя базы данных в поле Host String (Имя базы данных), как показано на рис. 10 2 (Процедура можем отличаться, если вы используете версию Oracle, на- строенную кем-го другим. В этом случае следует обратиться к администратору б<иы данных.) Нажмите ОК, и вы должны будете увидеть окно, подобное изобра- женному на рис 10 3
438 Глава 10. Работа с базами данных в Oracle 9i Рис. 10.2. Вход в базу данных с учетной записи Oracle A Oracle SOI •Plus . Г! X File ЕЛ Search Options И-: M)l»Plus: Release 9.2.0.1.в - Production on Hon Sep 2 19:02:11* 2002 Copyright (c) 1982. 2002, Oracle Corporation, fill rights reserved. Connected to: Personal 0racle9i Release 9.2.0.1.0 - Production With the Partitioning, OLfiP and Oracle Data Hining options JServer Release 9.2.0.1.0 - Production SQL> | Рис. 10.3. Приглашение SQL*Plus Буфер SQL*Plus Среди множества функций SQL*Plus есть и функция текстового редактора- ?а бота с Oracle будет проще, если вы узнаете немного об этом редакторе. Во вых, когда вы вводите что-то с клавиатуры в SQL* Plus, вводимые вами симво-пы помещаются в буфер. При нажатии клавиши Enter SQL*Plus сохраняет то, что вы
ввели, в виде строки в буфере и переходит на новую строку, но не завершает опе- ратор и не пытается его выполнить. На рис. 10.4 пользователь ввел SQL-оператор из двух строк. При необходи- мости пользователь может ввести большее количество строк. Когда пользователь вводит точку с запятой и нажимает Enter, SQL*Plus отмечает конец оператора и выполняет его. Попробуйте это сделать, но не обращайте внимания на резуль- таты — ими мы займемся позже. Re £Л Seerdj. Optionsijlslp SQL»Plus: Release 9.2.0.1.в - Production on Hon Sep 2 19:27:b8 2002 Copyright (c) 1982, 2002, Oracle Corporation, nil rights reserved. Connected to: Personal 0racle9i Release 9.2.0.1.0 - Production With the Partitioning, OLfiP and Oracle Data Mining options JSeruer Release 9.2.0.1.0 - Production SQL> SELECT Table_Nane 2 FROM USER_TRBLES 3 Рис. 10.4. Многострочный буфер SQL*Plus ЧЛЛ -s? тобы увидеть содержимое буфера, введите команду LIST, как показано в ниж- ней части рис. 10.5. Строка, помеченная звездочкой, — в данном случае строка 3 — является текущей строкой. Чтобы сделать текущей другую строку, введите LIST и номер строки, например LIST 1. Теперь текущей станет первая строка. Чтобы изменить содержимое текущей строки, введите команду change/строка1/ Стро'а2/ где строка1 — это последовательность символов, которую вы хотите за- менить, а строка2 — последовательность символов, на которую производится за- мена На рис. 10.6 пользователь ввел Change /ТзЬ1е_Нате/*/ •^то выражение заменяет строку TabLe_Name на строку *.
440 Глава 10. Работа с базами данных в Oracle 9i Рис. 10.5. Использование команды LIST Теперь в первой строке буфера выражение SELECT Table_Name поменялось на SELECT *. Чтобы увидеть весь оператор, введите команду LIST. Если ввести символ косой черты (/), а затем нажать клавишу Enter, то оператор, находящийся в буфе- ре, будет выполнен. Прежде чем продолжить, отметим, что в Oracle команды, имена столбцов, таблиц и представлений, а также прочие элементы базы данных не чувствитель- ны к регистру. LIST — это то же самое, что и list, как показывает рис. 10.6. Единст- венный случаи, когда регистр имеет значение, — внутри кавычек в строковых выражениях. Так, выражения SELECT * from ARTIST и select * FROM artist идентичны. Но выражения SELECT * FROM ARTIST WHERE Name = 'Miro' ii SELECT * FROM ARTIST WHERE Name = 'MIRO' являются различными. Регистр внутри кавычек важен.
Установка Oracle 441 Рис. 10.6. Изменение содержимого строки в буфере Есть также разница между точкой с запятой (;) и косой чертой (/). Точка с за- пятой является символом конца оператора, а косая черта предписывает Oracle выполнить операторы, находящиеся в буфере. Если имеется только один опе- ратор и отсутствует неопределенность по поводу того, что требуется сделать, Oracle будет интерпретировать точку с запятой и косую черту одинаково. Так, в выражении Select * from USERTABLES: точка с запятой одновременно служит символом конца оператора и заставляет Oracle выполнить этот опера гор. Введите вместо нее символ косой черты, и опе- ратор будет выполнен снова. Использование внешнего текстового редактора Возможностей встроенного текстового редактора SQL*Plus вполне хватает для вне ‘ ния небольших изменений, но при редактировании длинных выражений, та- ких как хранимые процедуры, он становится неудобным В связи с этим в SQL*Plus предусмотрена возможность работы с внешним текстовым редактором. Чтобы Настроить SQL’Plus/UiH работы с внешним редактором, необходимо прежде всего создать пайку для ваших файлов и указан, па нее SQL*Plus,
442 Глава 10. Работа с базами данных в Oracle 9i Для этого сначала выйдите из SQL*Plus, введя команду exit на при« яашение SQL>. Теперь создайте папку для ваших файлов Oracle - например, С: ,MyDirectory\ OracleCode. Найдите на вашем компьютере значок SQL Plus, щелкните на нем npj, вой кнопкой мыши, чтобы открыть диалог Свойства (Properties), и введите имя созданной вами папки в текстовое поле Рабочим каталог (Start In) Нажмите ОК и вновь запустите SQL* Plus. В оконном меню SQL*Plus выберите команду Edit ► Editor ► Define Editor (Прав- ка ► Редактор ► Задать редактор). Здесь вы можете ввести имя вашего текстового редактора. По умолчанию предлагается выбрать Блокнот (Notepad), для наших целей его будет достаточно, поэтому нажмите ОК. Теперь Блокнот выбран в качестве редактора по умолчанию для SQL*Plus, и ваша папка определена для него как рабочая. С этого момента, получив с кла- виатуры команду Edit, SQL*Plus будет вызывать Блокнот (или другой текстовый редактор, выбранный вами). Теперь вы можете создавать, сохранять и редактиро- вать файлы во вновь созданной папке. В качестве примера заново введите операторы SELECT Table_Name FROM USERTABLES: После появления результатов введите команду Edit. SQL*Plus вызовет Блок- нот, загрузив в него содержимое буфера. Сохраните данный файл под именем EXl.txt, выбрав в меню редактора команду Сохранить как... (Save As ...). Закройте Блокнот, и вы вернетесь в SQL* Plus. Чтобы отредактировать созданный только что файл, введите Edit EXl.txt, и этот файл откроется в вашем текстовом редакто- ре. Когда вы выйдете из редактора и возвратитесь в SQL*Plus, файл будет поме- щен в буфер SQL*Plus. Чтобы выполнить содержимое буфера, введите символ косой черты (/). Кстати, по умолчанию для файлов в SQL* Plus используется расширение .sqL Если вы назовете файл EXl.sql, то можно ввести просто Edit ЕХ1, и SQL*Plus доба- вит расширение за вас. Будучи вооружены этими знаниями SQL* Plus, мы теперь можем исследовать некоторые характеристики Oracle. В следующем разделе мы будем использовать пример с галереей View Ridge, описанный в главе 7, и создадим для него схем)’ базы данных с суррогатными ключами, показанную на рис. 7.3. Создание таблиц Операторы, создающие таблицы базы данных View Ridge (см. листинг 7.1) в вер- си11 для гас е, показаны в листинге 10.1. Эти операторы были оформлены в виде текстового файла под названием create_tables.sql и затем выполнены из команд- ной ооолочки SQL Plus посредством команды start create_tables. Листинг 10.1. Операторы создания таблиц базы данных View Rid0e в версии для Oracle CREATE TABLE CUSTOMER( CustomerlD Name Street int char(25) char(30) NOT NULL NOT NULL NULL.
Установка Oracle 443 City char(35) NULL. State char(2) NULL. ZipPostalCode char(5) NULL. Country varchar(50) NULL. AreaCode char(3) NULL. PhoneNumber char(8) NULL. Email varchar(lOO) NULL. CONSTRAINT CustomerPK PRIMARY KEY (CustomerlD) ): CREATE TABLE ARTIST! ArtistID int NOT NULL. Name char(25) NOT NULL. Nationality varchar(30) NULL. Bi rthDate numeric(4.0) NULL. DeceasedOate numeric(4.0) NULL, CONSTRAINT ArtistPK PRIMARY KEY (ArtistID). CONSTRAINT ArtistAKl UNIQUE (Name). CONSTRAINT Nationalityvalues CHECK (Nationality IN ('Canadian'. 'English’. 'French'. 'German'. 'Mexican'. 'Russian', 'Spanish'. 'US'.)). CONSTRAINT BirthValuesCheck CHECK (BirthDate < DeceasedOate). CONSTRAINT ValidBirthYear CHECK ((BirthDate > 1000) AND (BirthDate < 2100)). CONSTRAINT ValidDeathYear ): CHECK ((DeceasedOate > 1000) AND (DeceasedOate < 2100)) CREATE TABLE CUSTOMER_ARTIST_INT( ArtistID CustomerlD CONSTRAINT int NOT NULL. int NOT NULL. CustomerArtistPK PRIMARY KEY (ArtistID. CustomerlD). CONSTRAINT Customer_Artist__Int_ARtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) ON DELETE CASCADE. CONSTRAINT Customer Artist_Int_CustomerFK FOREIGN KEY (CustomerlD) REFERENCES CUSTOMER (CustomerlD) ON DELETE CASCADE
444 Глава 10. Работа с базами данных BOrud* ® Листинг 10.1 (продолжение} CREATE TABLE WORK( WorkID Title Description Copy ArtistID CONSTRAINT int NOT NULL. varchar(25) NOT NULL. varchar(lOOO) NULL. varchar(8) NOT NULL. int NOT NULL. WorkPK PRIMARY KEY (WorkID). CONSTRAINT WorkAKl UNIQUE (Title. Copy). CONSTRAINT ArtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) CREATE TABLE TRANSACTION( TransactionlD int NOT NULL. DateAcqui red Date NOT NULL. Acquisitionprice • Numeric(8,2) NULL. PurchaseOate Date NULL. SalesPrice Numeric(8.2) NULL. AskingPrice Numeric(8.2) NULL. CustomerlO int NULL, WorkID int NOT NULL. CONSTRAINT Transact!onPK PRIMARY KEY (TransactionlD). CONSTRAINT SalesPriceRange CHECK ((SalesPrice > 1000) AND (SalesPrice <= 200000)) CONSTRAINT ValidTransDate CHECK (DateAcquired <= PurchaseDate). CONSTRAINT Transact)onWorkFK FOREIGN KEY (WorkID) REFERENCES WORK (WorkID) CONSTRAINT T ransacti onCustomerFK FOREIGN KEY (CustomerlO) REFERENCES CUSTOMER (CustomerlO) В операторы SQL-92, приведенные в листинге 7.1, пришлось внести ряд изме- нении, чтооы приспособить их для использования в Oracle Во-первых, Oracle не поддерживает ограничение ON UPDATE CASCADE, поэтому оно было удалено. Кро- ме того, изменены были ограничения на значения столбцов BirthDate и DeceasedDate, гп отм мУ е непРавилыю интерпретирует ограничение (BirthDate LIKE'[1-2] IL J[0 9]). Тип данных этих столбцов был изменен на numeric(4,0), а ограни чсния ыли заданы в виде интервалов. Если не считать этих изменений, лис тинг 10.1 должен выглядеть для вас знакомым. Выполнив эти операторы, вы можете проверить состояние таблиц с помощь10 команды DESCRIBE. На рис. 10.7 показано использование команды DESCRIBE Д^ только что определенных таблиц. Обратите внимание, что можно использовать
Установка Oracle 445 две формы этой команды: DESCRIBE и DESC. Кроме того, заметьте, что определен- ный в стандарте SQL-92 тип данных int интерпретируется Oracle как Number(38), а тип varchar — как собственный тип данных Oracle VarChar2. В табл. 10.1 приве- ден список наиболее часто используемых типов данных Oracle. Обратите внима- ние, что имеется тип данных Date, но отсутствуют типы Money или Currency. Эти типы определяются в Oracle как Numeric. Fife Edft Search Options Hsb SQL) DESCRIBE CUSTOMER; Hane Hull? CUSTOHERID NAME STREET CI TV STATE ZIPPOSTALCODE COUNTRY AREACODE PHONENUMBER ENAIL NOT NULL NOT NULL HUHBER(38) CHAR(25) CHAR(30) CHRR(3S) CHAR(2) CHAR(5) UARCHAR2(50) CHAR(3) CHAR(8) UARCUAR2(100) SQL> DESCRIBE ARTIST; Нэпе Hull? Type ARTISTID NAME NATIONALITY OIRTHDATE DECEASEDDATE NOT NULL NOT NULL NUH0CR(38) CHAR(25) UARCHAR2(30) NUHOERT1*) HUMBERT i*) SQL> DESC WORK; Wane Hull? Type WORKID TITLE DESCRIPTION CDPV ARTISTID NOT NULL NOT NULL NOT HULL NOT HULL HUMDERT38) UARCHAR2(25) UARCHAR2(1000) UARCHAR2(8) HUMBER(3B) SQL> < ... Рис. 10.7. Использование команды DESCRIBE Таблица 10.1. Наиболее часто используемые типы данных Oracle Тип данных Описание BLOB CHAR(n) DATE INT NUMBER(n.d) VARCHAR(n) ИЛИ Большой двоичный объект. Может быть длиной до 4 Гбайт Текстовое поле фиксированной длины п. Максимум 2000 символов. Поле длиной 7 байт, содержащее дату и время Целое число длиной 38 знаков Число длиной п с d знаками после запятой Текстовое поле переменной длины до п символов. Максимальное значение п = 4000 _VARCHAR2(n) Все таблицы базы данных View Ridge, за исключением CUSTOM ER_ARTIST_INT, имеют суррогатные ключи. К сожалению, Oracle не позволяет напрямую опреде- лять суррогатные ключи. Вместо этого необходимо использовать так называе- мые пжледовагш'лъноспш.
446 Глава 10. Работа с базами данных в Oracle 9i Создание суррогатных ключей с помощью последовательностей Последовательность (sequence) — это объект, который генерирует ряд последова- тельных уникальных чисел. Следующий оператор определяет последовательность под названием CustID, которая начинается с 1000 и увеличивается на 1 при каж- дом использовании: Create Sequence CustID Increment by 1 start with 100; Для нас являются важными два метода последовательностей. Метод NextVal выдает следующее значение в последовательности, а метод CurrVal выдает теку- щее значение в последовательности. Так, CustID.NextVal выдает следующее значе- ние в последовательности CustID. С помощью последовательности вы можете вставить строку в таблицу CUSTOMER, как показано ниже: INSERT INTO CUSTOMER (CustomerlD. Name. Area_Code. Phone_Number) VALUES (CustID.NextVal, 'Mary Jones'. '350', '555-1234'); Этот оператор создаст в таблице CUSTOMER строю»', где столбцу CustomerlD будет присвоено следующее значение в последовательности CustID. Выполнив этот опе- ратор, вы можете извлечь только что созданную строку с помощью метода CurrVal SELECT * FROM CUSTOMER WHERE CustomerlD = CustID.CurrVal; Здесь метод CustID.CurrVal возвращает текущее значение в последовательно- сти, то есть только что использованное значение. К сожалению, использование последовательностей не гарантирует коррект- ности значений суррогатных ключей. Во-первых, любой разработчик может ис- пользовать существующую последовательность для произвольных целен. Если последовательность используется для каких-либо иных целей, нежели генерация суррогатных ключей, некоторые значения в ней будут пропущены. Вторая, более серьезная проблема заключается в том, что в схеме нет ничего, что запрещало бы выполнить вставку без использования последовательности. Так, Oracle примет без возражений оператор INSERT INTO CUSTOMER (CustomerlD. Name. Area Code. Phone Number) VALUES (350. 'Mary Jones'. '350'. '555-1234'); Возможно, что выполнение этого оператора приведет к появлению одинако- вых значений сурогатного ключа. В этом случае Oracle не позволит выполнить вставку, поскольку атрибут CustomerlD определен как первичный ключ. Нода»с если и так, все равно может возникнуть потребность в коде, который бы обраоа- тывал эту исключительную ситуацию. Наконец, есть вероятность, что кто-то случайно использует не ту последовательность для вставки в таблицу.
Установка Oracle 447 Несмотря на возможность таких проблем, последовательности представляют собой лучший способ работы с суррогатными ключами в Oracle. Приведенные ниже последовательности будут использоваться нами в базе данных галереи View Ridge. Создайте их с помощью SQL* Plus. Create Sequence CustIO Increment by 1 start with 1000: Create Sequence ArtistID Increment by 1 start with 1; Create Sequence WorkID Increment by 1 start with 500: Create Sequence TransID Increment by 1 start with 100; Ввод данных Теперь с помощью этих последовательностей мы можем заполнять таблицы данны- ми. В листинге 10.2 показан созданный в Блокноте файл, состоящий из последова- тельности операторов INSERT. Создайте такой файл в своем текстовом редакторе, по- местите в конце символ косой черты и сохраните файл под именем ACIns.sqt. Наберите Start ACIns; и операторы, содержащиеся в ACIns, будут выполнены. Ваши данные должны вы- глядеть так, как показано на рис. 10.8. Листинг 10.2. Ввод информации в базу данных View Ridge в Oracle INSERT INTO ARTIST VALUES ( ArtistID.NextVal. 'Miro', 'Spanish'. 1870. 1950): INSERT INTO ARTIST VALUES ( ArtistID.NextVal. 'Kandinsky'. 'Russian'. 1854. 1900): INSERT INTO ARTIST (ArtistID. Name. Nationality BirthDate) VALUES ( Artist ID.NextVai. 'Klee'. 'German', 1900); INSERT INTO ARTIST (ArtistID. Name. Nationality) VALUES ( ArtistID.NextVal. 'Moos’, 'US'): INSERT INTO ARTIST (ArtistID Name. Nationality) VALUES ( ArtistID.NextVal, 'Tobey'. 'US'): INSERT INTO ARTIST (ArtistID. Name, Nationality) VALUES ( ArtistID.NextVal. 'Matisse', 'French'): INSERT INTO ARTIST (ArtistID. Name. Nationality) VALUES ( ArtistID.NextVal. 'Chagall'. 'French'); INSERT INTO CUSTOMER VALUES ( CustID NextVal. 'Jeffrey Janes'. '123 W. Elm St'. 'Renton'. 'WA'. '98123'. 'USA'. '206'. '555-1345'. 'Customerl0000somewhere.com'); INSERT INTO CUSTOMER VALUES ( OustID.NextVai. 'David Smith'. 'B13 Thumbleweed Lane’. 'Loveland'. 'CO'.'B0345'. 'USA', '303', '555-2434'. 'Customerl001Qsomewhere.com'): INSERT INTO CUSTOMER VALUES ( CustID NextVal. 'Tiffany Twilight'. '8B - First Avenue’. 'Langley', 'WA , '98114'. 'USA'. '206', '555-1000'. Customerl015@somewhere.com'): INSERT INTO CUSTOMER VALUES (
448 Глава 10 Работа с базами данных в Oracle 9i Листинг 10.2 (продолжение) CustID.NextVal. 'Fred Smathers'. '10899 - 88th Ave’, 'Bainbridge Island'. 'WA', '98108', 'USA'. ' 0 4 'Customerl033@somewhere.com'): INSERT INTO CUSTOMER VALUES ( CustID.NextVal. 'Mary Beth Frederickson’, '25 South Lafayette', 'Denver'. 'CO'.'B0210'. 'USA'. '303'. 555-1000 . 'CustomerlO340somewhere.com'): INSERT INTO CUSTOMER VALUES ( CustID.NextVal. 'Selma Warning'. '205 Burnaby’. 'Vancouver'. 'BC. 'VON 1B4'. 'Canada'. '253'. '555-1234'. 'Customer1036@somewhere.com'): INSERT INTO CUSTOMER VALUES ( CustID NextVal. Susan Wu . '105 Locust Ave'. 'Atlanta'. 'GA'. '23224'. 'USA'. '721'. '555-1234'. 'CustomerlO370somewhere.com'): INSERT INTO CUSTOMER VALUES ( CustID NextVal. Donald G Gray'. ’55 Bodega Ave'. 'Bodega Bay'. 'CA‘. '92114'. 'USA', '705'. '555-1234'. 'Customerl040@somewhere.com'); INSERT INTO CUSTOMER VALUES ( CustID.NextVal. 'Lynda Johnson’, '117 C Street’. 'Washington'. 'DC'. '11345'. 'USA'. '703'. '555-1000'."); INSERT INTO CUSTOMER VALUES ( CustID.NextVal. 'Chris Wilkens’. 'B7 Highland Drive'. 'Olympia'. 'WA'. '98008'. 'USA'. '206'. '555-1234'.”): Рис. 10.8. Таблицы ARTIST и CUSTOMER после вставки
Установка Oracle 449 Операторы DROP и ALTER С помощью оператора DROP можно удалять различные структуры из базы дан- ных. Например, операторы DROP TABLE MYTABLE; DROP SEQUENCE MySequence; удалят из базы данных таблицу MYTABLE и последовательность MySequence. Все данные из таблицы MYTABLE будут потеряны. С помощью оператора DROP можно также удались столбец из таблицы, как показано ниже: ALTER TABLE MYTABLE DROP COLUMN MyColumn- Ввод данных для примера Чтобы сохранить последовательность в работе с примерами, будем предполагать, что база данных VRG содержит данные, приведенные в табл. 7.1-7.5. Допустим также, что значения суррогатных ключей были получены в результате использо- вания последовательностей, а неравные расстояния между соседними значения- ми ключей являются следствием неоднократной вставки и удаления данных. Между прочим, ввод данных в столбцы, имеющие тип данных Date, может представлять проблему в Oracle. Oracle требует, чтобы даты вводились в опреде- ленном формате, но иногда бывает трудно определить, в каком именно. В этой ситуации на помощь может прийти функция TO_DATE. Эта функция принимает два параметра, как показано ниже’ TO_DATE(’11/12/2002'.'MM/DD/YYYY’) Первый параметр — это значение даты, а второй — шаблон, который должен использоваться для интерпретации этого значения. В данном примере число 11 указывает месяц, а 12 — день месяца. Функцию TO_DATE можно использовать в операторе INSERT для записи даты во вновь создаваемые строки. Пусть, например, таблица Т1 имеет два столбца, А и В, где А имеет тип int, а В — date Тогда новую строку в таблицу Т1 можно вставить с помощью следующего оператора: INSERT INTO Т1 VALUES (100. TO_DATE('0Д/05/02'.'DD/MM/YY')); Результатом будет строка, содержащая значение 100 и дату 1 мая 2002 года в формате Oracle. Функцию TO_DATE можно также использовать в операторах UPDATE. Создание индексов Индексы создаются для обеспечения уникальности столбцов, упрощения сор- тировки и быстрого поиска данных по значениям столбцов Столбцы, которые часто фигурируют в условиях равенства в предложениях WHERE, являются хоро- шими кандидатами па создание индекса Условия равенства могут относиться К одной таблице или же к соединению. Эш два случая представлены в следую Ших примерах-
450 Глава 10. Работа с базами данных в Oracla 9i SELECT * FROM MYTABLE WHERE Coluninl - 100: и SELECT * FROM MYTABLE1, MYTABLE2 WHERE MYTABLEl.Columnl = MYTABLE2.Column2: Если подобные операторы выполняются часто, то столбцы Columnl и ColumnZ являются перспективными кандидатами на создание индексов. Следующий оператор создает индекс по столбцу Name таблицы CUSTOMER: CREATE INDEX CustNameldx ON CUSTOMER!Name): Индексу дано имя CustNameldx. И здесь имя не играет особой роли для Oracle Чтобы создать уникальный индекс, перед ключевым словом INDEX вставьте клю- чевое слово UNIQUE. Например, чтобы гарантировать, что ни одно произведение не будет записано дважды в таблицу WORK, мы можем создать уникальный ин- декс по столбцам (Title, Copy, ArtistID), как показано ниже: CREATE UNIQUE INDEX WorkUniquelndex ON WORK(Title, Copy, ArtistID): Изменение структуры таблицы После создания таблицы ее структуру можно изменять с помощью оператора ALTER TABLE. Будьте, однако, осторожны с этим оператором, поскольку при его ис- пользовании возможна потеря данных. Добавление или удаление столбца осуществляется элементарно: ALTER TABLE MYTABLE ADD Cl NUMBERS): ALTER TABLE MYTABLE DROP COLUMN Cl: Первый оператор добавляет столбец с именем С1 и присваивает ему тип числа длиной четыре символа. Второй оператор удаляет только что созданный столбец. Обратите внимание, что при создании столбца ключевое слово COLUMN опускается. При запуске этих команд вы получите короткое сообщение: «Table altered» (таб- лица изменена). Чтобы убедиться в том, что желаемые изменения действительно были произведены, просмотрите структуру таблицы с..помощью оператора DESCRIBE. Ограничения на модификацию столбцов таблиц Столбец можно удалить в любой момент. При этом, однако, все данные из этого столбца будут потеряны. Также в любой момент можно добавить пустой, или не- обязательный (NULL), столбец. Чтобы добавить обязательный (NOT NULL) столбец, сначала создайте его в таблице как необязательный, заполните все его строки данными, а затем объ- явите его обязательным при помощи конструкции MODIFY. Предположим, напри- мер, что вы добавили столоец С1 в таблицу Т1. После' того как этот столбец будет заполнен в каждой строчке таблицы Т1, можно выполнить следующий оператор.' ALTER TABLE Т1 MODIFY Cl NOT NULL:
Установка Oracle 451 Теперь столбец Cl будет обязательно требовать присвоения значения. При модификации столбца вы можете увеличивать количество символов в тек- стовых столбцах и количество цифр в числовых столбцах. Вы можете также сво- бодно увеличивать или уменьшать количество цифр после десятичной точки. Если данный столбец является пустым во всех строках, можно уменьшать длину текстовых и числовых данных, а также менять тип данных столбца. Создание представлений SQL-представления создаются в SQL*Plus с помощью стандартного оператора CREATE VIEW. Oracle поддерживает все элементы синтаксиса оператора CREATE VIEW, описанные в главе 7. Например, следующий оператор создает представление под названием Customerinterests. CREATE VIEW CustomerInterests AS SELECT C.Name AS Customer. A.Name AS Artist FROM CUSTOMER C JOIN CUSTOMER_ARTIST_INT I ON C.CustomerID = I.CustomerlD JOIN ARTIST A ON I.ArtistID = A.ArtistID; Результаты запроса данных из этого представления для данных из табл. 7.1-7.5 показаны на рис. 10.91. В отличие от стандарта SQL-92, Oracle допускает нали- чие предложений ORDER BY в определении представлений. МММНМШММННИИММН Fte, Edit Search Optuns SQL> select » fron Custonerlnterests order by Custoneri CUSTOMER ARTIST Chris Wilkens Chris Wilkens David Snith Donald G. Gray Fred Snathers Lynda Johnson Lynda Johnson Lynda Johnson Mary Beth Frederickson Hary Beth Frederickson Mary Beth Frederickson Frings Tobey Tobey Tobey Tobey Frings Moos Tobey Frings Tobey Moos CUSTOMER ARTIST Selna Warning Selna Warning Tiffany Twilight Tiffany Twilight Tiffany Twilight Miro Tobey Frings Chagall Tobey 16 rows selected. S0l> | Г X Рис. 10.9. Использование представление Customerinterests Orack 91поддерживает синтаксис JOIN. .ON. Если вы используете Oracle 8i пли более раннюю Пер- сию Oracle, необходимо исполь.юпать градициоииую форму оператора JOIN.
452 Глава 10. Работа с базами данных в Oracle 9i Работа с Oracle Enterprise Manager Console Кроме командной оболочки SQL*Plus, базами данных Oracle можно управлять с помощью программы Oracle Enterprise Manager Console, предоставляющей гра фический интерфейс для выполнения тех же задач. Для запуска этой программы в меню Пуск выберите Программы ► 0racle-0rade9i ► Enterprise Manager Console В от- крывшемся окне выберите режим Launch standalone (Автономный запуск). В левой части окна программы вы увидите иерархический список. Щелкните на узле Network (Сеть), чтобы увидеть список баз данных, имеющихся на вашем компьютере. На рис. 10.10 показан вид окна после того, как пользователь выбрал в списке базу данных VRG. При щелчке на имени VRG Oracle предложит пользо- вателю войти в систему. В данном случае для входа в систему применялась учетная запись SYSTEM. Соответственно, на рис. 10.10 база данных показана как VRG-SYSTEM. Рис. 10.10. Открытие базы данных VRG с помощью программы Enterprise Manager Console Чтобы увидеть таблицы, созданные в базе данных, щелкните на узле Schema (Схема) и на учетной записи, таблицы которой вы хотите просмотреть. В нашем случае таблицы были созданы под учетной записью SYSTEM, поэтому пользова- тель выбрал узел SYSTEM, как показано на рис. 10.11. Чтобы увидеть структуру таблицы, щелкните на ее имени. В правой панели появится список столбцов с указанием типов данных, обязательности и значе- ний по умолчанию, как показано на рис. 10.12. Эта панель позволяет добавлять и удалять столбцы, а также изменять их свойства. Например, на рис. 10.13 поль- зователь изменил длину столбца Name, сделав ее равной 35 символам, и щелкну.
Работа с Oracle Enterprise Manager Console 453 на кнопке Show SQL (Показать SQL-код). В нижней части окна программа пока- зывает SQL-оператор, который будет выполнен, когда пользователь щелкнет на кнопке Apply (Применить). Просмотр SQL-кода бывает полезен в более сложных случаях, когда разработчику необходимо знать, как Oracle интерпретирует изме- нение в структуре базы данных. В данном случае пользователь отменил измене- ние, щелкнув на кнопке Revert (Отменить), и длина столбца Name осталась преж- ней — 25 символов. Рис. 10.11. Ресурсы учетной записи SYSTEM в базе данных VRG kUCMQtr Стгчлн UMttTkinr. .INTERNE Г_АОЕН( 8 I NUMBER CHAR •fCTID NAME NATION.*! ITY VARCHAR? В RTHDATE NUMBER JDECEASEDC'ATE number Г a ? ' &08..WS Ач&ЯМШ imscon f >ARYS I гЛ8У8ТЕЫ <*O?3Dl0S ' ^ffl^MjICERNET^OENT.F QUEUES I QUEUE. WBU=B < «HEUULES -mn < '©CUOIOMCR I «jfflCUSTCiMERJWTCT.IHT Й i I ТВИН «ERROR i ^nji>e<Ej:«.LOEH l.l'tl'AUirOEBt Рис. 10.12. Столбцы таблицы ARTIST и их свойства
454 Глава 10. Работа с базами данных в Oracle 9I Рис. 10.13. Изменение свойства столбца Программа Enterprise Manager Console позволяет также просматривать огра- ничения, наложенные на таблицу. Для этого необходимо перейти на вкладку Constraint (Ограничение). Ограничения для таблицы ARTIST показаны на рис. 10.14. На этой вкладке можно также управлять выделением пространства для таблицы на физическом носителе, а также менять другие параметры. Однако эти вопросы выходят за рамки нашего обсуждения. Рис. 10.14. Ограничения для таблицы ARTIST С помощью Enterprise Manager Console можно создавать и удалять таблН’ цы, а также просматривать и редактировать их. Кроме того, можно создавать.
Логика приложения 455 удалять, просматривать и редактировать представления. На рис. 10.15 показано представление Customerinterests, созданное ранее с использованием SQL*Plus. Это представление можно изменить, модифицировав необходимым образом SQL-операторы в его определении. 4 Ctafri* fЛин CURTOMERVWHIST Рис. 10.15. Вид представления Customerinterests j -AR^an i >д&соп i&SH =kxsvs h&SYSTEM (F.<JT«Jtes QOViews p&AQ'EEFS.ACCALL -CjAOfDEFf_AGERROR -^ARTlSrNET -C^ARIlS^WRkNET 1 -^BASiCCUlSTOMERCWTA BASIO.C’JSTO^ER&VIAJ^A -^CUSTOMERNAMEVIEW vC IWSTOMERtWNE • C-MVIB^EVALUATONS ftMEW^EXCEF’RONB MVIEW.FIJTER WViSV/J-’lLrgRINSTANpS pb¥YlEW_l.OG вад сиэтюиж C ДОГО№К*М1$Г„31Г1 X C1H c.£uscow*rlt> - l.CusSGMtli* JtlS AXTIST A CH I.ActistW • A.A.rtistir <и» В программе Enterprise Manager Console предусмотрено окно для непосредст- венного выполнения SQL-операторов (SQL scratchpad). Оно особенно полезно в ходе разработки и тестирования. Чтобы открыть это окно, щелкните на третьей снизу кнопке на панели инструментов, находящейся слева, в результате чего вы- двинется горизонтальная панель. Щелкните на последней кнопке этой панели, как показано на рис. 10.16, а. Откроется окно непосредственного выполнения (рис. 10.16, б). Введите оператор в текстовую область в верхней части формы и Щелкните на кнопке с молнией. Введенный вами оператор будет выполнен. Логика приложения Есть много способов обработки баз данных Oracle из приложений. Один из способов заключается в том, чтобы создавать приложения на C++, С#, Java, Visual Basic или каком-либо другом языке программирования и вызывать из них Команды СУБД Oracle. Сегодня для этого используются библиотеки объектных Классов создаются объекты, выполняющие необходимые действия с базой дан- ных, Задаются значения свойств этих объектов и вызываются их методы. При- *’РЫ такой обработки вы увидите в ходе обсуждения ADO в главе 12, ADO NET главе 13 и Java Server Pages в главе 14
456 Глава 10. Работа с базами данных в Oracle 0i а * SQL Scratchpad-STST£MS>VRG , . > Select * from Customerinterests Order By Customer &! SQL Ш [CUSTOMER Jartist .: JChris Wilkens Frings 'Chris Wilkens Tobey David Smith Tobey ! Donald G, Gray Tobey FredSmathers [Tobey £ Lynda Johnson Frings Lynda Johnson •Moos § Lynda Johnson jTobey A'? jMary Beth Frederickson | Frings . jMary Beth Frederickson [Tobey хД’Магу Belh Frederickson Moos y- jSelma Warning ! Miro Selma Warning [Tobey | Tiffany Twilight Springs Tiffany Twilight I Chagall ! »x_ . [TiffanyTwilight ,‘Tobey i б Рис. 10.16. Работа с окном непосредственного выполнения SQL-операторов: а — открытие окна, б — выполнение оператора SELECT
Логика приложения 457 Другой способ обработки баз данных Oracle состоит в написании хранимых процедур, как описывалось в главе 7. Эти процедуры могут вызываться из при- кладных программ или из веб-сценариев, написанных па языках VBScript или JScript. Хранимые процедуры можно также вызывать из командной оболочки SQL*Plus и из окна непосредственного запуска в программе Enterprise Manager Console. Однако это следует делать лишь на стадии разработки и тестирования. Как вы знаете из главы 9, по соображениям безопасности не следует разрешать доступ к рабочей базе данных в интерактивном режиме никому, кроме назначен- ных администраторов базы данных. Третий способ обработки баз данных Oracle — запуск последовательностей команд, сохраненных в .sql-файлах. Это делается при помощи команды Start — точно так же, как мы действовали при создании базы данных View Ridge в преды- дущем разделе. Опять-таки из соображений безопасности такие файлы следует запускать только на стадии разработки и тестирования и никогда не использо- вать их на рабочей базе данных. Наконец, логику приложения можно реализовывать посредством триггеров. Как вам известно из главы 7, триггеры можно использовать для проверки допус- тимости данных, задания значений по умолчанию, обновления представлений и |)еализации нестандартных процедур обеспечения ссылочной целостности. В этой главе мы рассмотрим две хранимые процедуры. Здесь мы будем тес- тировать процедуры, запуская их из командной оболочки SQL*Plus Еще раз напомним, что делать это следует только в ходе разработки и тестирования. Из глав 12-14 вы узнаете, как вызывать хранимые процедуры из прикладных программ. Кроме того, мы опишем четыре триггера, каждый из которых будет демонстрировать один из способов применения триггеров. Эти триггеры будут вызываться Oracle при наступлении определенных событий. Хранимые процедуры Хранимая процедура — это программа на языке PL/SQL или Java, которая хра- нится в базе данных. Хранимые процедуры могут иметь параметры, вызывать другие процедуры и функции, возвращать значения и генерировать исключения. Хранимые процедуры могут вызываться удаленно. Примеры вызова хранимых процедур вы увидите в главах 12-14. В этом разделе мы рассмотрим две храни- мые процедуры. Хранимая процедура Customerjnsert Предположим, галерее View Ridge требуется возможность добавлять в базу дан- ных сведения о новых клиентах и о том, какими художниками они интересуются. В частности, нужно записывать имя и телефон клиента, а также связывать его со ьсеми художниками выбранной национальности. В листинге 10.3 изображена хранимая процедура, выполняющая эту задачу. Процедура, которая называется Customer_Insert, принимает четыре параметра: newname (имя новою клиента), newareacode (код региона), newphone (телефон) и artistnationality (национальность художника). Ключевое слово IN указывает на
458 Глава 10. Работа с базами данных в Oracle 91 то что все эти параметры являются ихолпыми. Выхолвые параметры («pr<w XXtZwpbi пет) обозначаются ключевым еловом OUT. а параметры, м,раю- да рвТйвтодных и выходных, - сочетанием IN OUT. Обратите внимание.™ т,Параметра указывается только т.п. данных, а длина не указывается Oracle определит длину из контекста. Листинг 10.3. Хранимая процедура Customerjnsert CREATE OR REPLACE PROCEDURE Customerjnsert ( newname IN char newareacode IN char newphone IN char artistnationality IN char ) AS rowcount integer(2); CURSOR artistcursor IS SELECT ArtistID FROM ARTIST WHERE Nationality=ArtistNatlona1ity: BEGIN SELECT FROM WHERE Count!*) INTO rowcount CUSTOMER Name = newname AND AreaCode = newareacode AND PhoneNumber = newphone: IF rowcount > 0 THEN BEGIN действий не DBMS_OUTPUT.PUTJINE ('Клиент уже есть в базе данных - никаких предпринято. Число строк = ’IIrowcount)• RETURN: ENO ENO IF; INSERT INTO CUSTOMER (CustomerlD. Name. AreaCode, PhoneNumber) VALUES (CustID.NextVal, NewName. NewAreaCode. NewPhone); FOR artist IN artistcursor LOOP INSERT INTO CUSTOMER_ARTIST_INT (CustomerlD. ArtistID) VALUES (CustID.CurrVal, artist.ArtistID): END LOOP; DBMS_OUTPUT PUTJ.INE ('Клиент успешно добавлен в базу данных') END; /
Логика приложения 459 Раздел объявления переменных следует за ключевым словом AS. Оператор SELECT определяет переменную-курсор (cursor variable) с именем artistcursor. Этот курсор выделяет из таблицы ARTIST для обработки строки всех художников за- данной национальности. В первой части процедуры проверяется, есть ли в базе информация о данном клиенте. В этом случае никакие действия не предпринимаются, а пользователю с помощью пакета Oracle DBMS_OUTPUT выводится соответствующее сообщение. Обратите внимание, что для вывода строки и значения переменной используется следующий синтаксис: DBMS_OUTPUT.PUT_LINE ('<строка>'||<переменная>): Прежде чем мы продолжим обсуждение этой процедуры, обратите внимание, что пользователь получит это сообщение только в том случае, если процедура будет вызвана из SQL*Plus. В случае вызова процедуры иным путем, например с помощью браузера через Интернет, пользователь не увидит этого сообщения. Чтобы сообщить пользователю об ошибке, разработчик должен воспользоваться выходным параметром или сгенерировать исключение. Эти вопросы, однако, выходят за рамки настоящей дискуссии. Кроме того, чтобы такие сообщения стали видимыми, следует выполнить команду Set serveroutput on: Если при работе в SQL*Phis вы не видите сообщений, выводимых вашими процедурами, то, скорее всего, вы не выполнили этот оператор. Оставшаяся часть процедуры в листинге 10.3 вставляет данные о новом клиенте и затем перебирает всех художников выбранной национальности. Обратите внима- ние на использование специальной конструкции PL/SQL FOR artist IN artistcursor. Эта конструкция выполняет несколько задач. Прежде всего, она открывает кур- сор и считывает первую строку. Затем она последовательно обрабатывает все строки под курсором и по окончании обработки передает управление следующе- му оператору после FOR. Заметьте также, что обращение к столбцу ArtistID теку- щей строки происходит с использованием синтаксиса artist.ArtistID, где artist — это имя переменной цикла FOR, а не курсора. После того как процедура написана, ее необходимо скомпилировать и сохра- нить в базе данных. Наберите текст процедуры в редакторе и сохраните его под именем, скажем, SP_CI.sqL Если в последней строке файла вы поместите косую черту, то процедура будет скомпилирована и сохранена в базе данных автомати- чески после ввода команды Start SP_CI Если вы что-ю ввели неправильно, у вас могут возникнуть ошибки компиля- ции К сожалению, SQL*Plus нс покажет вам эти ошибки автомагически, а выдаст сообщение "Warning: Procedure created with compilation errors" (Предупреждение: При компиляции процедуры обнаружены ошибки). Чтобы увидеть ошибки, введите команду Show errors;
460 Глава 10. Раоота с базами данных в Oracle 91 Если синтаксических ошибок не было, вы получше сообщение "Procedure created" (Процедура создана). Теперь иы можете вызывать эту процедуру с ломо. щыо команды EXECUTE пли ЕХЕС: Exec Customer_Insert('Michael Bench'. '203'. '555 2014'. 'US'). Выполнив этот опера гор, следует запроси гь данные из таблиц CUSTOMER, ARTIST и CUSTOMER_ARTIST_INT. чтобы убедиться, что изменения были сделаны правильно Если возникнут ошибки на этане выполнения процедуры, номера строк в от- чете об ошибках не будут совпадать с номерами строк, которые вы можете ви- деть в своем текстовом редакторе. Вы можете настроить SQL*Plus так, чтобы выводимые номера строк соответствовали вашим, по этот процесс слишком сло- жен, чтобы описывать его здесь. С теми простыми процедурами, которые мы бу- дем рассматривать, можно обойтись и без этого. Главное, имейте в виду, что но- мера строк могут различаться. Хранимая процедура NewCustomerWithTransaction В листинге 10.4 показана хранимая процедура, записывающая в базу данных но- вого клиента и регистрирующая факт покупки им произведения. Логика этой процедуры, носящей имя NewCustomerWithTransaction, такова. Сначала создаются данные для нового клиента, и в таблице TRANSACTION, где регистрируются куплен- ные произведения, ищутся строки с пустым столбцом CustomerlD. Поиск ведется по соединению таблиц ARTIST, WORK и TRANSACTION, так как имя художника (Name) хранится в таблице ARTIST, а название произведения (Title) и номер копии (Сору) хранятся в таблице WORK. Если найдена одна и только одна такая строка, в ней обновляются столбцы CustomerlD (идентификатор клиента), SalesPrice (цена про- дажи) и PurchaseDate (дата приобретения). Затем добавляется запись в таблицу пересечения, чтобы зарегистрировать интерес клиента к данному художнику. В противном случае, если число найденных строк больше или меньше 1, никаких изменений в базе данных не производится. Листинг 10.4. Хранимая процедура NewCustomerWithTransaction CREATE OR REPLACE PROCEDURE NewCustomerWithTransaction ( newname IN char. newareacode IN char. newphone IN char. artistname IN char. worktitle IN char. workcopy IN char. price ) IN number AS rowcount integer: tid int: aid int: -МмтммяЖМЯЯ
Логика приложения 461 CURSOR transcursor IS SELECT TransactionlD. ARTIST.ArtistID FROM ARTIST. WORK. TRANSACTION WHERE Name=artistname AND Title=worktitle AND Copy=workcopy AND TRANSACTION. CustomerlO IS NULL AND ARTIST.ArtistID = WORK.ArtistID AND WORK.Work ID = TRANSACTION.Work ID: BEGIN /* Есть ли клиент в базе данных? */ SELECT Count!*) INTO rowcount FROM CUSTOMER WHERE Name=newname AND AreaCode=newareacode AND PhoneNumber=newphone: IF rowcount > 0 THEN BEGIN DBMS_OUTPUT.PUT_LINE ('Клиент уже есть в базе данных - никаких действий не предпринято. Число строк = '||rowcount): RETURN; END END IF; /* Клиент остутствует в базе данных - добавляем его в базу */ INSERT INTO CUSTOMER (CustomerlO. Name. AreaCode. PhoneNumber) VALUES (CustID.NextVal. newname, newareacode. newphone): /* Ищем ровно одну доступную строку в таблице TRANSACTION */ rowcount := 0: FOR trans IN transcursor LOOP tid := trans.TransactionlD; aid := trans.ArtistID: rowxount := rowcount + 1; END LOOP: IF rowcount > 1 THEN BEGIN /* Слишком много доступных строк. Отменяем транзакцию, выводим сообщение и завершаем процедуру */ ROLLBACK.
462 Глава 10. Работа с базами данных в Oracle 9I Листинг 10.4 (продолжение) DBMS_DUTPUT.PUT_LINE (’Некорректные данные в таблицах ARTI5T/W0RK/ TRANSACTION. Никаких действий не предпринято Число строк - ' 11 г (Mount: - RETURN; END; END IF: IF rowcount = О THEN BEGIN /* Нет ни одной доступной строки. Отменяем транзакцию, выводим сообщение и завершаем процедуру. */ ROLLBACK: DBMS_OUTPUT.PUT_LINE ('Ни одной доступной строки - никаких действий не предпринято'): RETURN: END: ENO IF: Utt1 т*1 /* Есть ровно одна строка - используем ее (значение tid получено выше из transcursor) */ UPDATE TRANSACTION SET CustomerlD = CustID.CurrVal. Salesprice = price. PurchaseDate = SysDate WHERE TransactionlD = tid: Чй DBMS_OUTPUT PUT-LINE ('Данные о клиенте и транзакции обновлены'): /* Теперь регистрируем интерес клиента к данному художнику */ /* Используем currval из последовательности и aid из transcursor */ INSERT INTO CUSTOMER_ARTIST_INT (ArtistID, CustpmerlD) VALUES (aid. CustID.CurrVal): ENO: енте и прггобретенном ^e'^BstonierW’thTransact’on содержат информацию о кли- переменных и курсор Курсоп ^Ведении' В пР°иедуре объявлены несколько и TRANSACTION Он ru™ УР Р определен на соединении таблиц ARTIST. WORK держащих данные % СТ°лбцЫ Transa^onID и ARTIST.ArtistID из строк, со- столбец CustomerlD искомых художнике и произведении и имеющих пустой
Логика приложения 463 Прежде всего процедура проверяет, нет ли уже в базе данных информации о данном клиенте. Если нет, данные нового клиента добавляются в базу. В PL/SQL нет оператора BEGIN TRANSACTION1 — первое действие с базой данных автоматиче- ски начинает транзакцию. Здесь новая транзакция начнется при добавлении данных о покупателе. Обратите также внимание, что комментарии заключены между скобками ви- да /* и */ Такие комментарии могут состоять из нескольких строк, и если вы начнете комментарий с символов /*, но забудете завершить его символами */, то вся ваша программа будет воспринята как комментарий. После того как данные о новом покупателе добавлены в базу, обрабатывается курсор TransCursor. Переменная rowcount используется для подсчета строк, в пере- менную tid записывается значение TransactionlD, а в переменную aid — значение ArtistID. Заметьте, что оператор присваивания в Oracle выглядит так: На- пример, tid := trans.transactionlD обозначает, что в переменную tid записывается значение trans.TransactionlD. В соответствии с логикой процедуры, если найдена одна и только одна стро- ка, удовлетворяющая критериям, то в переменных tid и aid будут содержаться значения, нужные нам для успешного завершения транзакции. Если же таких строк не найдено или найдено более одной, то транзакция будет прервана, и ни tid, ни aid не будут использованы. Для подсчета строк мы могли бы использовать выражение Count(*) и затем, если Count(*) = 1, запустить другой оператор, который бы получал нужные нам значения aid и tid. При той логике, которая реализована в листинге 10.4, необхо- димость во втором SQL-операторе отпадает. Если число строк RowCount больше единицы или равно нулю, го выдается со- общение об ошибке и выполняется откат транзакции, отменяющий вставку дан- ных в таблицу CUSTOMER. Если RowCount равно 1, обновляется соответствующая строка в таблице TRANSACTION. Обратите внимание па использование функции SysDate, с помощью которой записывается текущая дата. Наконец, в таблицу пе- ресечения добавляется строка с информацией о покупателе и авторе купленного произведения (aid). Эта хранимая процедура может быть вызвана командой наподобие Exec NewCustomerWithTransaction('Maiinda Gliddens'. '303'. '555-6687'. 'Chagall', 'Northwest By Night'. '37/50'. '27000'): Чтобы протестировать эту процедуру, удобно будет сначала создать представ- ление, содержащее данные о покупках клиентов. Пусть было создано следующее представление: CREATE VIEW WorkPurchase AS SELECT C Name as Customer. A.Name as Artist. W.Title. W Copy. T PurchaseDate. T.SalesPrice 1 Вульте внимательны! Слови I RANSACTION нснолычуегся здесь u двух значениях: как имя одной иг Таблиц в базе данных галереи View Ridge и как английское слот), обозначающее транзакцию группу операторов, выполняемых как единое целое. Конкретное значение ясно из контекста, ио имейте и яйлу, что пыможпл путаница
464 Глава 10 Раоота с базами данных в Orac I > £ FROM JOIN CUSTOMER C JOIN TRANSACT ION T C.CustomerlD - 1 CustomerlD W JOIN ON WORK ON T.WorkID - W.WorkID ARTIST a' ON W.ArtistID = A.ArtistID: Ha pnc. 10 17 изображены SQL-операторы опрашивающие данные из этого представления представления Customerinterests и таблицы CUSTOMER Как видно из рисунка, изменения были выполнены правильно. Разумеется, чтобы полностью протестировать эту процедуру, необходимо посмотреть на ее поведение в ошибоч- ной ситуации, но здесь мы опустим этот шаг. Ffe Edit 5ea«b Optwns Нф SQL> Select * froR Workpurchase WHERE Oustoner ” ‘Malinda Gliddens'; CUSTOMER ARTIST TITLE COPY PURCHASED SALESPRICE Malinda Gliddens Chagall Northwest by Night 37/50 O^-SEP-02 27000 • SQL> Select • from CustomerInterests WHERE Customer » ’Nalinda Gliddens’; CUSTOMER ARTIST Nalinda Gliddens Chagall SQL> Select Name, Areacode, PhoneNumber FROM CUSTOMER WHERE Name «= ‘Halinda Gliddens’; NAME ARE PHONENtIN Gliddens 303 555-6687 SQL> > Рис. 10.17. Результат работы хранимой процедуры NewCustomerWithTransaction (листинг 10.4). Триггеры Т риггеры в Oracle — это процедуры на языке Java или PL/SQL, которые вы- зываются при выполнении определенных действий с базой данных. Oracle под- держивает несколько типов триггеров. Одни из них вызываются при создании новых таблиц, представлений или триггеров, другие (командные) — единожды при выполнении SQL-оператора, третьи (строчные) — для каждой строки, затро- нутой SQL-оператором. Чтобы понять разницу между двумя последними типами триггеров, рассмот- рим следующий оператор обновления: UPDATE SET WHERE Командный триггер будет вызван один раз при обработке этого оператора. Строчный триггер будет вызван по одному разу для каждой строки, которая CUSTOMER AreaCode = '425' ZipPostalCode = '98119'; 51 a ss
Логика приложения 465 будет обновлена в ходе выполнения оператора. Строчные триггеры наиболее распространены, и в этой главе мы будем рассматривать только их. Oracle поддерживает три вида строчных триггеров: предваряющие (триг- геры BEFORE), завершающие (триггеры AFTER) и замещающие (триггеры INSTEAD OF). Предваряющие и завершающие триггеры могут назначаться таб- лицам, а замещающие — представлениям. Триггер каждого типа может вызы- ваться при вставке, обновлении или удалении. Из-за того, как Oracle управляет параллельной обработкой, завершающие триггеры, которые обновляют таблицу, вызвавшую их запуск, могут привести к проблемам. Например, если таблица Т1 имеет завершающий триггер обновле- ния, те фрагменты кода триггера, которые обращаются к таблице Т1, могут рабо- тать некорректно. В таких случаях Oracle выдает сообщение Table Т1 is mutating, trigger/function may not see it (Таблица Т1 находится в процессе изменения, триг- гер или функция не может видеть ее). По этой причине любые действия, связан- ные с доступом к таблице, вызвавшей запуск триггера, лучше всего выполнять в предваряющих триггерах. Завершающие триггеры, однако, могут быть полезны, когда действия тригге- ра распространяются на таблицу, отличную от той, которая вызвала его запуск. Например, если таблица Т1 требует обязательной дочерней строки в таблице Т2, для Т1 можно определить завершающий триггер вставки, который будет созда- вать требуемого потомка в Т2. Пример такого использования триггера вы увиди- те в листинге 10.8. Триггеру доступны значения столбцов таблицы или представления, которому он принадлежит. Триггеры вставки и обновления могут обращаться к новым значениям столбцов таблиц и представлений, используя префикс :new. Напри- мер, если таблица Т1 имеет два столбца, С1 и С2, то для триггера вставки или обновления, запущенного таблицей Tl, inew.Cl будет содержать новое значение столбца Cl, a :new.C2 — новое значение столбца С2. Триггеры обновления и удаления могут обращаться к старым значениям столбцов таблиц и представлений, используя префикс :old. Например, :old.Cl будет содержать значение, которое имел столбец С1 до обновления или удаления. В последующих разделах мы рассмотрим четыре примера, каждый из кото- рых демонстрирует одно из возможных применений триггеров: реализацию биз- нес-правила, расчет значения ио умолчанию, обновление представления и реали- зацию ограничения обязательного потомка. Триггер, реализующий бизнес-правило Галерея View Ridge ведет список «проблемных» клиентов — тех, кто нс оплатил вовремя покупку или представил какие-то другие проблемы для галереи. Когда в базу данных вводится покупа тель, фигурирующий в списке таких клиентов, Менеджер галереи хотел бы знать об этом. Завершающий триггер, текст которого приведен в листинге 10.5, обеспечива- ет такое уведомление Фраза AFTER INSERT OR UPDATE OF Name ON CUSTOMER являет- я Правильной, но содержит в себе неопределенность. Она означает, что триггер шъм'и быть запущен после побои ш i шки в таблицу CUSTOMER или после обнов
466 Глава 10. Работа с базами данных в Oracle 9I ления столбца Name этой таблицы. Таким образом, запуск iрипера вызовет дю- бая вставка, а также обновление столбца Name. Листинг 10.5. Триггер ValidateCustomer CREATE OR REPLACE TRIGGER ValidateCustomer AFTER INSERT OR UPDATE OF Name ON CUSTOMER FOR EACH ROW DECLARE rowcount integer; BEGIN /* Ищем нового клиента в таблице PROBLEM-ACCOUNT */ SELECT Count!*) INTO rowcount FROM PROBLEM_ACCOUNT PA WHERE :new.Name = PA.Name AND :new.AreaCode = PA.AreaCode AND :new.PhoneNumber = PA.PhoneNumber: /* Если клиент фигурирует в таблице "проблемных" клиентов. выводим предупреждающее сообщение */ IF rowcount > О THEN DBMS_OUTPUT.PUT_LINE('С клиентом по имени ' || :new.Name || имеющим номер телефона (' || :new.AreaCode || ’)' || :new.PhoneNumber || '. были проблемы в прошлом.'); END IF; END; TpiiTOenPZnv™ R ЕАСН R°W определяет Данный триггер как строчный, то есть в таблицу и п аемыи п° °Дн°му разу для каждой строки, которая вставляется телицу или в которой обновляется столбец Name. вшпеннем^лГ _ * триггера в текстовом редакторе и сохраните его в файле с рас- команлу Start тг' Иапр“мер’ Tn99erl.sql. Затем откройте SQL*Plus и введите появится слаб '"еГ ° ЭТ°й комаиде Oracle скомпилирует ваш триггер. Если Errors Юк бьтппЦеИИе ° налич|,и синтаксических ошибок, введите команду Show Чтобы ° Оп1|сано в Разделе, посвященном хранимым процедурам. со столбгг-1мГ^™Р°лаТЬгЭГОТ триггер- сначала создайте таблицу PROBLEM^ACCOUNT столбцам таблицы CUSTOME^R Ph°neNumber’ соответствующими одноименным вого клиент- ЧМЕ". Вставьте в нее несколько строк. Затем добавьте но- PROBLEM дсгли^т'^л е которого совпадают с данными одной из строк таблицы - На рис. 10.18 показан результат тестирования триггера на
Логика приложения 467 клиенте по имени Nichole Not Рау. Обратите внимание, что этот триггер выводит уведомление о проблемном клиенте в оболочку SQL*Plus. Более реалистичным вариантом была бы отправка сообщения менеджеру галереи по электронной по- чте или какое-либо другое более очевидное действие. -t Or.ulv SOI 1’tns : Fie Edit Search Options Help .Л:-.-, SQL> set seruernutput nn; SQL> SELECT * FROM PROBLEM ACCOUNT; NAME ARE PHONEHUH Nichole Not Pay 213 555-1234 SQL> INSERT INTO CUSTOMER (CustomerlD, Name, AreaCode, PhoneNumber) 2 VALUES (CustID.NextUal, 'Nichole Not Pay', ’213*, ’555-1234); A Customer with name Nichole Not Pay and phone of (213) 555-1234 has been a problem in the past. 1 row created. SQL> | Рис. 10.18. Результат работы триггера ValidateCustomer Использование таблицы допустимых (или недопустимых) значений обеспечи- вает большую гибкость и динамичность, чем указание этих значений в ограниче- ниях CHECK. Рассмотрим, например, ограничение CHECK, определяющее допусти- мые значения столбца Nationality в таблице ARTIST. Если менеджер галереи хочет расширить географию художников, с произведениями которых работает галерея, ему придется изменить ограничение с помощью оператора ALTER TABLE. В реаль- ности для этого менеджеру пришлось бы нанимать консультанта. Более удачный подход — свести все допустимые значения столбца Nationality в таблицу. Такая таблица могла бы называться, например, ALLOWED_NATIONALITY (допустимая национальность). Затем можно написать триггер, подобный изобра- женному в листинге 10.5, который бы при вставке и обновлении ограничивал воз- можные значения столбца Nationality множеством значений из таблицы ALLOWED- NATIONALITY. Если владелец галереи захочет изменить список национальностей, ему достаточно будет добавить строки в таблицу ALLOWED_NATIONALITY или уда- лить их оттуда. Триггер, присваивающий значения по умолчанию Триггеры можно использовать для присвоения начальных значений, расчет кото- рых слишком сложен, чтобы его можно было выполнить с помощью ограничения DEFAULT в определении столбца. Например, согласно ценовой! политике галереи View R dge, запрашиваемая цена произведения, которая устанавливается по умол- чанию, зависит о! того, появлялось лн это произведение в галерее в прошлом. Если нет, она ус 1апавлнвас1ся равной удвоенной стоимости приобретения. Если Произведение уже появлялось в галерее прежде, зап] опиваемая цепа устанавли- вается ранной большему из двух значений — удвоенной стоимости приобретения или стоимости приобретения плюс средняя чистая прибыль от продажи произве- дения в прошлом
468 Глава 10 Работа с базами данных в Oracle 9i Предваряющий триггер, текст которого приведен в листинге 10 в, реалиху. ет эту политику. Он имеет название SetAskingPrice и использует Л|м ш гав ArtistWorkNet, определенное в главе 7 следующим образом CREATE VIEW ArtistWorkNet AS SELECT W.Workld. Name. Title, Copy. AcquisitionPrice. SalesPrlce. (SalesPrice - AcquisitionPrice) AS NetPrice FROM TRANSACTION T JOIN WORK W ON T.WorkID - W WorkID JOIN ARTIST A ON W ArtistID A ArtistID; Листинг 10.6. Триггер SetAskingPrice CREATE OR REPLACE TRIGGER SetAskingPrice BEFORE INSERT ON TRANSACTION FOR EACH ROW DECLARE avgNetPrice numeric!8.2); newPrice numeric!8.2); rowcount integer; BEGIN /* Сначала проверяем, появлялось ли произведение ранее в галерее */ SELECT Count!*) INTO rowcount FROM TRANSACTION WHERE WorkID =:new.WorkID; IF rowcount = 0 THEN /* Произведение появилось в галерее в первый раз */ :new.AskingPrice := 2*(:new.AcquisitionPrice): ELSE /* Произведение уже появлялось в галерее */ SELECT AVG(NetPrice) INTO avgNetPrice FROM Arti stWorkNet AW WHERE AW.Work ID = :new.Work ID GROUP BY AW.WorkID: newPrice = avgNetPrice + :new.AcquisitionPrice; IF newPrice > 2 * :new.AcquisitionPrice THEN ;new.AskingPrice := newPrice:
Логика приложения 469 ELSE .new.AskingPrice := 2 * -.new.AcquisitionPrice: END IF; END IF. END; / Триггер сначала подсчитывает количество строк в таблице TRANSACTION, в ко- торых значение WorkID равно :new.WorkID. Поскольку это предваряющий триг- гер, произведение еще не добавлено в базу данных, и количество будет рав- ным нулю, если это произведение не появлялось в галерее ранее. В этом случае rnew.AskingPrice устанавливается равным удвоенному значению AcquisitionPrice. Если произведение появлялось в галерее в прошлом, рассчитывается средняя чистая прибыль от его продажи с помощью представления ArtistWorkNet. После этого вычисляется переменная newPrice как сумма средней чистой прибыли и сто- имости приобретения. Наконец, mew.Askingprice присваивается большее из двух значений — newPrice или удвоенное значение AcquisitionPrice. Так как триггер предваряющий, для усреднения можно использовать встроенную функцию AVG: новая строка еще не добавлена в таблицу WORK, поэтому она не будет учтена при расчете среднего значения. Есть один нюанс: если в какой-либо из строк представления ArtistWorkNet стол- бец SalesPrice или Acquisition Price является пустым, это может вызвать проблемы при вычислениях в триггере. Обсуждение этого вопроса, однако, выходит за рам- ки данной главы. Этот триггер выполняет для галереи полезную функцию, избавляя персонал от значительного количества ручной работы, а также повышая точность результатов. Триггер, обновляющий представление В главе 7 обсуждались проблемы, связанные с обновлением представлений. Одна из таких проблем касается представлений, созданных при помощи операции со- единения- как правило, СУБД не способна обновлять таблицы, лежащие в основе таких представлений. Однако, зная специфику конкретного приложения, можно определить, как следует интерпретировать запрос на обновление соединенного представления. Рассмотрим представление Customerinterests, определенное ранее в этой главе. Оно содержит строки таблиц CUSTOMER и ARTIST, соединенные через таблицу пересече- ния Столбцу CUSTOMER.Name дан псевдоним Customer, а столбцу ARTIST.Name — Artist Запрос па изменение имени клиента в представлении Customerinterests можно иитерпретирова।ь как запрос па изменение столбца Name в таблице CUSTOMER Такой запрос, однако, можс1 быть обработан лишь в том случае, если это имя яв- ляется уникальным в таблице CUSTOMER В противном случае невозможно будет ''«рсделигь, какую из строк следует обновлять В Листинге 10 7 приведен текст замещающего триггера, который обновляет имл клиента, если это имя является уникальным в базе данных Вместо того чтобы
470 Глава 10. Работа с базами данных в Oracle 9I подсчитывать количество строк с данным именем клиента и выполнить обновке- пне только в том случае, если такая строка всею одна, триггер обусловливает об- новление ключевым словом NOT EXISTS. Такая конструкция триггера позволяет Oracle оптимизировать SQL-оператор и приводит к лучшей производительности. Листинг 10.7. Триггер CustomerinterestsJJpdate CREATE OR REPLACE TRIGGER Customerinterests JJpdate INSTEAD OF UPDATE ON CustomerInterests FOR EACH ROW /* Обновляем Name только в том случае, если имя является уникальным ? таблице Customer */ BEGIN UPDATE CUSTOMER Cl SET Cl.Name = :new.Customer WHERE Cl.Name = :old.Customer AND NOT EXISTS (SELECT * FROM CUSTOMER C2 WHERE C2.name = Cl.Name AND C2.CistomerID <> Cl.CustomerID); END: / Триггер, реализующий процедуру обеспечения ссылочной целостности Согласно рис. 7.3, таблица WORK в базе данных View Ridge имеет обязательного потомка в таблице TRANSACTION. Это означает, что всякий раз когда в таблицу WORK вставляется строка, необходимо вставить соответствующую ей строку в таб- лицу TRANSACTION. Реализовать такие ограничения ссылочной целостности непросто. Первое, что приходит в голову, — это создать завершающий триггер для таблицы WORK, который бы проверял, что приложение создало требуемую строку в таблице TRANSACTION. Однако любой такой триггер будет запускаться непосредственно после вставки строки в таблицу WORK, то есть до того как приложение получит шанс вставить новую строку в таблицу TRANSACTION. Таким образом, триггер не сможет увидеть строку, которую собирается вставить приложение. Другое решение — потребовать от приложения создать строку в таблице TRANSACTION перед тем, как вставить новую строку в таблицу WORK. Но в этом случае мы переопределяем связь так, что теперь строка в таблице TRANSACTION требует строки в таблице WORK. Поэтому СУБД откажется вставлять в таблиц' TRANSACTION строку, не имеющую родителя, и сделает она это еще до того, как
Логика приложения 471 будет вызван какой-либо триггер таблицы TRANSACTION. Таким образом, триггер, определенный для таблицы TRANSACTION, никогда не получит возможности соз- дать требуемую строку в таблице WORK. Одно возможное, хотя и не очень красивое, решение заключается в том, чтобы создать пару триггеров. Первый из них будет создавать строку в таблице TRANSACTION при вставке строки в таблицу WORK. Второй триггер будет удалять строку, вставленную но умолчанию, когда приложение захочет вставить строку в таблицу TRANSACTION. При таком подходе, если приложение не создаст тре- буемой строки, будет использоваться строка, вставленная триггером. Если пред- ложение создаст новую строку в таблице TRANSACTION, то вставленная по умолча- нию строка будет предварительно удалена Эта пара триггеров представлена в листингах 10.8, а, и 10.8, б. Триггер, изобра- женный в листинге 10.8, а, создает строку по умолчанию в таблице TRANSACTION Сначала он проверяет, пет ли в этой таблице существующей строки с таким WorkID; если нет, он вставляет новую строку. Второй триггер (листинг 10.8, б) удаляет строку, созданную первым триггером, когда пользователь вставляет со- ответствующую строку в таблицу TRANSACTION. Листинг 10.8, а. Триггеры для реализации ограничения обязательного потомка: Customerlnterests_Update CREATE OR REPLACE TRIGGER EnforceTransChild AFTER INSERT ON WORK FOR EACH ROW DECLARE RowCount int; NewID int; BEGIN newID := :new.WorkID; SELECT Count!*) INTO rowCount FROM TRANSACTION WHERE WorkID = newID AND CustomerlD IS NULL: If rowCount - 1 then /* Вставляем новую строку в таблицу TRANSACTION, поскольку соответствующей строки в ней еще нет */ INSERT INTO TRANSACTION (TransactionlD. DateAcquired. WorkID) VALUES (TranslD.NextVal. SysDate. newID): End If, END.
472 Глава 10. Работа с базами данных в Oracle 9i Листинг 10.8, б. Триггеры для реализации ограничения обязательного потомка: RemoveDupTrans CREATE OR REPLACE TRIGGER RemoveDupTrans BEFORE INSERT ON TRANSACTION FOR EACH ROW /* Удаляем дубликат дочерней строки, если необходимо */ BEGIN DELETE FROM TRANSACTION WHERE WorkID = :new.WorkID AND CustomerlO IS NULL AND TransactionlD <> :new.TransactionlD: END: / Тем не менее это решение нельзя назвать удовлетворительным. Еще одна альтернатива, более сложная в реализации, но эстетически более привлекатель- ная, — потребовать от приложения, чтобы новые произведения добавлялись в ба- зу данных через представление, содержащее все необходимые данные для таблиц WORK и TRANSACTION. В этом случае вставку данных из представления WORK/ TRANSACTION в таблицы WORK и TRANSACTION осуществлял бы триггер, а прямую вставку строк в эти таблицы следовало бы запретить. (См. Проект (8).) Обработка исключений В пашем изложении опущена тема обработки исключений в PL/SQL. Это заслу- живает сожаления, ибо обработка исключений важна и полезна. Но дело в том, что эта тема является слишком обширной, чтобы обсуждать ее здесь. Однако, если вы в будущем собираетесь программировать на PL/SQL, обязательно изучи- те этот важный вопрос Обработка исключений может использоваться в любых видах процедур на PL/SQL, но особо она полезна в предваряющих и замещаю- щих триггерах для отмены незафиксированных обновлений. Исключения необ- ходимы потому, что в Oracle откат транзакции невозможно произвести в теле триггера. Вместо этого можно использовать исключения для генерации преду- преждении и сообщений об ошибках. Исключения также дают Oracle больше ин- формации о том, что делает триггер. Словарь данных Oiacle поддерживает исчерпывающий словарь метаданных. Этот словарь описы- вает структуру таблиц, последовательностей, представлений, индексов, ограниче- нии, хранимых процедур и многого другого. Он также содержит исходные тексты процедур, функций и триггеров. И это еще не все. В габлице DICT словаря метаданных содержатся данные, описывающие сам оварь. ы можете запрашивать данные из этой таблицы, чтобы узнать больше о содержимом словаря данных, но имейте в виду, что она имеет большие разме-
Словарь данных 473 ры. Например, если вы запросите имена всех таблиц словаря данных, вам будет возвращено более 800 строк. Предположим, вы хотите узнать, какие таблицы с информацией о пользова- тельских и системных таблицах имеются в словаре данных. В этом вам поможет следующий запрос: SELECT Table_Name. Contents FROM 0IСТ WHERE Table_Name LII C^TABLESD: Будет возвращено около двадцати пяти строк. Одна из таблиц будет назы- ваться USER_TABLES. Чтобы увидеть столбцы этой таблицы, введите DESC USER_TABLES: Вы можете использовать эту стратегию для получения из словаря метадан- ных информации об интересующих вас объектах и структурах. В табл. 10.2 пере- числены многие из представлений и указано их назначение. Таблицы USER_SOURCE и USER-TRIGGERS полезны, когда требуется узнать, исходные тексты каких проце- дур и триггеров хранятся в настоящий момент в базе данных. Таблица 10.2. Метаданные в Oracle Имя таблицы Содержимое DICT Метаданные, описывающие словарь данных USER_CATALOG Список таблиц, представлений, последовательностей и других структур, принадлежащих пользователю USER_TABLES Структуры таблиц пользователя USER_TAB_COLUMNS Потомок таблицы USER_TABLES Содержит данные о столбцах таблиц. Синонимом является COLS USER_VIEWS Пользовательские представления USER-CONSTRAINTS Пользовательские ограничения USER_CONS_COLUMNS Потомок таблицы USER-CONSTRAINTS. Содержит столбцы, на которые наложены ограничения USER-TRIGGERS Метаданные, описывающие триггеры. Запрашивайте столбцы Trigger-Name, Trigger Туре и Trigger Event. Предупреждение: Trigger- Body в действительности не содержит исходного кода триггера USER_SOURCE Чтобы получить текст процедуры MYTRIGGER, введите SELECT Text FROM USER-SOURCE WHERE Name='MYTRIGGER' AND Type-PROCEDURE' На данном этапе вы обладаете достаточным знанием SQL, чтобы самостоя- тельно Исследовать словарь метаданных. Имейте в виду, что Oracle записывает Нее имена в верхнем регистре Если вы ищете триггер On_Customer_Insert, вам следует иткагь имя ON_CUSTOMER. INSERT.
474 Глава 10. Работа с базами данных в Oracle 8i ЛЙф Z > Управление параллельной обработкой Oracle поддерживает три различных уровня изоляции транзакций и вдобавок позволяет приложениям налагать блокировки явным образом. Явное наложение блокировок, однако, не рекомендуется, поскольку оно может войти в конфликт со стратегией блокировки, применяемой Oracle по умолчанию, и, кроме тою, уве- личивает вероятность взаимной блокировки транзакций. Прежде чем мы будем обсуждать уровни изоляции транзакций, необходимо кратко рассмотреть то, как Oracle обрабатывает изменения в базе данных. Oracle ведет учет числа изменений в системе (System Change Number, SCN), которое представляет собой глобальное значение, увеличивающееся на единицу всякий раз, когда в базе данных производится изменение. Когда изменяется строка, те- кущее значение SCN сохраняется вместе со строкой. Одновременно исходный образ строки помещается в сегмент отката (rollback segment) — буфер, поддер- живаемый Oracle для выполнения отката и записи транзакций в журнал. Исход- ный образ включает в себя значение SCN, которое было записано в строке до из- менения. Завершив обновление, Oracle увеличивает SCN. Допустим, приложение выдает SQL-оператор вида UPDATE MYTABLE SET MyColumnl = 'Новое_3начение' WHERE MyColumn2 = 'Что-нибудь'; Сначала записывается значение SCN, имевшее место в момент запуска опера- тора. Назовем это значение SCN оператора. При обработке запроса, в данном случае при поиске строк, в которых MyColumnZ = 'Что-нибудь', Oracle выберет толь- ко те строки, которые содержат завершенные изменения и имеют SCN, меньший или равный SCN оператора. Если Oracle находит строку с завершенным изме- нением, SCN которой превышает SCN оператора, она ищет в сегменте отката версию этой строки с завершенным изменением, SCN которой меньше, чем SCN оператора. При таком способе обработки SQL-операторы всегда считывают согласо- ванный набор значений — те значения, которые были записаны до или в мо- мент запуска оператора. Как вы увидите, эта стратегия иногда применяется и к транзакциям. В этом случае все операторы в транзакции считывают строки, SCN которых не превышает значение SCN, имевшее место на момент начала транзакции. Обратите внимание, что Oracle считывает только завершенные изменения. Следовательно, «грязное» чтение невозможно. Oracle поддерживает три уровня изоляции транзакций: «завершенное чтение», «сериализуемость» и «только чтение» (read only). Первые два уровня изоля- ции определены в стандарте ANSI 1992 года, а уровень «только чтение» явля- ется уникальным для Oracle. В таблице 10.3 приведена характеристика этих уровней изоляции.
Управление параллельной обработкой 475 Таблица 10.3. Уровни изоляции транзакций в Oracle Уровень изоляции Описание Завершенное чтение Уровень изоляции, используемый Oracle по умолчанию. «Грязное» чтение невозможно, но повторное чтение может дать различные результаты. Возможно возникновение фантомов. Каждый оператор считывает согласованные данные. Когда налагается блокировка на обновление, операторы откатываются и запускаются вновь по необходимости. Взаимная блокировка обнаруживается, и один из операторов, вызвавших ее, откатывается Сериализуемость «Грязное» чтение невозможно. Повторное чтение дает один и тот же результат, фантомы невозможны. Все операторы в транзакции считывают согласованные данные. Ошибка Cannot Serialize (Невозможно сериализовать) возникает, когда транзакция пытается обновить или удалить строку с завершенным изменением, которое произошло после начала транзакции. Кроме того, эта ошибка возникает, когда транзакции или операторы, налагающие блокировку, фиксируют свои изменения, а также когда транзакция откатывается вследствие взаимной блокировки. Обработку исключения «Cannot Serialize» необходимо производить в прикладн ix программах Только чтение Все операторы считывают согласованные данные. Невозможны вставка, обновление или удаление Явные блокировки Не рекомендуются Уровень изоляции «завершенное чтение» Вспомните из главы 9, что при уровне изоляции «завершенное чтение» «грязное» чтение невозможно, однако чтение может быть невоспроизводимым, и могут воз- никать фантомы. «Завершенное чтение» — это уровень изоляции транзакции, применяемый в Oracle по умолчанию, поскольку Oracle никогда не считывает несохраненные изменения. При уровне изоляции «завершенное чтение» каждый оператор по отдельно- сти согласован, но два различных оператора в одной и той же транзакции могут считать несогласованные данные. Это то же самое, что согласованность на уровне оператора, как она определена в предыдущей главе. Если требуется согласо- ванность на уровне транзакции, необходимо использовать уровень «сериализуе- мость». Однако не смешивайте согласованность па уровне оператора с пробле- мой потери обновления. В Oracle потерянные обновления невозможны, так как она никогда не читает «грязные» данные. Из-за того, как Oracle использует SCN, ей не требуется налагать блокировки при чтении. Но перед тем как изменить пли удалить строку, Oracle наложит на нее монопольную блокировку. Если другая транзакция наложила монопольную блокировку па данную строку, оператор будет ждшь. Если наложившая блоки- ровку транзакция откатываемся, изменение пли удаленно выполняется. Если наложившая блокировку транзакция сохраняется в базе данных, то оператору иередаеи я новое значение SCN, п сам онера гор (а не транзакция)
476 Глава 10. Работа с базами данных в Oracle 9i откатывается и запускается заново. Кшда происходи! огк«н оператора, изме- нения. уже произведенные этим оператором, отменяются с помощью сегментов отката. Вследствие использования монопольных блокировок могут возникать ситуа- ции взаимной блокировки. Когда такое происходит, Oracle обнаруживает взаим- ную блокировку с помощью графа ожидания (wait-for graph) и производит откат одного из вызвавших конфликт операторов. Уровень изоляции «сериализуемость» Как вы узнали из главы 9, при уровне изоляции «сериализуемость» «грязное» чтение невозможно, чтение всегда является воспроизводимым и фантомы возни- кать не могут. Oracle поддерживает этот уровень изоляции, но для его работы не- обходимо участие прикладной программы. Чтобы изменить уровень изоляции транзакции внутри самой транзакции, ис- пользуйте команду Set. Следующий оператор установит уровень изоляции «се- риализуемость» на время выполнения транзакции: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, Чтобы изменить уровень изоляции для всех транзакций в сессии, восполь- зуйтесь командой ALTER: ALTER SESSIONS SET ISOLATION-LEVEL SERIALIZABLE: Когда установлен уровень изоляции «сериализуемость», Oracle сохраняет зна- чение SCN в момент запуска транзакции. Назовем это значение SCN транзак- ции. Пока транзакция выполняется, Oracle считывает только те зафиксирован- ные изменения, для которых значение SCN не превышает SCN транзакции. Сле- довательно, чтение всегда является воспроизводимым, а фантомы невозможны. Пока транзакция не пытается обновить пли удалить какую-либо строку с за- вершенным изменением, SCN которой больше SCN транзакции, обработка транз- акции будет идти своим чередом. Если же транзакция попытается обновить или удалить такую строку, Oracle выдаст ошибку Cannot Serialize (Сериализация невозможна). Здесь должна сыграть свою роль прикладная программа. Она мо- жет зафиксировать сделанные изменения, либо выполнить откат всей транзак- ции или предпринять какое-то другое действие. Любая программа, выполняемая с уровнем изоляции «сериализуемость», должна содержать такую обработку ис- ключений. Кроме того, когда транзакция, выполняемая при уровне изоляции «сериали- зуемость», пытается обновить или удалить строку, на которую другой транзак- цией или оператором наложена монопольная блокировка, транзакция ждет. Если происходит откат транзакции пли оператора, наложившего блокировку, обработка транзакции может быть продолжена. Если же наложившая блокиров- ку транзакция сохраняется, Oracle выдает ошибку Cannot Serialize, и приложение должно обработать это исключение.
Безопасность 477 Подобным же образом, если произошел откат сериализуемой транзакции вследствие взаимной блокировки, произойдет ошибка Cannot Serialize. уровень изоляции «только чтение» При этом уровне изоляции транзакция считывает только те строки с завершен- ными изменениями, для которых значение SCN меньше или равно SCN транзак- ции. Если транзакция обнаруживает строки с завершенными изменениями, в ко- торых значение SCN превышает SCN транзакции, Oracle обращается к сегментам отката и реконструирует строку в том виде, как она была до начала транзакции. На этом уровне изоляции запрещены вставка, обновление и удаление. Дополнительные замечания о блокировках Приложение может налагать блокировки явным образом, используя форму SELECT FOR UPDATE оператора SELECT. Это не рекомендуется, и вам не следует это делать, пока вы не узнаете о блокировках в Oracle гораздо больше, чем опи- сано здесь. Oracle использует большое разнообразие типов внутренних блокировок для обеспечения описанных здесь уровней изоляции. Существует, например, коллек- тивная блокировка строки, а также несколько типов табличных блокировок. Есть и другие блокировки, используемые Oracle для своих нужд. Побольше о них можно узнать из документации по Oracle. Чтобы снизить вероятность конфликта блокировок, Oracle не дает возмож- ности распространять блокировки с одного уровня на другой. Строчные блоки- ровки остаются строчными, даже если их насчитываются сотни на сотнях строк аблицы. Эта стратегия отличается от стратегии SQL Server, как вы узнаете из следующей главы. Oracle Corporation заявляет, что нерасширение блокировок является преимуществом, и возможно, что это так, особенно если учитывать ар- хитектуру блокировок Oracle в целом. Безопасность Oracle предлагает надежные и всеохватывающие меры безопасности. Структурные связи основных компонентов системы безопасное и Oracle показаны на рис. 10.19. Таких компонентов четыре: УЧЕТНАЯ ЗАПИСЬ, ПРОФИЛЬ, СИСТЕМНАЯ ПРИВИЛЕГИЯ и РОЛЬ УЧЕТНАЯ ЗАПИСЬ — это учетная запись пользователя, например SYSTEM, MaryJane, Fred и i. д. ПРОФИЛЬ представляет собой совокупность максимальных объемов системных ресурсов, присвоенную учетной записи. На рис. 10.20 по- Казан типичный профиль. Обратите внимание, что профиль ограничивает как машинные ресурсы, гак и ресурсы базы данных; кроме того, он используется Мя управления паролями, как описывается в следующем разделе. Согласно
478 Глава 10 Работа с базами данных в Oracle 9[ рис. 10.19, любая учетная запись имеет ровно одни профиль, нс, один и гот же профиль может быть присвоен множеству учетных записей Рис. 10.19. Основные компоненты системы безопасности Oracle Рис. 10.20. Определение профиля в Oracle Системные привилегии учетной записи гий и по^ ги°и записи может быть назначено множество системных привиле- вие с пнйк пт 1,сге,миая привилегия — это право выполнять определенное дейст- иримеп тяб *aitlIfn п азе данпых, со структурным элементом базы данных (на- ресупсов ОгХТ ПреДСтаБЛе™ем или индексом) или с одним из системных щепия таблиц) На пис'То’^ Пр°?ран™м на Физическом носителе для разме- вилегий л° ’21 изобРажено окно редактирования системных прп- UNLIMITED TABLESPATF Г'1ИС11 SYSTEM’ Здесь показана только одна привилегия - Другие ппппипаг (неограниченное пространство для размещения таблиц) 1 XS “ХбХ"азна,,и,ы у™п заlc"S¥STEM>
Безопасность 479 Рис. 10.21. Привилегии, назначенные учетной записи SYSTEM Роль может иметь множество системных привилегий, а также иметь собствен- ные роли. На рис. 10.22, а, учетной записи SYSTEM назначено три роли. Учетная запись SYSTEM наследует роли и привилегии каждой из этих трех ролей. Напри- мер, учетной записи SYSTEM была присвоена роль SALES_HISTORY_ROLE, системные привилегии которой показаны на рис. 10.22, б. Вместе с этой ролью учетная за- пись SYSTEM получит и четыре принадлежащих ей привилегии. Как видно из рис. 10.19, ролям могут также присваиваться роли. В этом слу- чае роль наследует все роли и привилегии назначенных ей ролей. Таким образом, системные привилегии учетной записи включают в себя все системные привилегии, непосредственно присвоенные этой учетной записи, плюс все системные привилегии принадлежащих ей ролей, плюс привилегии всех ролей, которыми обладают эти роли, и так далее — по всем}' множеству ролей, прямо или косвенно назначенных учетной записи. В нашем примере учетной записи SYSTEM была присвоена системная привилегия UNLIMITED TABLESPACE (см. рис. 10.21), а кроме того, эта учетная запись получила все системные привилегии ролей AQ_ADMINISTRATOR_ROLE, DBA и SALES_HISTORY_ROLE (см. рис. 10.22, я), плюс все привилегии, унаследованные этими ролями. Роли упрощаюг администрирование базы данных. Если бы не было ролен, ка- ждой учетной записи приходилось бы явно присваивать все необходимые при- вилегии, одну за другой. Этот трудоемкий процесс приходилось бы повторять каждый раз при создании повой учетной записи. Использование ролей упрощает Процедуру; достаточно одни раз присвоить роли совокупность привилегий, и, когда № {юль будет назначена учетной записи, данная учетная запись автоматически получит все ее привилегии. Далее, когда у роли отбирается некоторая привиле- гия, Все учетные записи, имеющие эту роль, также теряют данную привилегию
4СД Глава 10 Работа с базами данных в Oracle pl а [CREATE SNAPSHOT |DROP ANY DIRECTORY QUERY REWRITE i-^JAVA.ADMIN ±-WJAVA_DEPLOY -? LOGSTOBY-AOMINISTRAT ^OEM^MONITOR WOLAP_DBA - -®RECOVERY_CATALOG_Oc/ «RESOURCE I Roles Granted &OSyslem Privileges Gran -JR CREATE DIMENSlO -•B CREATE SNAPSHO Г. -® DROP ANY DIREC' 4R QUERY REWRITE ®O0H|ecl Privileges Grante vOconsumer Groups Grant, f >’®SELECT_CATALOG_ROLE (l-WWKUSER t >‘®VJM_ADMirj_POLE SY'eXOBADMirj ^□Profiles <5-® DEFAULT •^XJusers Assigned *'Л*&СЧЛГ»\«ЧЛ ___ Ajnu<lCrS»O Oac«»i R-w t lyusml Object, x*. foatfaaie___ , j < ADMINISTER DATABASE TRIGGER ADMINISTER RESOURCE MANAGER ALTER ANY CLUSTER ALTER ANY DIMENSION ALTER ANY EVALUATION CONTEXT ALTER ANY INDEX : ALTER ANY INDEXTYPE ALTER ANY LIBRARY ALTER ANY OUTLINE ALTERANY PROCEDURE ALTER ANY ROLE ALTER ANY RULE ALTER ANY RULE SET ..I i-Rrry.qp t ; Oranittf ^retort PrMlecie create dimension tile ЛЖ! Г0СН1 ?vy:.1rticr ЦИЬ IA1.ES_HI8TC*RY_RC€E LeU<jjriMi СоишЬ?, SLwtolw*!’ 6 Рис. 10.22. Роли учетной записи: а — роли, назначенные учетной записи SYSTEM; о — привилегии, присвоенные роли SALES. HISTORY^ ROLE
Безопасность 481 Идентификация пользователей с помощью учетных записей На рис. 10.23 показано окно программы Oracle Enterprise Manager Console, позво- ляющее создать новую учетную запись пользователя. Администратор базы данных присваивает имя учетной записи, назначает ей профиль и метод идентификации н устанавливает другие параметры. На рис. 10.23, а, для идентификации пользовате- ля используется пароль. Учетной записи был назначен новый пароль, но при этом был установлен флажок Expire password now (Срок действия пароля истекает немед- ленно). Это означает, что, когда пользователь в первый раз войдет в систему с этой учетной записи, программа сообщит ему об истечении срока действия его пароля и необходимости задать новый пароль. Это принудит пользователя собственно- ручно задать пароль для учетной записи, прежде чем он сможет воспользоваться ею. На рис. 10.23, б, показана учетная запись, которая использует внешнюю по от- ношению к Oracle идентификацию. Это значит, что операционная система удо- стоверяет личность данного пользователя и передает все необходимые иденти- фикационные данные Oracle. Между прочим, если идентификация пользователя производится операционной системой, имя учетной записи данного пользовате- ля должно начинаться с символов OPS$. На рис. 10.23, б, операционная система идентифицирует пользователя с именем MARYJANE в домене MYD0MAIN1. Симво- лы OPS$ не являются частью имени пользователя в операционной системе: это префикс, требуемый Oracle для таких учетных записей. Мы будем использовать идентификацию средствами операционной системы в главах 12 и 13, когда будем обсуждать обработку баз данных Oracle с использованием встроенных средств защиты (Integrated Security) ASP и ASP.NET. В Oracle имеется множество полезных функций и служебных программ для управления паролями. На рис 10.24 показана вкладка Password (Пароль) для про- филя под названием USERPROFILE (профиля, созданного ранее администратором базы данных). Управление паролями всех учетных записей, базирующихся на данном про- филе, происходит согласно заданным на этой вкладке установкам. В частности, срок действия паролей истекает через 60 дней, и, если пользователь не поменяет свой пароль через 30 дней после истечения этого срока, учетная запись будет за- блокирована (сделается недоступной). Во втором разделе этой вкладки указано, что Oracle будет хранить два «поколения» паролей пользователей. Это означает, что пользователь не сможет выбрать тот же пароль, что и раньше, пока он не ис- пользует но крайней мере два отличных от пего пароля. Третий раздел вкладки определяет, насколько сильным должен быть пароль: сколько в нем должно быть символов, обязательно ли использовать буквы верхнего и нижнею pci ист рои и цифры, и должен ли пароль содержать специальные симво- лы Значение Default (J Jo умолчанию) в поле Complexity function (Функция сложно- сти) означает, что будет m пользоваться политика, заданная по умолчанию для базы данных (Волге подробную информацию па эту тему вы найдете в документа- ции по Oracle ) Наконец, последний раздел вкладки ощюделяет действия системы п случае неудачной попытки идеи in<j>iiKaiuiii. В данном случае, если пользователь сделал шесть или более неудачных попыток ввести пароль, Oracle блокирует Данную учетную саипсь, и она будет осгавапюя недоступной в течение 10 дней.
482 Глава 10. Работа с базами данны в Oracle 9I CraiioUter $YSTt«*.:-VRG Oimtwl нт»1 M"m Nam». MARV_JAN£| V Prof® DEFAULT к„АЛ»аИсаг<;п password ^htsrPasswmd СогЛп-™ Vftpra piMwnrdNow TsWewacs» _ _____ ult Тон,о6г»1 •ЛчЧг.***>||Мв» Matvs LortMl VnlocXed Areata I ShwzS Hsia a 6 ИС" Идентификация учетной записи: a — идентификация по паролю; б — внешняя идентификация
Резервное копирование и восстановление в Oracle 483 Рис. 10.24. Управление паролями с помощью профиля В этом разделе главы были вкратце рассмотрены средства безопасности, предо- ставляемые Oracle. Разумеется, сами по себе эти средства не делают базу данных защищенной. Организации, использующие базы данных, должны разрабатывать планы защитных мер и политику, определяющую, как должны применяться средства безопасности. Обсуждение таких планов выходит за рамки данной кни- ги, но о них вы узнаете из курса системного программирования. Резервное копирование и восстановление в Oracle В Oracle имеется превосходный набор средств и служебных программ для ре- зервного копирования и восстановления. Они обладают большой гибкостью, что позволяет применять их для самых разных типов баз данных — от небольших коллективных, копирование которых может осуществляться ночью, в нерабочее время, до огромных межоргапизационных, которые функционируют круглые cyjj<H без выходных и не должны цп на минуту прекращать работу. Средства восстановления Oracle Oracle поддерживает три типа файлов, важных для резервного копирования и вос- становления. Файлы данных (datafiles) содержат данные пользователя и систем- ную информацию. Из- ча способа, применимого Oracle для сброса буферов дан- ных на диск, в произвольны!! момент времени файлы данных могут содержать как сохраненные, так и песохраиепиые изменепия. Разумеется, обработка транзак- ций в Oracle происходи г таким образом, что песохрапенпые изменения в конечном
484 Глава Ю. Раоота с базами счете либо сохраняются в базе данных, либо удали» >,« а, цо а «< ним«е» > данных, взятом в любой отдельно взятый момент времени, несохранениы^ ния будут присутствовать. Таким образом, при остановке Oracle или «ыподим- определенных видов резервного копирования необходимо П|«>илй<лии файлов данных, чтобы в них оставались только сохраненные изменения Файлы отката (ReDo files) содержат журналы изменений б.мы данные представляют собой резервные конин сегментов отката, используемых пои щ раллельной обработке транзакции. Контрольные файлы (control Шее) эд большие файлы, в которых перечисляются имена, местоположение и содержимого различных файлов, используемых Oracle Контрольные '|;.>йлы зд то обновляются, и они должны быть доступны для Oracle, чтобы база могла функционировать. Есть два типа файлов отката. Текущие, или онлайновые, файлы отката (овЫ ReDo files) хранятся на диске и содержат сегменты отката от недавних измене- ний в базе данных. Архивные, или оффлайновые файлы отката (offline ReDo file) - это резервные копии текущих файлов отката. Они хранятся отдельно от текущих файлов отката и не обязательно на дисковом накопителе. Oracle может работать в одном из двух режимов: ARCHIVELOG и NOARCHIVELOG. В режиме ARCHIVELOG ври заполнении текущих файлов отката их содержимое копируется в архивные фай- лы отката. Контрольные файлы и текущие файлы отката настолько важны, что Grade рекомендует хранить по две активные копии каждого из них. Этот процесс назы- вается в терминологии Oracle мультиплексированием (multiplexing). Типы сбоев Техника восстановления в Oracle зависит от типа возникшего сбоя. В случае сбоя приложения (application failure), произошедшего, например, из-за ошибки в логи- ке приложения, Oracle просто выполняет откат несохраненных изменений, сде- ланных данным приложением, используя для этого сегменты отката в от ратми- ной памяти и текущие файлы отката. Другие типы сбоев подразумевают более сложный процесс восстановления. Сбой экземпляра (instance failure) — это сбой в самой СУБД Oracle, произошедший из-за ошибки операционной системы или аппаратного обеспечения компьютера. Сбой носителя (media failure) происходит, когда Oracle оказывается не в состоя- нии произвести запись в физический файл. Причина может заключаться в т что имеется повреждение головки диска или другая дисковая ошибка, что нуж ное устройство не включено в сеть или что файл испорчен. Восстановление после сбоя экземпляра сматривает - после с^оя экземпляра, она в первую очередь про- файлы. Затем она об ” ^аил’ чтобы определить, где находятся все остальные щих файлов отката V? атывает Файлы данных, используя информацию из гекЦб ЭТОМ выпол™™ся (накатываются) ^изменения. за₽е- ф илах отката, но не сохраненные в файлах данных на моме"т
Резервное копирование и восстановление в Oracle 485 возникновения сбоя. В ходе этого процесса сегменты отката заполняются запися- ми транзакций из файла отката. По завершении наката файлы данных могут содержать несохраненные изме- нения. Эти изменения могли присутствовать в файлах данных в момент сбоя эк- земпляра, а могли появиться в результате наката. Так или иначе, Oracle удаляет эти изменения, используя сегменты отката, созданные в ходе выполнения нака- та. Чтобы незавершенным транзакциям не приходилось дожидаться отката, все сохраненные транзакции помечаются как мертвые (dead transactions). Если но- вая транзакция оказывается заблокированной изменением, которое произведено мертвой транзакцией, диспетчер блокировок снимает блокировки, удерживаемые мертвой транзакцией. При восстановлении после сбоя экземпляра архивные файлы отката не ис- пользуются. Следовательно, восстановление после сбоя экземпляра может быть произведено как в режиме ARCHIVELOG, так и в режиме NOARCHIVELOG Восстановление после сбоя носителя Для восстановления после сбоя носителя используется резервная копия базы данных. Если база данных работала в режиме NOARCHIVELOG, то ничего больше сделать нельзя Архивные файлы отката будут бесполезны, поскольку они будут содержать записи изменений, сделанных значительно позже, чем была сделана резервная копия. Организация должна найти какой-то другой способ восстанов- ления данных. (Между прочим, начинать думать о таких вещах нужно гораздо раньше!) Если Oracle работала в режиме ARCHIVELOG, то в архиве после сбоя будут со- держаться копии текущих файлов отката. В этом случае база данных восстанав- ливается из резервной копии, а затем с помощью архивных файлов отката про- изводится накат. По завершении наката изменения, сделанные несохраиенными транзакциями, отменяются путем описанного выше процесса отката. Существуют два вида резервных копий. Согласованная резервная копия (con- sistent backup) — это такая резервная копия, в которой из файлов данных удале- ны все несохраненные изменения. Для создания такой копии работа базы дан- ных должна быть приостановлена, все буферы должны быть сброшены на диск, а изменения, произведенные несохраиенными транзакциями, должны быть уда- лены. Ясно, что этот вид резервного копирования неприемлем для баз данных, функционирующих в режиме 24 х 7. Несогласованная резервная копия (inconsistent backup) может содержать несо- хранеиные изменения. Такого рода резервное копирование производится Oracle «на лету», в ходе обработки базы данных. Чтобы восстановить базу данных из несогласованной резервной копии сначала эту копию делают согласованной. Для этого па основании записей из архивных журналов записываются или отме- няются все транзакции, которые выполнялись в момент, когда делалась резерв- ная копия. Несогласованную резервную копию можно делать не со всей базы Данных, а с какой-то ее части. Так, в приложении, работающем в режиме 24 х 7, каждую ночь можно копировать одну седьмую часть базы данных. В результате за неделю будет сделана резервная копия всей базы данных
486 Гпяаа 10. Работа с базами данных в СсаЮ W rh к-le ((hade Recovery MaiWjer RM AX) «тъ Менеджер <“ЗД8И‘”‘ ^рй“М* Кв"** И “* служебная нрограм. «. I ' AN Iin„l(wwr создать специальную 6<»у ддямьк становления балы д.н . . ацмю архишшх файлах и oiw-fwUMMX «в ^='.№. О№№ >’<“ "PO4M.MMU ВЫХОЛИТ » рами, изложения. Вопросы, не затронутые в данной главе Есть несколько важных аспектов Oracle, которые не обсуждались нами в этой главе Во-первых, Oracle поддерживает объектно-ориентированные структуры, которые разработчики могут использовать для создания собственных абстрактных типов данных. С помощью Oracle можно также создавать и обрабатывать базы данных, представляющие собой гибриды традиционных и объектных баз, ных. Такие гибриды называются объектно-реляционными базами данных (object- relational databases); их мы будем обсуждать в главе 18. Далее следует отметить, что версия Oracle для предприятии (Enterprise >п поддерживает обработку распределенных баз данных, которые хранятся более чем на одном компьютере. Этот вопрос будет обсуждаться в главе 17. Помимо этого есть еще несколько служебных программ Oracle, которые не были нами упомянуты. Например, Oracle Loader — это утилита для ввода больших 4ъемов информации в базу данных Oracle. Другие утилиты предназначены для измере- ния и оптимизации производительности Oracle. Тем не менее наиболее важные аспекты и вопросы, связанные с Oracle, на- шли свое отражение в этой главе. Если вы разобрались с представленными здесь базовыми концепциями, то у вас уже есть многое для того, чтобы стать успеш- ным разработчиком баз данных в СУБД Oracle. Резюме Oracle — мощная и надежная СУБД, работающая под управлением множества операционных систем и содержащая в себе много различных продуктов. В этой главе отписана работа с программой SQL*Plus, с помощью которой можно созда- обрабатывать процедуры на языках SQL и PL/SQL во всех версиях Oracle. ' ато язык> Расширяющий возможности SQL за счет добавления в него . нструкции, специфичных для языков программирования. 11гяНлпДдТЬ- *аЗУ данных Е Oracle можно с помощью мастера Database Contig' cryj SS1S ant, предоставляемых Oracle специализированных процедур или ^ZfEATE DATABASE- Уастер Database Configuration Assistant создает редактопс данных и Фа”лы журналов. SQL*Plus содержит текстовый В многострочном буф^е SoSurMr^1"1'1' КОТОрЬ,й хранит тск>’,ций оператор вым редактором, таким ка^Блокнот НаСТР°ИТЬ Иа работУ с внеШНИМ теКСТ°*
Резюме 487 Можно вводить SQL-операторы непосредственно в командной оболочке SQL*Plus, а можно записывать их в текстовые файлы и запускать эти файлы на выполнение из SQL*Plus. Таким образом можно выполнить любой из операто- ров, рассмотренных нами в главах 6-8. Oracle Entei pi ise Manager Console — это программа, предоставляющая графи- ческий интерфейс для управления базами данных Oracle. С ее помощью можно создавать, удалять и модифицировать различные структуры базы данных — на- пример, таблицы и представления, — а также управлять учетными записями, па- ролями, ролями и привилегиями. Последовательности операторов PL/SQL и программы на языке Java могут записываться в базу данных в виде хранимых процедур и вызываться из других программ на PL/SQL или из прикладных программ. Примеры хранимых процедур приведены в листингах 10.3 и 10.4 В Oracle также имеются триггеры — програм- мы на PL/SQL или Java, которые вызываются при наступлении определенного события в базе данных. Примеры предваряющих, завершающих и замещающих триггеров приведены в листингах 105-10.8 Oracle поддерживает словарь мета- данных. Метаданные самого словаря хранятся в таблице DICT. Запросив инфор- мацию из этой таблицы, можно ознакомиться с содержимым словаря. Oracle поддерживает три уровня изоляции транзакций: завершенное чтение, сериализуемость и только чтение. Из-за того, как обрабатываются значения SCN, «грязное» чтение в Oracle невозможно. При использовании уровня изоляции «се- риализуемость» прикладная программа должна обрабатывать ошибку «Cannot serialize» («Сериализация невозможна»). Приложения могут налагать блокировки явным образом, используя команду SELECT FOR UPDATE, но это не рекомендуется. Система безопасности Oracle состоит из четырех основных компонентов: учетных записей, профилей, привилегий и ролей. Каждая учетная запись имеет профиль, определяющий предельные объемы системных ресурсов, которые мо- гут быть выделены для этой записи, а также аспекты управления паролями. Привилегией называется право на выполнение определенных действий с ресур- сом Oracle. Учетным записям могут присваиваться роли, которые могут обла- дать привилегиями, а также иметь собственные роли. Учетная запись имеет все системные привилегии, присвоенные ей явно, плюс все системные привилегии принадлежащих ей ролей, плюс привилегии всех ролей, которыми обладают эти роли, и так далее — по всему множеству ролей, прямо или косвенно назначенных учетной записи. Идентификация пользователей может производиться с помощью паролей или средствами операционной системы. Параметру управления пароля- ми определяются в профиле. В процессе резервного копирования п восстановления в Oracle используются три типа <|>айлов: <|>айлы данных, текущие и архивные файлы отката и контрольные файлы. При работе в режиме ARCHIVELOG Oracle записывает в журнал все измене- ния, произведенные в базе данных В случае сбоя приложения или экземпляра Oracle может восстановить базу данных без использования архивного файла журнала. Однако для восстановления после сбоя носителя архивные файлы не- обходимы Резервные копии могут быть согласованными и несогласованными. Несогласованную копию можно сделать согласованной, обработав архивный файл журнала.
Глава 10 Работа с базами данных в Oracle 9* Вопросы группы I ' 1 Опишите общие характеристики Oracle и со- гав пакета программ Grade, ‘ Объясните, почему эти характерно гики порождают значительную савж ность освоения продукта. 2. Что такое SQL*Phis и каковы его функции? 3. Назовите три способа создания базы данных Oracle. Какой способ являет, ся наиболее простым? 4. Объясните, как изменить содержимое строки в буфере SQL Plus. Преддо- ложим, что в буфере находятся три оператора, текущим является оператор 3 а вам необходимо поменять второй оператор с CustID-ЮОО на CustomerID-1000 5. Как настроить рабочий каталог для SQL*Plus? 6. Постройте SQL-оператор, создающий таблицу Т1 со столбцами Cl, С2 и СЗ Пусть С1 является суррогатным ключом. Пусть также С2 содержит текст длиной 50 символов, а СЗ содержит дату. 7. Напишите оператор, создающий последовательность, которая начинается с 50 и имеет инкремент 2 (то есть каждый элемент на 2 больше предыду- щего). Назовите эту последовательность TlSeq. 8. Покажите, как вставить строку в таблицу Т1 (вопрос 6), используя после- довательность, созданную в ответе на вопрос 7. 9. Напишите SQL-оператор, запрашивающий строку, созданную в ответе на вопрос 8. 10. Опишите проблемы, которые связаны с использованием последовательно- стей для столбцов, являющихся суррогатными ключами. И. Напишите SQL-операторы, удаляющие таблицу Т1 и последовательность TlSeq. 12. Напишите SQL-операторы, удаляющие столбец СЗ таблицы Т1. 13. Напишите SQL-операторы, создающие связь между таблицами Т2 и ТЗ. Пусть ТЗ имеет столбец FK1, являющийся внешним ключом и связанный с Т2. и пусть удаления в Т2 должны вызывать удаления в ТЗ. 14. Ответьте на вопрос 13, но не вызывайте удаления в ТЗ. 15. Объясните, как используется функция To_Date 16. Напишите SQL-операторы, создающие уникальный индекс по столбцам С2 и СЗ таблицы Т1. 17. В каких случаях следует использовать индексы? 18. Напишите SQL-операторы, добавляющие в таблицу Т1 новый столбец С4. Пусть этот столбец содержит значения типа Currency, и максимальное зна- чение равно $ 1 000 000. 19. При каких условиях можно удалить столбец из существующей таблицы? При каких условиях можно добавить столбец к существующей таблице? *•1 •Т|
Вопросы группы I 489 21. Покажите, как добавить обязательный (непустой) столбец к существую- щей таблице. ' 22. При каких условиях можно изменить ширину текстового или числового столбца? 23. При каких условиях можно изменить тип данных столбца? 24. Покажите, как добавить ограничение, указывающее, что значение столбца С4 таблицы Т1 не может быть меньше 1000. 25. Покажите, как добавить ограничение, указывающее, что столбец С4 табли- цы Т1 не может быть меньше столбца С5 таблицы Т1. 26. Для базы данных галереи View Ridge, описанной в этой главе, постройте представление, содержащее имя клиента (Name), город (City) и штат (State), в котором он проживает. Назовите это представление CustView 27. Для базы данных галереи View Ridge, описанной в этой главе, постройте представление, содержащее имя клиента и имена авторов всех работ, при- обретенных данным клиентом. 28. Для базы данных галереи View Ridge, описанной в этой главе, постройте представление, содержащее имя клиента и имена всех художников, рабо- тами которых интересуется данный клиент. Поясните, в чем разница меж- ду этим представлением и представлением из вопроса 27. 29. Можно ли объединить представления из вопросов 27 и 28 в одно пред- ставление? Почему? 30 Как обновить соединенное представление с помощью Oracle? 31. Создайте файл с последовательностью операторов PL/SQL, которая опи- сывает структуру таблиц CUSTOMER, ARTIST, WORK, TRANSACTION и CUSTOMER- ARTIST_INT. Дайте файлу имя VRTabs.sql и покажите, как запустить этот файл на выполнение из SQL* Plus. 32. Что означают ключевые слова IN, OUT и IN OUT в процедуре на PL/SQL? 33. Что нужно сделать, чтобы можно было увидеть сообщения, выводимые с помощью пакета DBMS_OUTPUT? Какие ограничения существуют на такой вывод? 34. Объясните, как работает оператор PL/SQL FOR переменная IN имя_курсора. 35. Какой оператор используется для вывода сообщений об ошибках при ком- пиляции триггеров и хранимых процедур? 36. Каков синтаксис оператора BEGIN TRANSACTION в PL/SQL? Как запускается транзакция? 37 Как используются переменные tid и aid в хранимой процедуре в листин- ге 10.3, если в таблице TRANSACTION не обнаружено подходящих строк? Как они используются в случае, если в таблице TRANSACTION найдена ровно одна подходящая строка? 38 Объясните, в чем состоит назначение предварительных, завершающих и за- мещающих триггеров.
Глава 10 Работа с базами данных в Otacto & Каким образом п теле триггера. запушенною обновлением о.. получить значение, которое столбец имел до обновления? Каким «Лри» в коде триггера можно полупив значение. ксророе будет присвоено Объясните, почему для соединенных представлений необходимо #сад»к 490 39. 40. зовать заметающие триггеры. 41. Какое ограничение имеют завершающие три >ы 42. Напишите SQL-оператор, который получает из словаря данных и «ш лиц, содержащих информацию о триггерах. 43. Какие три уровня изоляции транзакций поддерживаются Oracle’ 44. Объясните, как число изменений в системе используется Oracle для счи тывания данных в том состоянии, в каком они были в определенный мо- мент времени. 45. В каком случае в Oracle возможно «грязное» чтение? 46. Объясните, как Oracle обрабатывает конфликтующие блокировки, транзакция выполняется в режиме завершенного чтения. 47, Напишите SQL-оператор, задающий уровень изоляции «сериализуемость» на весь сеанс. 48. Что происходит, когда транзакция, выполняемая в режиме сериализуемо- сти, пытается обновить данные, которые уже обновлены другой транзак- цией? Пусть (1) SCN меньше, чем SCN транзакции; (2) SCN больше, чем SCN транзакции. 49. Сформулируйте три ситуации, в которых транзакция может получи > ис- ключение «Cannot serialize». 50. Объясните, как Oracle обрабатывает уровень изоляции «только чтение». 51. Объясните, как связаны учетные записи, привилегии и роли в системе безопасности Oracle. 52. Какие три типа файлов важны для резервного копирования и восстановле- ния в Oracle? 53. В чем разница между текущими и архивными файлами отката? Как ис- пользуется каждый из этих типов файлов? 54. Что означает термин мультиплексирование в контексте восстановления баз данных в Oracle? 55. Объясните, как в Oracle происходит восстановление после сбоя приложения- 56. Что такое сбои экземпляра и как Oracle восстанавливается после него. Что такое сбой носителя и как Oracle восстанавливается после него? Проект или заданий используйте командную оболочку SQL*PluS ИЛИ программу Oracle Enterprise Manager Console. 1. Установите Oracle и создайте базу данных View Ridge.
Вопросы к проекту FiredUp 491 2. Создайте таблицы, как в листинге 10.1, но не создавайте ограничение Nationality Values. 3. Заполните базу данных информацией. Пусть у вас будет по меньшей ме- ре три клиента, три художника, пять произведений и пять транзакций. Национальность художника должна иметь одно из трех значений: 'German’, 'French’ или 'English'. 4. Напишите хранимую процедуру для чтения данных из таблицы ARTIST и вы- вода их на экран с помощью команды DBMS_OUTPUT.PUT_LINE. 5. Напишите хранимую процедуру, считывающую данные из таблиц ARTIST и WORK. Ваша процедура должна выводить сведения о первом художнике и всех его работах, затем о следующем художнике и т. д. Пусть имя худож- ника, информацию о котором нужно вывести, будет входным параметром процедуры 6. Напишите хранимую процедуру, записывающую в базу данных новый но- мер телефона клиента. Пусть ваша процедура принимает в качестве вход- ных параметров имя клиента, старый код региона, новый код региона, ста- рый номер телефона и новый номер телефона. Прежде всего процедура должна взять имя клиента, старый код региона и старый номер телефона и убедиться, что в базе данных есть только один клиент с такими данны- ми. Если такой клиент не один, процедура должна вывести сообщение об ошибке и завершить свою работу. В противном случае процедура должна записать в базу данных новые код региона и телефон клиента. 7. Создайте таблицу с именем ALLOWEDNATIONALITY (допустимая националь- ность) с одним столбцом Nation. Поместите в эту таблицу значения ’German’, 'French' и 'English'. Напишите триггер, который при вставке и обновлении строки в таблице ARTIST будет искать новое значение столбца Nationality в таб- лице ALLOWED_NATIONALITY. Если поиск завершился неудачно, триггер должен вывести сообщение об ошибке с помощью команды DBMS_OUTPUT.PUT_LINE. Продемонстрируйте корректную работу триггера, используя SQL* Plus. 8. Создайте представление, содержащее все данные из таблиц WORK и TRANS- ACTION. Напишите для этого представления замещающий триггер вставки, который будет создавать новую строку в таблицах WORK и TRANSACTION. Продемонстрируйте корректную работу триггера, используя SQL Plus. Вопросы к проекту FiredUp Создайте с помощью Oracle базу данных со следующими четырьмя таблицами: КЛИЕНТ (И^Клиени, Имя, Телефон, АдресЭлПочты) ГОРЕЛКА (Г^рийныйНзме,-, Тип, Версия, ДатаВыпуска) РЕГИСТРАЦИЯ (ИЙ.мЖс«Ш. ДатаРег) РЕМОНТ-ГОРЕЛКИ (Н /Ме>0№. СерийныйНомер, ДатаРемонта, Описание, Стоимость, ИдКлиента)
Пусть первичные ключи таблиц КЛИЕНТ, ГОРЕЛКА и Р МОНТ ГОРЕЛКИ явзяктц суррогатными ключами. Создай те для них нослсдовашлыюети Создайте связи, реализующие следующие ограничения ссылочном нею 1ии и 4- значение столбца ИдКлиента в таблице РЕГИСТРАЦИЯ существует среди зна- чений столбца ИдКлиента в таблице КЛИЕНТ, ♦ значение столбца СерийныйНомер в таблице РЕГИСТРАЦИЯ существует среди значений столбца СерийныйНомер в таблице ГОРЕЛКА, ♦ значение столбца СерийныйНомер в таблице РЕМОНТ_ГОРЕЛКИ существует среди значений столбца СерийныйНомер в таблице ГОРЕЛКА; ♦ значение столбца ИдКлиента в таблице РЕМОНТ ГОРЕЛКИ существует среди значении столбца ИдКлиента в таблице КЛИЕНТ. Не включайте каскадные удаления. и ♦ ♦ м % 1. Заполните ваши таблицы данными и отобразите их на экране. Создайте хранимую процедуру для регистрации горелки. Процедура полу- чает в качестве входных параметров имя, телефон, адрес электронной по- чты клиента и серийный номер горелки. Если данный клиент уже имеется в базе данных (имя, телефон и электронный адрес совпадают), записывай- те его ИдКлиента в таблицу РЕГИСТРАЦИЯ. В противном случае создайте для этого клиента новую строку в таблице КЛИЕНТ Будем предполагать, что горелка с заданным серийным номером уже существует в базе данных. Если это не так, выведите сообщение об ошибке и отмените изменения, сделанные в таблице КЛИЕНТ. Написав процедуру, протестируйте ее. Создайте хранимую процедуру для регистрации ремонта горелки. Проце- дура получает в качестве входных параметров имя, телефон и адрес элек- тронной почты клиента, серийный номер горелки, описание и стоимость ремонта. Будем предполагать, что заданный серийный номер существует; если это не так, выведите сообщение об ошибке и не производите в базе данных никаких изменений. Используйте существующую строку в табли- це КЛИЕНТ, если имя, телефон и электронный адрес совпадают; в против- ном случае создайте новую строку в таблице КЛИЕНТ. Предположим, что строка в таблице РЕМОНТ—ГОРЕЛКИ должна быть создана. Зарегистрируйте горелку, если необходимо. Создайте представление под названием РегистрацияКлиента, содержащее все данные из таблиц КЛИЕНТ, ГОРЕЛКА и РЕГИСТРАЦИЯ. Создайте замещаю- щий триггер вставки для этого представления. Предположим, что поль- зователь задал значения столбцов ИдКлиента, Имя, Телефон, АдресЭлПочты и ерийныйНомер. Если такого клиента нет в базе данных, создайте для него новую строку в таблице КЛИЕНТ. Зарегистрируйте горелку па этого к.тпен гпрсппл указаниый пользователем серийный номер отсутствует в таблшЮ ЮРЕЛКА, триггер должен вывести сообщение об ошибке и не предпрпнп- мать никаких дальнейших действий. Продемонстрируйте корректную боту триггера. 2. 3. 4. £ 1£в я I? i£a i с .2 (X
Вопросы к проекту Twigs Tree 493 Вопросы к проекту Twigs Tree Создайте с помощью Oracle базу данных с тремя таблицами: ВЛАДЕЛЕЦ (ИмяВладельца, Телефон, Дом, Улица, Город, Штат, Индекс) РАБОТА ( В лн^ни^, ИмяВладельца, Описание, Стоимость, Уплачено, ДатаВыплаты) ДОСТАВКА-СТРУЖКИ (ИмяКлиента, ДатаДоставки. Объем, Стоимость, Уплачено, Да- таВыплаты) Создайте связи, реализующие следующие ограничения ссылочной целостности: ♦ значение столбца РАБОТА.ИмяВладельца существует среди значений столб- ца ВЛАДЕЛЕЦ.ИмяВладельца; ♦ значение столбца ДОСТАВКА_СТРУЖКИ.ИмяКлиента существует среди значе- ний столбца ВЛАДЕЛЕЦ.ИмяВладельца. Включите каскадное удаление. 1. Заполните ваши таблицы данными и отобразите их на экране. 2. Создайте хранимую процедуру, назначающую выполнение работы на опре- деленную дату. Пусть процедура получает все данные о владельце, опи- сание работы и дату в качестве входных параметров. Если клиент уже име- ется в базе данных, используйте существующие данные. В противном случае создайте новую строку в таблице ВЛАДЕЛЕЦ. Добавьте строку в таб- лицу РАБОТА. Протестируйте вашу процедуру. 3. Создайте хранимую процедуру, назначающую доставку стружки на опре- деленную дату. Пусть процедура получает все данные о владельце, дату доставки, объем груза и стоимость в качестве входных параметров. Если клиент уже имеется в базе данных, используйте существующие данные. Не назначайте доставку, если у клиента имеется задолженность по ра- ботам или доставке стружки. Выведите в этом случае сообщение об ошиб- ке с помощью команды DBMS_OUTPUT.PUT_LINE. Задолженность существует, если столбец Стоимость не пуст, а столбец Уплачено является пустым. 4. Создайте представление РаботаДляКлиента, содержащее все данные из таб- лиц ВЛАДЕЛЕЦ и РАБОТА. Создайте для этого представления замещающий триггер вставки. Предположим, пользователь предоставит все данные о сеое, а также дату выполнения и описание работы. Если такого клиента нет в базе данных, создайте новую строку в таблице ВЛАДЕЛЕЦ. Добавьте строку в таб- лицу РАБОТА. Продемонстрируйте корректную работу вашего триггера.
Глава 11 Работа с базами данных в SQL Server 2000 Эта глава описывает основные возможности и функции Microsoft SQL Server 2000 Для иллюстрации используется пример с галереей View Ridge из главы 7. а струк- тура изложения повторяет ход обсуждения задач администрирования баз данных в главе 9. Направленность и охват изложения остаются примерно такими же, каковы они были в предыдущей главе, посвященной Oracle. SQL Server — большой и сложный продукт. В рамках этой главы мы сможем рассмотреть его лишь поверхностно. Цель заключается в том, чтобы подготовить вас к использованию SQL Server в ваших собственных проектах и дать необхо- димые основы, которые позволят вам продолжить изучение этого продукта само- стоятельно или в других курсах. Установка SQL Server 2000 2000 ЛЛ еСТЬ Д»гК С>SQL ScrVer’ Установите программу. Для работы SQL Server Windows2000Р Л °"Т u? j пакетом обновлений Service Pack 5 или новее, Кроме то^ 2 ’Windows 2000 Professional или Windows XP Professional. 250 Мбайт 4L<Te уетСЯ как МИПИМУМ 64 Мбайт оперативной памяти и около Чтобы устаипп^°^°<;1пг,СсРаНСТВа«МОЖНО И меНьшс> 1,0 это не рекомендуется), нистраторскими ппа еП СГ’ во“Д1тге в систему на вашем компьютере с адми- на запуститься ян ЭВами И ВСтавьте компакт-диск. Программа установки долж- ап^и^ехе^Л^ево^катадоге^СВ Г ° Не ”Р0ИСХОДИТ’ На фаЙЛе (Компоненты SQL Served ЛЛ CD’ ,целкните ,,а SQL Server Components сервер баз дан инп ’ ем иа комаиде Install Database Server (Установить обичиую устаю„ку прсдстаыяег выбрав в Meino^nySTn^pa^1^40'’110^’1’1 М0ЖСТС пачать РаботУ с SQL Server. Enterprise Manager. Запусгив этуРУ"ПУ Mlcrosoft SQL Server> a в »c» “ программу Microsoft SQL Servers Шелк» » . пРО|РаммУ> найдите на левой панели значок так же откройте группу SQLServer"?1 “°Ле Л»' ЧТ°бЫ РазвсР,,уть его- затем точно J г er Group. Под именем этой группы вы увидите
Создание базы данных SQL Server 2000 495 значок с именем вашего компьютера, за которым будет следовать (Windows NT) Щелкните на символе «+» рядом с этим значком. После этого окно программы должно будет принять вид, изображенный на рис. 11.1. На этом рисунке видно имя компьютера, с которого была получена эта копия экрана, а именно DBGRV101QA1. Рис. 11.1. Окно программы Enterprise Manager со списком баз данных на сервере Создание базы данных SQL Server 2000 Чтобы создать новую базу данных, щелкните на папке Databases (Базы данных) и выберите New Database (Новая база данных). Введите имя вашей базы данных (здесь VRG) в поле Name (Имя), как показано на рис. 11.2. По умолчанию SQL Server создаст один файл данных и один файл журнала для каждой базы данных. Вы можете создать несколько файлов данных и журна- лов и ассоциировать определенные таблицы и журналы с определенными фай- лами и группами файлов. Однако все это выходит за рамки нашего изложения. Если вы хотите узнать об этом больше, щелкните правой кнопкоп мыши на папке Databases и выберите Help (Справка) Чтобы найти информацию по этой теме, в ле- вой панели окна Help введи ге в поле Search Text (Найти текст) строку «file groups». На данном этапе примите все параметры файлов, которые SQL Server предла- гает по умолчанию Увидеть эти параметры можно во вкладках Data Files (Файлы данных) и Transaction Log (Журнал транзакций). Создав базу данных, oi крон te папку Databases, а в йен — папку с именем вашей базы данных Затем щелкниie па значке Tables (Габлнцы) Окно программы долж- но поел, этою выглядеть как на рис 11.3, только у вас еще не будет никаких Пользовательских таблиц. Вы таблицы, перечисленные у ас на правой панели, — *го системные таблицы, используемые SQL Server 2000 для управления базой данных Кстати, dbo означает database owner — «владелец базы данных». Если вы установили SQL Server и создали эту базу данных, владельцем являетесь вы.
496 Глааа 11 РаЛота с базами данных в SQL Server 2000 Рис. 11.2. Создание базы данных VRG » Суд-' С(дайада?1(дел5 (^т^ятт нЪ]О<П»Ь^^*абПаЫга - Ц “* О S*°'er Group *v; Tables 2? Items '-’fib DBGRVIOIKAI (Windows NT) j£ О Databases •i. $ Scat ? Й ow.Cbapterfi i Name ,j Owner User User | Create Dace UEjMlOWEDJaAWNALlTY ARTIST dbo dbo 9^.^2002 2.17^9 PM 9/6/2002 12.32: !3 PM •* 0 E2E Scjstomcr dbo User 9/6/300212-33:37 PM S 0 FiredUp fS3cUSTC*ER_AP.TIST_INT dbo User 9/6/2002 12^5^6 PM y! lakeview ;|Щ]Лргор«Се5 dbo System 9/6/2003 KkZZHSAM ф- $ master ;<Йиюи.ем_Ако1»л dbo User 9/6/2002 2:38:32 PM ф Q model ’ s£-|| hisdb & Nortbwind * '•* У Pubs . ¥• (j tempdb - '£ ф ViawRidgel • l^}svgcdumns 'l^sysconiments '^^Wsysdepends J^5ysffegroups •®syrfies "l^syshfesi •^sy^txejgrieys . sysf ufecoitcetafogs dbo dbo (fee dbo Лю System System System System System 8/6/3000 Г29:12 AM W20001:25:12 AM В/б/'ЗООО 1’29-12 AM 8;'6/20001:29:12 AH в.’б.’ЗООО 1:29:12 AM X 8 ие»«И#>г - Q VRG Лю Лю System System 8^6/2000 1.29:12 AM 8,^2000 1:29:12 AM Diagrams Лк» System вдаХЮ 1:29:12 AH s m Views Stored Procedures /^sysMtextootlfy iBlsysIndexes .|Osysir»dexkftys Лю Лю Лю System System System 8/6/20001:29:12 AM 8/6/2000 1:29:12 AM 8/6/2000 1-29:12 AH 5/? Users ©Roles if] Rules ^Defaults £L User Defined Data Types tfc User Defined Functions i-B^sysmembers l^sysobjecu Лю Лю System System 8/6/30001:29:12 AM ev*6/20001-2Kl2AH •|(B|syspef missions l^syspropertles .T^Usysprotects -s^sysreferences jUJsyAypes Лю Лю Лю System System System 8/6/2000 129:12 AM 8.^’2000 Г29:12 AH 8/6/30001:39-12 AM Ф Data Transformation Services Лю System 9.W Ф Management Лю System 8/8/2W01:29:12 AM Repkateri Л«~~»5У supers И&Ттпл.и- Лю System W2000k»:12AM Ф. iXl Security -|uil TRAN5 Лю User W2002 l;08.«W » a Support toVKB s.l Лю User Wtce: u.sTiioRM . . . _/ ; \ - - й j ~ «y'W.'ywW.XV. Рис. 11.3. Список таблиц в базе данных
Создание базы данных SOL Server 2000 4 97 Создание таблиц Есть два способа создания и модификации таблиц и других структур SQL Server 2000. Первый способ - использовать SQL-операторы CREATE или ALTER, как мы делали в Oracle в предыдущей главе. Второй способ — использовать гра- фические возможности SQL Server Хотя оба способа годятся, операторы CREATE проще в том смысле, что в этом случае не требуется щелкать мытью в многочис- ленных окнах. Их также можно использовать для создания структур базы данных программным способом. Многие профессионалы предпочитают создавать структуры базы данных с помощью SQL, а модифицировать с помощью графических средств. Создание таблиц с помощью оператора CREATE На рис. 11.4 показан типичный SQL-оператор CREATE TABLE. Как описано в преды- дущей главе, такие операторы всегда начинаются с ключевых слов CREATE TABLE, за которыми следует имя повой таблицы. Далее идет список столбцов таблицы, заключенный в скобки. Для каждого столбца указывается имя, гни данных и свой- ства, если они есть. Описания столбцов разделяются занятыми, но после послед- нею столбца запятая не ставится. Рис. 11.4. Пример оператора CREATE TABLE для SQL Server Таблица, создаваемая оператором на рис. 11.4, называется CUST и содержит четыре столбца: CustomerlD, Name, AreaCode и LocalNumber. Столбец CustomerlO имеет Целый тип (int) и является первичным ключом таблицы Столбец Name содерж строковые данные (тип char) и имеет длину 50 символов. Столбец Name считает- ся обязательным (NOT NULL), пустые значения для этого столбца не допускаются. Если свойство NULL или NOT NULL не указано, по умолчанию предполагается NULL.
498 Глава 11 Работа с базами данных в SQL server 2000 . м „..„nvvieiK, в квадратные скобки [Name], Это необходим^ Имя столбца Name з< е |1р<)1)а1)цым словом SQL Server Если не по- потому. чго Name являет -пытаться интерпретировать его как имя местить его в скобки, < . ТаКНМ обра.юм, всякий раз, когда вы собираете^ одной из своих кон 1 у OI Server в качестве пользовательского идснти использовать кл”ч®° СТ(Д скобки. Если вы не уверены, является лидам на всякий случай все равно заключите его в скоб- VI. Ввела от этого не будет. Лия столбца AreaCode в этом примере установлено значение по умолчанию, павное (206) Далее, ограничение CHECK допускает присваивание столбцу AreaCode топько тех значений, которые указаны в списке. Кроме того данный столбец мо- жет быть пустым Столбец LocalNumber определен как char(8), и, поскольку свой- ство NULL или NOT NULL для него це указано, будет использоваться установка по умолчанию, то есть NULL. ,пг,тг Есть несколько способов передать оператор CREATE на выполнение SQL Server Простейший из них - использовать анализатор запросов Query Analyzer. Для этого в главном меню Enterprise Manager выберите команду Tools (Инструменты), и в открывшемся меню выберите SQL Query Analyzer, как показано на рис. 11.5 Введите оператор CREATE TABLE в окне анализатора запросов и щелкните на синей галочке, расположенной на панели инструментов. Если ваш оператор содержит синтаксические ошибки, отчет о них будет представлен ниже, в окне под текстом оператора. Исправив ошибки, щелкните на зеленой стрелке, и таблица будет создана 4^ Generate SQL Script... R Wcards... Transformation Services Job Scheduling ,, Replication Database Maintenance Planner... Oj Backup Database... 6s Restore Database... ® £3 Manage SQl Server Configuration Properties, f О PepHcej HafW,9oSQ*.5eiverMessages... ^BsunpU b^TooIr ®&MetaO! QPh°nS- - Щ * S 19 items I/-...... ^IScolumrts M-5CCHTf;-»ent$ sdepends jsfifegtoups sfeteignkeys sF'jlRex«-.cati?logs '"sfaBtextnGbty indexes »ndexkeys ^members .objects । ОУ A db dh dbs^ db db dh <S> dh dtx db= - <s>v Рис. 11.5. Вызов Query Analyzer Enterprise Manager, щелкните nna Ha самом делс 6ь1Ла создана, вернитесь в окно Refresh (Обновить). Новая табпи D°H КНоПкой мь”»и на значке Tables и выберите панели. Щелкните правой кип™ ДОЛЖ1,а появиться в списке таблиц в правой правой кнопкой мыши на 11ОВОЙ таблнце „ вы6еритс Design Table
Создание базы данных SQL Server 2000 499 (Проектировать таблицу). Вы увидите окно, подобное изображенному на рис. 11.6. Обратите внимание, что для столбца AreaCode действительно выбрано значение по умолчанию (206) и что столбцы AreaCode и LocalNumber могут быть пустыми. Кроме того, первичным ключом таблицы является столбец CustomerlO, на что I казываст символ ключа слева от имени этого столбца. Рис. 11.6. Столбцы и свойства таблицы CUST Создание базы данных галереи View Ridge Для просмотра и редактирования структуры таблицы можно использовать гра- фический интерфейс, как показано на рис. 11.6. С сто помощью можно также соз- давать таблицы с нуля Для этого требуется щелкнуть правой кнопкой мыши на значке Tables в левой панели окна Enterprise Manager и выбрать New Table (Создать таблицу). Появится пустая сетка, имеющая формат, аналогичный представленно- му на рис. 11.6. Вводя данные в строки этой сетки, можно определить таблицу. Выполнение операторов CREATE TABLE с помощью Query Analyzer Графические средст ва на практике хороши для создания лишь простейших таблиц. Более удобный способ создать таблицы — это записать операторы CREATE TABLE и текстовый файл и выполнить эти операторы с помощью SQL Query Analyzer. В листинге 11.1 изображены операторы CREATE TABLE для создания базы данных галереи View Ridge, описанной в главе 7. Эгп операторы были записаны в файл с именем VRG Create_.Tables.sql, и эпи фйпл был оперы г в программе Query Analyzer.
500 Глава 11. Работа с базами данных в SQL Server 2000 На рис. 11.7 разработчик щелкнул на кнопке Execute (Выполнить), и программа создала пять таблиц. Листинг 11.1. Операторы, создающие таблицы для б<да данных View RidOe CREATE TABLE CUSTOMER( Customer-™ int NOT NULL IDENTITY(lOOO.l). Наше char(25) NOT NULL. Street char(30) NULL, City char(35) NULL. State char(2) NULL. ZipPostalCode char(9) NULL, Country char(50) NULL. AreaCode char(3) NULL. PhoneNumber char(8) NULL. Email char(lOO) NULL. CONSTRAINT CustomerPK PRIMARY KEY (CustomerlO). CONSTRAINT CustomerAKl UNIQUE(Name) ): CREATE TABLE ARTIST! ArtistID Name Nationality Bi rthDate DeceasedDate CONSTRAINT CONSTRAINT ONSTRAINT CONSTRAINT ‘i * 4 x 5 CONSTRAINT CONSTRAINT ); int NOT NULL. . IDENTITY(l.l). char(25) NOT NULL. char(30) NULL. numeric(4) NULL. numeric(4) NULL. ArtistPK PRIMARY KEY (ArtistID). ArtistAKl UNIQUE (Name). Nationalityvalues CHECK (Nationality IN ('Canadian'. 'English'. 'French'. 'German'. Mexican', 'Russian'. 'Spanish' 'US' )) BirthValuesCheck CHECK (BirthDate < DeceasedDate) VaiidBirthYear Sn(B^vhDate LIKE ’П-2][0-9][0-9][0-9]'). ValidDeathYear CHECK (DeceasedDate LIKE '[l-2][0-9][0-9][0-9]') CREATE TABLE CUSTOMER ArtistID CustomerlD CONSTRAINT CONSTRAINT _ARTIST_INT( int NOT NULL lnt NOT NULL. CustomerArtistPK cSY KEYJArtistID, CustomerlD). Customer_Arti st_Int_Arti stFK
Создание базы данных SQL Server 2000 501 FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) ON UPDATE CASCADE. ON DELETE CASCADE. CONSTRAINT Customer_Artist_Int_CustomerFK FOREIGN KEY (CustomerlO) REFERENCES CUSTOMER (CustomerlO) ON UPDATE CASCADE. ON DELETE CASCADE CREATE TABLE WDRK( WorkID int NOT NULL. IDENTITY(500.1). Title Description Copy ArtistID CONSTRAINT char(25) NDT NULL. varchar(lOOO) NULL. char(8) NDT NULL, int NOT NULL. WorkPK PRIMARY KEY (WorkID). CONSTRAINT WorkAKl UNIQUE (Title. Copy). CONSTRAINT ArtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) CREATE TABLE TRANS( TransactionlD int NOT NULL. IDENTITYdOO. 1). DateAcquired datetime NOT NULL. AcquisitionPrice Numeric(8.2) NULL. PurchaseDate SalesPrice AskingPrice CustomerlO WorkID CONSTRAINT datetime NULL. Numeric(8.2) NULL. Numeric(8.2) NULL int NULL. int NOT NULL. TransactionPK PRIMARY KEY (TransactionlD). CONSTRAINT SalesPriceRange CHECK ((SalesPrice > 1000) AND (SalesPrice <= 200000)). CONSTRAINT ValidTransDate CHECK (DateAcquired <= PurchaseDate). CONSTRAINT TransactionWorkFK FOREIGN KEY (WorkID) REFERENCES WORK (WorkID) CONSTRAINT T ransactionCustomerFK FOREIGN KEY (CustomerlO) ), REFERENCES CUSTOMER (CustomerlO)
502 Глава 11. Работа с базами данных в SQL < rver 2000 CREATE TABLE TRANS t TraneactionID DateAcquired AcquisitionPrice PurchaseDate SalesPrice AskingPrice CustomerlD WorkID CONSTRAINT CONSTRAINT CONSTRAINT CONSTRAINT CONSTRAINT lnc NO'/ NULL/ datetime Numeric /6,2) NUTL, datetime Numeric (6,2.' NUI Lz Numeric (6,21 NULL/ int NULL/ int NOT NULL, TransactionPK PRIMARY KEY -TransactionlD' , SalesPriceRange CHECK i(Salesprice 1000 AND ValidTransDate CHECK (DateAcquired s* Purchase! TransactionlTorkFK FOREIGN KEY-WorkID) REFERENCl TransactionCustotnerFK FOREIGN KEY <CustomerlD F NCT NULL/ NULL, _____________________________________________ > I The command(s) completed successfully. < _________________________________________________________________________________________’ БЗ Cuds Messaaes | .....©BGRVIOHQAI (8.0) OBGRVWl\Achr«trator (52) VRG 0 00:00 .Orows tn 1, Coll Connections; I Рис. 11.7. Выполнение операторов CREATE TABLE в окне программы Query Analyzer (видна только последняя часть) В листинге 11.1 имя таблицы TRANSACTION изменено на TRANS. Это сделано потому, что слово TRANSACTION имеет особенный смысл для SQL Server, и храни- мые процедуры и триггеры не будут корректно работать с таблицей, названной таким именем, даже если вы заключите его в скобки. Так что жизнь будет проще, если вы назовете таблицу TRANS. SQL-код в листинге 11.1 содержит один новый элемент — ограничение IDENTITY. Это ограничение используется в SQL Server для определения суррогатного клю- ча. Задается оно в виде IDENTITY(n,m); в результате создается суррогатный ключ с начальным значением т и приращением п. Так, столбец CustomerlD будет сурро- гатым ключом с начальным значением 1000 и приращением 1. Между прочим, ко1да щрапичеиие IDENTITY вводится для существующего столбца в таблице, со- держащей данные (посредством оператора ALTE R TABLE пли графического интер- фейса), начальное значение суррогатного ключа будет установлено равным наи- большему из двух значений — начального значения т, заданного в операторе, и максимального значения данного столбца, существующего в таблице. Просмотр структур базы данных с помощью графических средств SQL Server Tar/fV I10Ka3ana СТруктура таблицы ARTIST после обработки операторов CREATE тяА Т° >Ы увиде1Ь (Р,1С- 11.8, «), щелкните правой кнопкой мыши на имени и и1^1" С™ске " «‘чберитс Design Table (Структура таблицы). Обратите внима- , чю столбец ArtistID имеет ограничение IDENTITY, как и следовало ожидать.
Создание базы данных SQL Server 2000 503 Т ables Relationships ] Indeaes/Keys Check Constraints I Constraint expression: i ([Nationality] = ‘US' or ([Nationality]»’Spanish* or ([Nationality] = i ‘Russian1 or ([Nationality] = ‘Mexican1 or ([Nationality] = ‘German1 t or ([Nationality] == Trench’ or ([Nationality] = ‘English' or ' [Nationality] - ’Canadian’))))))) Г Check existing data on creation P Enforce constraint for replication W Enforce constraint for INSERTS and UPDATES а 6 Рис. 11.8 Структура таблицы ARTIST: в — столбцы и свойства; б — ограничения
504 Глава 11. Работа с базами данных в SQL Server 2000 Чтобы увидеть ограничения таблицы, щелкните правой кнопкой мыши где- нибудь в белом пространстве окна структуры таблицы и в контекстном меню выберите Check Constraints (Ограничения CHECK). На рис. 11.8, б, показано огра ничение Nationalityvalues. Очевидно, что легче написать это ограничение в виде оператора, чем вводить его в этом окне! На протяжении этой главы вам будут встречаться изображения диалоговых окон, подобные рис. 11.8, б, с флажками, которые будут говорить что-либо о ре- пликации (replication). Все эти флажки относятся к распределенным базам данных SQL Server, в которых информация помещается в две или более базы данных, а обновления в них некоторым образом координируются. Здесь мы не будем рас- сматривать этот вопрос, поэтому данные флажки мы будем игнорировать. Более подробно о репликации можно узнать, поискав в справочной системе SQL Server материалы на соответствующую тему. Кратко репликация будет обсуждаться в главе 15. Чтобы убедиться, что связи были созданы правильно, щелкните правой кноп- кой мыши на значке Diagrams (Диаграммы) и в открывшемся меню выберите New Database Diagram (Создать диаграмму базы данных). Появится мастер диа- грамм. Выберите таблицы ARTIST, WORK, TRANS, CUSTOMER и CUSTOMER_ARTIST_INT. Результатом будет диаграмма, подобная приведенной на рис. 11.9, а. Чтобы просмотреть свойства связи, щелкните правой кнопкой мыши на линии связи и в контекстном меню выберите Properties (Свойства). На рис. 11.9, б, показаны свойства связи TransactionWorkFK. Ввод данных Ввод данных в SQL Server производится путем заполнения сетки в окне про- граммы Enterprise Manager или с помощью операторов INSERT, выполненных программой Query Analyzer. Чтобы ввести данные первым способом, щелкните праной кнопкой мыши на имени таблицы и в контекстном меню выберите Open Table ► Return all rows (Открыть таблицу ► Возвратить все строки). Появится окно с сеткой, ячейки которой можно заполнять данными. Чтобы ввести данные с по- мощью Query Analyzer, просто откройте эту программу и введите в ее окне операторы INSERT с вашими данными. Все данные для примеров этой главы Analyz 71 7'5) 6ЫЛИ введены с помощью операторов INSERT в программе Query Создание представлений На рис. 11.10, а, показан оператор CREATE VIEW, который создает представление мкт JT n^ere5ts> описанное в главе 7. Этот оператор был введен в окно програм- ко4 Па У2ег и 3апУЩеп иа выполнение щелчком на кнопке с зеленой стрел- Views Р°СМОТРеть представление можно в Enterprise Manager, щелкнув на значке Custom Редставлеиня^’ затем щелкнув правой кнопкой мыши на представлении лениа^п erestS и в контекстном меню выбрав Design View (Структура представ- ) Юявится окно, аналогичное изображенному на рис. 11.10, б. Обратите
Создание базы данных SOL Server 2000 505 внимание, что в панели структуры таблиц (вверху) отображаются псевдонимы таблиц, а во втором столбце средней панели, содержащей определение представ- ления, перечислены псевдонимы столбцов. Isomer ’ Г ?lCustomeriD ZpPtwtaCode Country AreaCode Phoned jmber TRANS TransactionlD DateAcquired AcqutsAtocPrice PurchaseDate SalesPrice AskngPrice Customer© WorkID CUSTOMER ^ARTIST^IN j ? jArtist© Customer© 6 Рио. 11.0. Диаграмма связей: a — связи таблиц; б — свойства связи TransacttonWorkFK
506 Глава 11. Работа с базами данных в SOL Server 2000 а Ates. . ]table________|6/put ISortType, |5ort Order ’Jc&eria -t—-............... easterner С V Artist A V ~~Column __Name I Name Г»й ' __ ........... _____________ SELECT C.NomoAStustomor.A.NeneASAitist FROM SK.CU5TOMERC INNER JOIN dbo.CU5TOMER_ARTlST INT I ON C.CustwnertO - I.CuslomerlD INNER JOIN Obe.ARTIST AON I.Arbs&O - A.AitlstlD 6 PCustOTedntem3^sH6tnrA^TaBneHM5': a ~ onePaToP CREATE VIEW для представления рафическое отображение представления Customerinterests Enterprise Manager - вдлкнув nn-m™ ° ПОМ<ПЦЬЮ SQL-операторов или в окне линия) л в контекстном мето г 011 K,1OnK°ii мыши на значке Views (Представ- Опять-таки, зачастую оптихтв'п"3” КОмандУ New View (Создать представление), с использованием SOL ч П стра/теп,ей является создание представлений графических средств П1<ацня (в случае необходимости) — при помоши
Создание базы данных SQL Server 2000 507 Индексы Индексы, как уже говорилось, — это специальные структуры данных, создавае- мые для повышения производительности базы данных (см. приложение А) SQL Servei автоматически создает индексы по всем первичным и внешним клю- чам. Разработчик может также с помощью SQL Server создавать индексы и по другим столбцам, которые часто фигурируют в предложениях WHERE пли исполь- зуются для сортировки данных при последовательной обработке таблицы для за- просов и отчетов. Чтобы создать индекс, щелкните правой кнопкой мыши на таблице, содержа- щей столбец, который вы хотите индексировать, выбери re All Tasks (Все ыдачп), затем выберите Manage Indexes (Управление индексами). Откроется диалоговое окно, изображенное в левой части рпс. 11.11. Щелк.. на кнопке New... (Но- вый...), и перед вамп появится диалоговое окно, изображенное в пр твой части рисунка. Здесь разработчик создаст индекс но столбцу ZipPostalCode таблицы CUSTOMER. Индекс, который называется ZipPostallndex, должен быть разрежен, ла полнен на 80% и отнесен к группе файлов PRIMARY. Ратрежсиис ост шляег в пн дексс свободное пространство для вставок па всех уровнях, кроме самого нижне- го. Заполнение характеризует объем пустого и рос гране нм, которое оставляется на нижнем уровне индекса. За дальнейшей информацией об эт их параметрах обращайтесь к приложению А и к документации па SQL Server. Рис. 11.11. Создание индекса В последнем диалоговом окне щелкните на кнопке Edit SQL... (Редактировать SQL...), и вы увидите диалоговое окно, показанное на рпс. 11.12. В нем будет ото- бражаться текст SQL-оператора, введя который в окис анализатора запросов, можно было бы создан, тог же самый индекс.
508 Глава 11 Работа с базами данных в SQL Server 2000 Рис. 11.12. SQL-код, создающий индекс SQL Server поддерживает два вида индексов: кластеризованные и некла- стеризованные. В кластеризованном индексе данные хранятся на нижнем уровне и в том же порядке, что и сам индекс. В некластеризованном индексе нижний уровень не содержит данных, но содержит указатели на данные. Поскольку стро- ки могут быть отсортированы только в одном физическом порядке за один раз, для каждой таблицы допускается только один кластеризованный индекс. Кластеризованные индексы обеспечивают более быстрое получение данных, чем некластеризованные. Обычно они оказываются быстрее и при обновлении, но не в том случае, когда много обновлений происходит в одном и том же месте в середине отношения. За дальнейшей информацией обращайтесь к документа- ции на SQL Server. Логика приложения них заключиПОСО^ОВ обработки баз данных SQL Server из приложений. Один из lava и пи к СТСЯ гТ°М’ ЧТОбы создавать приложения на С#, C++, Visual Basic, ды СУБД ТоТ «Г >О ДРУ1ОМ языке программирования и вызывать из них коман- класепп-гюо. Сегодня для этого используются библиотеки объектных задаются чп™ЮТСЯ ° Ъ5КТЫ’ пыпол1|яющие необходимые действия с базой данных обработки СНПЯ Своиств ,тих объектов и вызываются их методы. Примеры такой и lava Serv₽r'p ВИДИТе в ходе Осуждения ADO в главе 12, ADO.NET в главе 13 jaxa Server Pages в главе 14.
Логика приложения 509 Другой способ обработки баз данных SQL Server состоит в написании храни- мых процедур, как описывалось в главе 7. Эти процедуры могут вызываться из прикладных программ или из веб-сценариев, написанных на языках VBScript или JScript. Хранимые процедуры можно также вызывать из программы Query Analyzer. Однако это следует делать лишь на стадии разработки и тестирования. Как вы знаете из 1лавы 9, по соображениям безопасности не следует разрешать доступ к рабочей базе данных в интерактивном режиме никому, кроме назначен- ных администраторов базы данных. Третий способ обработки баз данных SQL Server - выполнение последова- тельностей команд, сохраненных в .sql-файлах. Такие файлы запускаются из про- граммы Query Analyzer. Из соображений безопасности их следует запускать толь- ко на стадии разработки и тестирования и никогда не использовать на рабочей базе данных. Наконец, логику приложения можно реализовывать посредством триггеров. Как вам известно из главы 7, триггеры можно использовать для проверки допус- тимости данных, задания значений по умолчанию, обновления представлений и реализации нестандартных процедур обеспечения ссылочной целостности. В этой главе мы рассмотрим две хранимые процедуры. Здесь мы будем тести- ровать процедуры, запуская их из Query Analyzer. Еще раз напомним, что делать это следует только в ходе разработки и тестирования. Из глав 13-15 вы узнаете, как вызывать хранимые процедуры из прикладных программ. Кроме того, мы опишем четыре триггера, каждый из которых будет демонстрировать один из спо- собов применения триггеров. Эти триггеры будут вызываться SQL Server при наступлении определенных событий. Хранимые процедуры В SQL Server хранимые процедуры должны писаться на языке TRANSACT/SQL, или Т/SQL, как его иногда называют. По состоянию на осень 2003 года возмож- ность писать хранимые процедуры SQL Server на языках семейства .NET (С#, VB.NET) отсутствует. Предположительно, эта ситуация изменится с выходом следующих версий SQL Server; возможно, о выходе этих версий будет уже объяв- лено на момент прочтения вами этой книги. В таком случае вы можете использо- вать C# или VB.NET: эти языки гораздо лучше, чем TRANSACT/SQL Как и с другими структурами базы данных, вы можете записать текст процеду ры в файл и выполнить ее с помощью Query Analyzer. Есть только одна особен- ность, которую необходимо знать. В первый раз, когда вы записываете процеду- ру в текстовый файл, начните ее ключевыми словами CREATE PROCEDURE. Потом, если вы захотите изменить процедуру, поменяйте эти слова на ALTER PROCEDURE. В противном случае при поныгке запуска измененной процедуры вы получите сообщение об ошибке, гласящее, что такая процедура уже существует Можно также создать процедуру в программе Enterprise Manager, щелкнув правой кнопкой мыши па значке Stored Procedures (Хранимые процедуры) ив кон- текстном меню выбрав New Stored Procedure (Создать хранимую процедуру). В этом случае SQL Server самостоятельно разберется с оцнеаннои выше проблемой
510 Глава 11. Работа с базами данных в SQL Server 2000 rDr. TP /alter PROCEDURE. Однако вы не сможете сохранить нроце. ключевых слов СКЕА / авите все синтаксические ошибки. Это может е с ,"“та,““и ♦* лами в Query Analyzer. Хранимая процедура Customer_lnsgrt В листинге 11.2 изображена хранимая процедура, которая сохраняет в базе дан- ных информацию о новом клиенте и связывает этого клиента со всеми худож- никами заданной национальности. Процедура имеет четыре входных параметра. ©NewName, ©NewAreaCode, ©NewPhone и ©Nationality. Как вы можете видеть, параметры и переменные б TRANSACI -SQL предваряются символом @. Первые три параметра — это данные нового клиента, а четвертый параметр представляет собой национальность художников, которыми интересуется новый клиент. Листинг 11.2. Хранимая процедура Customer insert CREATE PROCEDURE dbo.Customerjnsert ONewName char(50), @NewAreaCode char(5). ONewPhone char(8). ^Nationality char(25) AS DECLARE @Count as smallint DECLARE @Aid as int DECLARE ©Cid as int /* Проверяем, нет ли данного клиента в базе */ SELECT @Count=Count(*) FROM dbo.CUSTOMER WHERE [Name] = ONewName AND AreaCode = ONewAreaCode AND PhoneNumber = ONewPhone; IF OCount > 0 BEGIN PRINT 'Клиент уже есть в фазе данных - никаких действий не предпринято RETURN END /* Добавляем данные о новом клиенте */ INSERT INTO dbo CUSTOMER ([Name]. AreaCode. PhoneNumber) VALUES (ONewName. ONewAreaCode. ONewPhone): /* Получаем новое значение суррогатного ключа */ SELECT @Cid<ustomerID FROM dbo.CUSTOMER WHERE [Name] = ONewName AND AreaCode = ONewAreaCode AND PhoneNumber = @NewPhone: л. it®
«а «ай Логика приложения 511 * Создаем запись в таблице пересечения для каждого художника */ DECLARE Artist_Cursor CURSOR FOR SELECT ArtistID FROM dbo.ARTIST WHERE Nat1onal1ty=ArtistNat1onality; /* Обрабатываем каждого художника выбранной национальности */ OPEN Art1st_Cursor FETCH NEXT FROM Artist_Cursor INTO @Aid WHILE @OFETCH_STATUS = 0 BEGIN INSERT INTO dbo.[CUSTOMER ARTISTJNT] (ArtistID, CustomerlD) VALUES (©Aid. ©Cid) FETCH NEXT FROM Artist_Cursor INTO @Aid END CLOSE Art1st_Cursor DEALLOCATE Artist_Cursor Первая задача, которую выполняет данная хранимая процедура, — проверить, нет ли записи об этом клиенте в базе данных. Если count в первом операторе SELECT оказывается больше 0, это значит, что строка для данного клиента уже существует. Тогда никаких действий не предпринимается, хранимая процедура выводит сообщение об ошибке и завершает свою работу. Это сообщение об ошиб- ке, между прочим, будет видно в Query Analyzer, но в общем случае не будет видимым для прикладных программ, вызывающих данную процедуру. Передать сообщение об ошибке пользователю через прикладную программу можно с помо- щью параметра или каким-нибудь другим способом. Этот вопрос мы рассмотрим в последующих главах. Далее процедура вставляет новые данные в таблицу dbo.CUSTOMER и считыва- ет новое значение CustomerlD в переменную @Cid. Чтобы создать соответствующие строки в таблице пересечения, с помощью SQL-оператора открывают курсор, возвращающий все строки из таблицы ARTIST, в которых значение столбца Nationality равно значению параметра ©Nationality. Курсор обрабагывается в цикле LOOP, в процессе чего в таблицу пересечения CUSTOMER_ARTIST_INT вставляются новые строки. Оператор FETCH передвигает курсор на следующую ст|юку. На рис. 11.13 показано, как с помощью этой хранимой процедуры, вызывае- мой из SQL Query Analyzer, добавить в базу данных новою клиента, интере- сующегося художниками из С 111 А. Процедуре передаются параметры, значения которых выделены красным цветом На рис. 11.14 показано состояние данных в базе после выполнения хранимой процедуры. В таблицу CUSTOMER был добав- лен покупатель Michael Bench с идеишфпкагором CustomerlD, равным 1058. Об- ратите внимание, что всего имеются три художника из США и что для каждого Из НИХ в таблицу CUSTOMER_ARTIST_INT была вставлена строка с CustomerID-1058.
512 Глава 11. Работа С балами да»пьх в SQL Sww 2000 Рис. 11.13. Вызов процедуры Customer Jnsert из окна Query Analyzer j CcstomerlO □State IZ^tstaiCode g&Ss .Country Bi - ш. >110» Jeffrey Janes 123 W an St Renton WA 98123 USA 206 SS'S*®. I 11001 David Smith S13 Tumtievieed L Lcvdand CO 80345 USA 303 5S-5O4 j 11015 Ttffeny Twight 68 - Fist Avenue Langley WA 98114 USA 206 355-LGB5 j [1033 Fred Smatbers 10899 - E8th Ave Bsnbndge Isianc WA 98108 USA 2Db SS-^ZM ' 1034 Mary Beth Frederic 2S South Lafayette Denver CO 80210 USA 303 SfrlCEE LJ1036 Selma Warring 205 Burnaby Vancouver BC VCNIB4 Canada 2S3 sss-izm = iiQ3? Susan Wu 105 Locust Ave Atlanta GA 23224 USA 721 5S<234 ; ‘1040 Donald G. Gray 55 Bodega Ave Bodega Bay CA 92114 USA 705 5&-2Э4 i 104» Lynda Johnson 117 C Street Wasbngton DC 11345 USA 7СЭ 555-3S0B —Jiosi Chris V^kens 87 Highland Drive Otymp^ WA 98008 USA 2O(> 5Э5- 33» _U0S8 L*J Michael Bench <NULL> <NLLL> <NULL> <NUU> <NUU> 555-ЖМ Ж _ 9l [Castomerto - 1058 1034 1041 1058 1001 1015 1033 1034 1036 1040 1041 1051 1058 Рис. 11.14. Результаты вызова хранимой процедуры с рис 11.13 Хранимая процедура NewCustomerWithTransaction В листинге 11.3 представлена хранимая процедура, добавляющая в базу данных информацию о новом клиенте и регистрирующая покупку им произведения та процедура принимает семь параметрон, содержащих данные о новом клиенте и его покупке.
Логика приложения 513 Листинг 11-3. Хранимая процедура NewCustomerWithTransaction CREATE PROCEDURE dbo.NewCustomerWithTransaction @NewName char(50). ONewAreaCode char(3) ONewPhone char(8), OArtistName char(50, OWorkTitle char (50). OWorkCopy char (10). OProce smallmoney AS DECLARE OCount as smallint. @Aid as int. OCid as int. OWid as int. @Tid as int SELECT @Count=Count(*) FROM dbo.CUSTOMER WHERE [Name] = ONewName AND AreaCode = ONewAreaCode AND PhoneNumber = ONewPhone; IF OCount > 0 L-EGIN PRINT 'Клиент уже есть в базе данных - никаких действий не предпринято’ RETURN END BEGIN TRANSACTION /* Начинаем транзакцию: если есть проблемы, производим откат */ INSERT INTO dbo.CUSTOMER ([Name], AreaCode. PhoneNumber) VALUES (ONewName. @NewAreaCode. ONewPhone): SELECT OCid=CustomerID FROM dbo.CUSTOMER WHERE [Name] = ONewName ANO AreaCode = ONewAreaCode AND PhoneNumber = ONewPhone. SELECT @Aid=ArtistID FROM dbo.ARTIST WHERE Name = OArtistName IF OAid IS NULL /* Неправильный ArtistID */ BEGIN Print ’Неправильное значение ArtistID ROLLBACK RETURN END SELECT @W1d=WorkID FROM dbo.[WORK] „ _ ,r WHERE Artistld - OAid ANO Title - OWorkTitle AND Copy - OWorkCopy продолжение^
514 Глава 11. Работа с базами данных в QL erver .4)00 Листинг 11.3 (продолжение} IF @Wid IS NULL /* Неправильный WorkID */ BEGIN Print 'Неправильное значение WorkID' ROLLBACK RETURN END SELECT FROM WHERE @Tid=TransactionID dbo.[TRANS] WorkID = @Wid AND SalesPrice IS NULL IF OTid IS NULL /* Неправильный Transactions */ BEGIN Print 'Нет ни одной транзакции' ROLLBACK RETURN END UPDATE SET WHERE dbo.[TRANS] /* Все в порядке, обновляем строку в таблице TRANS */ PurchaseDate = GETDATEO. SalesPrice = OPrice, CustomerlD = Odd Transactions = @Tid INSERT INTO dbo.[CUSTOMER_ARTIST_INT] (ArtistID. CustomerlD) VALUES (©Aid. ©Cid) COMMIT Первое, что нужно сделать, — это проверить, не существует ли уже этот клиент в базе данных; если да, то процедура завершает работу с сообщением об ошибке. Если этого клиента нет в базе данных, процедура начинает транзакцию. Вспомните из главы 11, что транзакции гарантируют атомарность действий, выполняемых с ба- зой данных: либо выполняются все обновления, либо не выполняется ни одного. Итак, начинается транзакция, и в таблицу CUSTOMER вставляется строка для нового клиента. Далее считывается новое значение CustomerlD, как показано выше. Затем процедура проверяет допустимость значений ArtistID, WorkID и Transactions. Если хотя бы одно из них является некорректным, происходит откат транзакции. Если все перечисленные значения правильны, оператор UPDATE обновляет столбцы PurchaseDate, Price и CustomerlD в соответствующей строке таблицы TRANS, стол ец PurchaseDate записывается системная дата (с помощью системной функ- ции ETDATE()), в столбец SalesPrice — значение параметра ©Price, а в столбец сп^тпмТ ло ЗНачеиие переменной @Cid. Наконец, добавляется строка в таблиц) — TIST—INT, чтобы зарегистрировать интерес клиента к данному худо*" нику, ели до этого момента все идет нормально, транзакция сохраняется. а Рис‘ ' показан вызов этой процедуры с тестовыми данными, а на рис. 11-1 изооражены результаты вызова в базе данных. Новому клиенту был присвоен ентификатор CustomerlD, равный 1059, и этот идентификатор был записан в стол-
Логика приложения 515 -41! Г ‘ 1 - беи внешнего ключа CustomerlD таблицы TRANS, как и требовалось. Соответст- вующим образом были установлены значения столбцов PurchaseDate и SalesPrice Обратите внимание на новую строку в таблице пересечения, которая отражает интерес клиента под номером 1059 к художнику под номером 16. <^е-у batch еда® «ted. bSGRViOltQAl (8.0) Vtf.CdW Рис. 11.15. Вызов процедуры NewCustomerWithTransaction из окна Query Analyzer Рис. 11.16. Результаты вызова хранимой процедуры с рис. 11.15 Триггеры SQL Server поддерживает только замещающие и завершающие триггеры. Предва- ряющие триггеры этой СУБД не поддерживаются. Таблица может иметь один или несколько завершающих rpniгеров вставки, обновления и удаления; завершаю- щи* триггеры немоту! назначаться представлениям. Представление или таблица
516 Глава 11 Работа с базами данных в SQL Server 2000 может иметь не более одного замещающего триггера на каждое из во;«мож,(Их действий — вставку, обновление или удаление. В SQL Server триггеры могут производить откаг транзакций, и влекших их запуск Когда триггер выполняет команду ROLLBACK, все действия, произведен- ные транзакцией, которая привела к запуску триггера, отменяются. Если в rei ге триггера за командой ROLLBACK следуют какие-либо инструкции, эти инструкции будут выполнены. Однако никакие инструкции, следующие за оператором, кото- рый вызвал запуск триггера, выполняться не буду!. Для триггеров вставки и обновления новые значения каждого столбца обраба- тываемой таблицы хранятся в псевдотаблице под названием inserted. Если, напри- мер, в таблицы ARTIST добавляется новая строка, то псевдотаблица inserted будет содержать четыре столбца: Name, Nationality, BirthDate и DeceasedDate. Аналогичным образом, в случае обновления или удаления старые значения каждого столбца будут храниться в псевдотаблице с именем deleted. В приведенных далее примерах вы увидите, как используются эти таблицы. В последующих разделах мы рассмотрим четыре примера, каждый из которых демонстрирует одно из возможных применений триггеров, описанных в главе 7 Триггеры можно создавать, записывая их в текстовые файлы (первым операто- ром в таких файлах должен быть оператор CREATE TRIGGER или ALTER TRIGGER), или в программе Enterprise Manager, щелкнув правой кнопкой мыши на имени таблицы и выбрав All Tasks ► Manage Triggers (Все задачи ► Управление триггера- ми). В последнем случае появится окно, в которое вы можете ввести текст триг- гера. Однако вы не сможете сохранить триггер в базе данных, если в нем будут синтаксические ошибки. Триггер, реализующий бизнес-правило Галерея View Ridge ведет список «проблемных» клиентов — тех, кто не оплатил вовремя покупку или представил какие-то другие проблемы для галереи. Когда в азу данных вводится покупатель, фигурирующий в списке таких клиентов, менеджер галереи хотел бы знать об этом. Для реализации этой политики галерея создала таблицу PROBLEM_ACCOUNT: в нее записывается информация о «проблемных» клиентах. При вставке или ° ° клиенте триггер проверяет, не фигурирует ли клиент в таб- J И е - COUNT. Если да, то выполняется откат вставки или обновления и выводится соответствующее сообщение. в JvTXCheCl<FOrPrOblemAcCOlJnt в листинге 11.4 реализует эту политику. Хотя он имрмнг, 1ГгеРа не Указано явно, что он является завершающим, мы знаем, что шие тпиггргаТ'51112101111111’ ПОСКОЛЬКУ в SQL Server не поддерживаются предваряю- котооые ХнЛ Б 3аГ°ЛОВКе тРиггеРа отсутствуют ключевые слова INSTEAD OF. которые обозначают замещающий триггер. Листинг 11.4- Триггер CheckForProblemAccount т “F“rProM=*cM] о» WM.[CUSTOMER] AS
/* Пытаемся соединить данные из inserted со строкой в таблице PROBLEM ACCOUNT */ inserted I JOIN PROBLEM_ACCOUNT P I.Name = P.Name I.AreaCode = P.AreaCode I.PhoneNumber = P. PhoneNumber Логика приложения 517 Sji- Wr 83 «ОГТрец а в паж-7 siM QGgQgfij. anoER), в на иска «1PW типтрвг- ввем будут досдали SELECT FROM ON AND ANO /* В следующем операторе необходимо проверить OOrowCount. Если результат соединения не пуст, выполняем откат транзакции и выдаем сообщение 010 <^2 If OOrowCount > О BEGIN ROLLBACK Print ‘Клиент принадлежит к числу "проблемных".' Print ‘Вставка и обновление не разрешены.’ END Триггер CheckForProblemAccount пытается соединить новые значения в псевдо- таблице inserted по очереди со всеми строками таблицы PROBLEM-ACCOUNT. Если соединение возвращает какие-либо результаты, значит, данный клиент присут- ствует в таблице PROBLEM-ACCOUNT. В этом случае следует выполнить откат транз- акции и вывести предупреждение. Данный триггер использует системную функцию @@rowCount, которая воз- вращает количество строк, обработанных предыдущим оператором Т/SQL. Зна- чение этой функции необходимо проверять сразу после выполнения оператора или сохранять в переменной для последующей проверки. Здесь триггер выпол- няет эту проверку сразу. Если @@rowCount равняется нулю, то данный клиент не присутствует в таб- лице PROBLEM-ACCOUNT и ничего делать не требуется. Если же @@rowCount име- ет положительное значение, значит, информация о данном клиенте содержится в таблице PROBLEM-ACCOUNT, поэтому транзакцию необходимо отменить, а поль- зователю выдать предупреждающее сообщение. Между прочим, в предыдущих двух процедурах вместо подсчета строк в пере- менной @rowCount можно было бы использовать функцию @@rowCount. Но мы сделали по-другому, чтобы у вас была возможность изучить альтернативные способы получения информации о количестве строк. Чтобы проверить, что триггер работает корректно, в таблицу PROBLEM-ACCOUNT была добавлена строка со значениями 'Nicole Not Pay', '213', '555-1234' После этого был выполнен оператор INSERT, показанный на рпс. 11.17. Как вы можете видеть, пользователю было выдано соответствующее сообщение. Была также проверена таблица CUSTOMER, чюбы убедиться, что вставка не была выполнена (эти действия не показаны здесь).
518 Глава 11 Работа с базами данных в SQL Server 2000-------- Рис. 11.17. Тестирование триггера CheckForProblemAccount Использование таблицы допустимых (или недопустимых) значений обеспе- чивает большую гибкость и динамичность, чем указание этих значений в ограни- чениях CHECK. Рассмотрим, например, ограничение CHECK, определяющее до- пустимые значения столбца Nationality в таблице ARTIST. Если менеджер галереи хочет расширить географию художников, с произведениями которых работает галерея, ему придется изменить ограничение с помощью оператора ALTER TABLE. В реальности для этого менеджеру пришлось бы нанимать консультанта. Более удачный подход — свести все допустимые значения столбца Nationality в таблицу. Такая таблица могла бы называться, например, ALLOWED_NATIONALITY (допустимая национальность). Затем можно написать триггер, подобный изобра- женному в листинге 11.4, который при вставке и обновлении ограничивал бы возможные значения столбца Nationality множеством значений в таблице ALLOWED_ NATIONALITY. Если владелец галереи захочет изменить список национальностей, ему достаточно будет добавить или удалить строки из таблицы ALLOWED_NATIONALITY. Триггер, присваивающий значения по умолчанию риггеры можно использовать для присвоения начальных значений, расчет кото- пгглш ”ШК0М сложен> чтобы его можно было выполнить с помощью ограничения v; , п / опРеделении столбца. Например, согласно ценовой политике галереи ®е’ запРашнваемая цена произведения, которая устанавливается по умол- р Ю' зависиг от того> появлялось ли это произведение в галерее в прошлом пппИ НеТ' °На -устаиавливастся равной удвоенной стоимости приобретения. Если ваетенТ”^ Г6 П0ЯВЛЯЛ0СЬ в галвРсе прежде, запрашиваемая цена устанаапи- или гт ЙВН0И ОЛЬ1вемУ И3 Двух значений — удвоенной стоимости приобретения лепим °ИМОСТИ ПРИО ретения плюс средняя чистая прибыль от продажи произве- дения в прошлом.
Логика приложения 519 Завершающий триггер, показанный в листинге 11.5, реализует эту ценовую по- литику. Сначала из таблицы inserted получаются значения WorkID и AcquisitionPrice Затем выполняется оператор SELECT FROM dbo.TRANS для подсчета количества строк с данным значением WorkID. Переменная @countPriorRows устанавливается равной @@rowCount минус единица, поскольку данный триггер является завер- шающим, и новая строка будет уже добавлена в базу данных. Следовательно, ко- личество удовлетворяющих условию строк в таблице TRANS, которое было в базе данных до выполнения вставки, равно (@@rowCount - 1). Листинг 11.5. Триггер SetAskingPrice CREATE TRIGGER [SetAskingPrice] ON [dbo].[TRANS] FRO INSERT AS DECLARE DWorkID as int. OTransID as int. OaqPrice as money. OSumNetPrice as money. OcountPriorRows as int. OnewPrice as money /* Получаем новье значения WorkID и AcquisitionPrice */ SELECT OWorklD = WorkID. OaqPrice = AcquisitionPrice. OTransID = TransactionlD FROM i nserted /* Проверяем, не появлялось ли произведение в галерее ранее */ SELECT * FROM dbo.TRANS T WHERE T.WorkID = OWorkID /* Это завершающий триггер, поэтому число строк будет включать только что вставленную строку. Вычитаем единицу, чтобы учесть это */ Set OcountPriorRows = ProwCount - 1 /* Устанавливаем newPrice и при необходимости корректируем ее значение*/ Set OnewPrice 2 * @aqPrice If OcountPriorRows > 0 BEGIN /* Функция AVG не подходит, поскольку в делителе будет учтена текущая строка Используем (№rowCount - 1 из предыдущих вычислений.
520 Глава 11 Работа с базами данных в SQL Server 2000 Листинг 11.5 (продолжение) SELECT OsumNetPrice = SUM(NetPrice) FROM ArtistWorkNet AW WHERE AW.Work ID = ©WorkID GROUP BY AW.WorkID /* Если необходимо, корректируем newPrice */ If PnewPrice < (PsumNetPrice / PcountPriorRows) + PaqPrice Set PnewPrice = (PsumNetPrice / PcountPriorRows) + PaqPrice END /* Теперь записываем в таблицу TRANS новое значение AskingPrice */ UPDATE dbo.TRANS SET AskingPrice = @newPrice WHERE TransactionlD = PTranslD Далее переменная ©newPrice устанавливается равной удвоенному значению AcquisitionPrice; при необходимости ее значение будет скорректировано ниже. Ес- ли @сои nt Prior Rows больше нуля, то в таблице TRANS до выполнения вставки уже были записи о транзакциях с данным произведением, и с помощью представле- ния ArtistWorkNet (см. главу 7) вычисляется суммарная чистая прибыль от прода- жи этого произведения. Встроенную функцию усреднения использовать нельзя, поскольку она будет вычислять среднее на базе значения @@rowCount, а не @countPriorRows. Затем текущее значение ©newPrice сравнивается с суммой сред- ней чистой прибыли и стоимости приобретения. Если оно оказывается меньше, переменная ©newPrice устанавливается равной сумме средней чистой прибыли и стоимости приобретения. Наконец, только что вставленная строка обновляется, в процессе чего в столбец AskingPrice записывается вычисленное значение ©newPrice. Для тестирования этого триггера необходимо проверить следующие три случая: ♦ произведение не появлялось в галерее ранее; 4- произведение появлялось в галерее прежде, но сумма средней чистой при- были и стоимости приобретения меньше или равна удвоенной стоимости приобретения; 4 произведение появлялось в галерее прежде, но сумма средней чистой при- были и стоимости приобретения превышает удвоенную стоимость приоб- ретения. Данный тест мы оставим читателю в качестве упражнения. гот триггер выполняет для галереи полезную функцию, избавляя персонал от значительного количества ручной работы, а также повышая точность резуль- татов. Триггер, обновляющий представление В главе 7 обсуждались проблемы, связанные с обновлением представлений. Одна таких про лем касается представлений, созданных при помощи операции со- пения. как правило, СУБД не способна обновлять таблицы, лежащие в основе
Логика приложения 521 * таких представлений. Однако, зная специфику конкретного приложения, можно определить, как следует интерпретировать запрос на обновление соединенного представления. Рассмотрим представление Customerlnterests, показанное на рис. 11.10. Оно со- держит строки таблиц CUSTOMER и ARTIST, соединенные через таблицу пересечения. Столбцу CUSTOMER.Name дан псевдоним Customer, а столбцу ARTIST.Name — Artist Запрос на изменение имени клиента в представлении Customerinterests можно интерпретировать как запрос на изменение столбца Name в таблице CUSTOMER. Такой запрос, однако, может быть обработан лишь в том случае, если это имя яв- ляется уникальным в таблице CUSTOMER. В противном случае невозможно будет определить, какую из строк следует обновлять. Замещающий триггер, текст которого приведен в листинге 11.6, реализует эту логику. Сначала триггер получает старые и новые значения столбца Customer представления Customerinterests. Затем с помощью коррелированного подза- проса с предложением EXISTS проверяется, является ли старое значение столбца CUSTOMER.Name уникальным. Если да, имя изменяется; если нет, никаких измене- ний не производится. Листинг 11.6. Триггер CustomerNameUpdate CREATE TRIGGER CustomerNameUpdate ON [dbo].[Customerinterests] INSTEAD DF UPDATE AS DECLARE @newName as char(30. @oldName as char(30) /* Получаем старое и новое имя */ SELECT @newName = Customer FROM i nserted SELECT OoldName = Customer FROM deleted /* Подсчитываем количество синонимов в таблице CUSTOMER */ SELECT * FROM dbo.CUSTOMER Cl WHERE Cl.Name = OoldName AND EXISTS (SELECT * FROM dbo.CUSTOMER C2 WHERE Cl.[Name] = C2.[Name] AND Cl.CustomerlD <> C2.CustomerlD) /* Теперь обновляем данные о клиенте, если имя было уникальным */ И @@rowCount • О UPDATE dbo CUSTOMER SET dbo CUSTOMER.[Name] - OrewName WHERE dbo CUSTOMER.[Name] - OoldName
522 Глава И. Работа с базами данных в SQL Sarver JOOO Z гргтппова! 1> в обеих возможных ситуациях когда Эшг.рптр.к^лпии^ я1мм1.1с11 .....,ШЫ1ЫМ. По p„t, ,, 18 „>Л1,ажа1 „МЯ уникально К л. „ Обрати тшмаиие пн панель реаудаи. « -....... с,|юм ,,с бы“ ',г"“,,,лй“ Рис. 11.18. Тестирование триггера CustomerNameUpdate Триггер, реализующий процедуру обеспечения ссылочной целостности Согласно рис. 7.3, таблица WORK в базе данных View Ridge имеет обязательного потомка в виде таблицы TRANSACTION. Это означает, что всякий раз, когда в табли- цу WORK вставляется строка, необходимо вставить соответствующую ей строку в таблицу TRANSACTION. Реализовать такие ограничения ссылочной целостности непросто. Эта тема обсуждается в главе 11, посвященной Oracle. Сделанные там замечания относят- ся равным образом и к Oracle, и к SQL Server. В листингах 11.7, а и б, показана пара триггеров, создающих строку в таблице TRANS при вставке в таблицу WORK и удаляющих ее, когда (и если) приложение са- мостоятельно вставляет строку в таблице TRANS после создания строки в таблице RK. Триггер в листинге 11.7, а, создает строку в таблице TRANS по умолчанию, начала он получает новое значение WorkID из псевдотаблицы inserted, а затем проверяет, нет ли доступной строки в таблице TRANS. Такой строки быть не должно, поскольку транзакция, создавшая строку в таблице WORK, еще не получила шанса вставить соответствующую строку в таблицу TRANS. После этого, если @@rowCount равняется нулю, трипер создает в таблице TRANS строку по умолчанию. EnforceTransChild" Триггеры для Реализации ограничения обязательного потомка: триггер CREATE TRIGGER EnforceTransChild ON Idbol rwORKi FOR INSERT L J AS
Логика приложения 523 DECLARE @newWorkID as Int /* Получаем новый WorkID */ SELECT @newWorkID = WorkID FROM inserted /* Проверяем, имеется ли доступная строка в таблице TRANS */ SELECT * FROM dbo.TRANS WHERE WorkID = @newWorkID AND CustomerlD IS NULL /* Если подходящей строки не найдено, вставляем строку */ If @@rowCount - О INSERT INTO dbo.TRANS (DateAcquired, WorkID) VALUES (GetDateO. OnewWorkID) Триггер в листинге 11.7, б, запускается при вставке в таблицу TRANS. Назначе- ние данного триггера — удалять из этой таблицы созданную по умолчанию стро- ку, если приложение собирается создать такую строку самостоятельно. Если приложение не запросит вставку такой строки, триггер запущен не будет, и дан- ные о транзакции для нового произведения будут записаны в строку, созданную предыдущим триггером. Листинг 11.7, б. Триггеры для реализации ограничения обязательного потомка: триггер RemoveDupTrans CREATE TRIGGER RemoveDupTrans ON [dbo].[TRANS] FOR INSERT AS DECLARE OWorkID as int. OTransID as int SELECT OWorkID = WorkID. OTransID = TransactionlD FROM i nserted /* Удаляем прочие доступные строки из таблицы TRANS */ DELETE FROM dbo.TRANS WHERf WorkID = OWorkID AND CustomerlD IS NULL AND TransactionlD <> OTransID На рис. 11.19 изображены результаты работы триггера при вставке строки в таблицу WORK. Как и следовало ожидать, в таблицы WORK и TRANS были добав- лены новые строки. Чтобы завершить тестирование, необходимо убедиться, что триггер таблицы TRANS удаляет строку, созданную по умолчанию, если такую строку собирается вставить приложение.
524 Глава 11 Работа с базами данных в SQL erver 2000 Рис. 11.19. Тестирование триггеров из листинга 11 7: вставка из Query Analyzer Как было отмечено в главе 10, более красивым решением для реализации ограничения обязательного потомка было бы потребовать от приложения, что- бы оно добавляло в базу данных новые произведения через представление WORK/ TRANSACTION, содержащее все необходимые данные для таблиц WORK и TRANSACTION. В этом случае вставку данных из представления WORK/TRANSACTION в таблицы WORK и TRANSACTION осуществлял бы триггер, а прямую вставку строк в эти таб- лицы следовало бы запретить. (См. проект 8 в конце главы.) Управление параллельной обработкой SQL Server 2000 предоставляет исчерпывающий набор возможностей для управ- ления параллельной обработкой. Количество вариантов выбора велико, и итого- вое поведение определяется взаимодействием трех факторов: уровня изоляции транзакции, характеристик курсора и блокировочных подсказок, заданных в пред- ложении SELECT. Блокировочное поведение зависит также от того, обрабатывает- ся ли курсор как часть транзакции, является ли оператор SELECT частью курсора и как подаются команды на обновление — из транзакции или независимо. В этом разделе мы обсудим только основы. За дальнейшей информацией об- ращайтесь к документации по SQL Server 2000. В SQL Server блокировки не налагаются напрямую. Вместо этого разработчик указывает требуемую стратегию управления параллельной обработкой, и SQL Server самостоятельно определяет, где налагать блокировки. Блокировки налагаются на строки, страницы, ключи, индексы, таблицы и даже на всю базу данных. SQL Server определяет необходимый уровень блокировки и может повышать или понижать его в ходе обработки. Также SQL Server определяет, когда налагать блокировку и когда снимать ее, в зависимости от предпочтений, сформулированных разработчиком. В таблице 11.1 представлены возможности управления параллельной обра* 01 кой. Самый обширный из них по количеству настроек — уровень изоляции транзакции. Возможные уровни изоляции перечислены в порядке возрастания ограничений в первой строке таблицы. Это те самые четыре уровня, которые вы изучали в главе И и которые определены в стандарте SQL-92. Обратите внпма-
ИЦ «Шапок ОАвтаои* ₽ОКВЭ1Ипб- ние, что в SQL Server можно разрешить «грязное» чтение, если установить уро- вень изоляции «незавершенное чтение» (READ UNCOMMITTED). По умолчанию установлен уровень изоляции «завершенное чтение» (READ COMMITTED). Таблица 11.1. Управление параллельной обработкой в SQL Server 2000 Тип Охват Варианты Уровень изоляции транзакции Соединение — все транзакции READ UNCOMMITTED READ COMMITTED REPEATABLE READ SERIALIZABLE Характеристики курсора Курсор READONLY OPTIMISTIC SCROLLLOCK Блокировочные подсказки SELECT READCOMMITTED READUNCOMMITTED REPEATABLEREAD SERIALIZABLE NOLOCK HOLDLOCK и другие... СОЙ ^.ИЯГЩЙЗ- Следующим по возрастанию ограничений уровнем изоляции является «воспро- изводимое чтение» (REPEATABLE READ), при котором SQL Server налагает и удер- живает блокировки всех строк, считываемых данной транзакцией. Это означает, что другие пользователи не могут изменить или удалить строку, которая была считана транзакцией, пока транзакция не будет зафиксирована или прервана. Повторное чтение курсора может, однако, привести к появлению фантомов. Наиболее жестким уровнем изоляции является «сериализуемость» (SERIALIZABLE). При нем SQL Server налагает блокировку на диапазон строк, считанных данной транзакцией. Тем самым гарантируется, что считанные данные не будут измене- ны или удалены и что в заблокированном диапазоне не будут вставлены новые строки, которые вызвали бы фантомное чтение. Обеспечение этого уровня изо- ляции обходится дороже всего, и его следует использовать только в тех случаях, когда он абсолютно необходим. В качестве примера можно привести следующий SQL-оператор, который уста- навливает уровень изоляции «воспроизводимое чтение»: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ Этот оператор можно поместить в любом месте, где допускается применение TRANSACT-SQL, но до выполнения любых действий с базой данных. Поведение курсора Второй способ объявления блокировочных предпочтений — задание поведения курсора (cursor concurrency). Возможны три варианта’ только чтение (READ_ONLY),
526 Глава 11. Работа с базами данных в SQL Server 2000 оптимистическая блокировка (OPTIMISTIC) и пессимистическая блокировка (в SQL Server обозначается SCROLL_LOCK). Как говорилось в главе 9, при оптимистически стратегии блокировки никаких блокировок не налагается, пока пользователь обновит данные. После этого, если ранее считанные данные были изменены, об- новление отклоняется. Разумеется, прикладная п|хл рамма должна указать, ( нужно делать, когда происходит отказ в обновлении. SCROLL.LOCK представляет собой вариант пессимистической блокировки. В этом случае при считывании любой строки на нее налагается блокировка обновления Если курсор открывается из транзакции, блокировка удерживается до тех пор пока транзакция не будет зафиксирована или отменена. Если курсор открывается вне транзакции, блокировка снимается при чтении следующей строки Вспомни- те из главы 9, что одна блокировка обновления может воспрепятствовать другой блокировке обновления, но не коллективной блокировке. Таким образом, в дру- гих соединениях эта строка может читаться при коллективной блокировке. Поведение курсора по умолчанию зависит от типа курсора (см. главу 9). Для статических и последовательных курсоров это только чтение, а для динамиче- ских и ключевых — оптимистическая блокировка. Поведение курсора задается с помощью оператора DECLARE CURSOR. В качестве примера приведем следующий оператор, который объявляет динамический кур- сор с пессимистической блокировкой, распространяющийся на все строки таб- лицы TRANS: DECLARE MY_CURSOR CURSOR DYNAMIC SCROLL_LOCKS FOR SELECT * FROM dbo.TRANS 1 Блокировочные подсказки Дальнейшее изменение блокировочного поведения возможно с помощью бло- кировочных подсказок (locking hints) в параметре WITH предложения FROM опера- тора SELECT. В табл. 11.1 перечислены некоторые из блокировочных подсказок, возможных в SQL Server. Первые четыре подсказки переопределяют уровень изоляции транзакции, а две другие влияют на тип налагаемой блокировки. Рассмотрим следующие операторы: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ DECLARE MY_CURSOR CURSOR DYNAMIC SCROLL_LOCKS FOR “ SELECT * FROM TRANS WITH READUNCOMMITTED NOLOCK RFP^Tapfc ос?ОВО^НЫХ П0Дсказ0к курсор MY_CURSOR имел бы уровень изоляции D и блокировал бы обновление всех считанных строк. Эти блокнров- удерживались бы до тех пор, пока транзакция не была бы сохранена. Благода- локировочным подсказкам этому курсору присваивается уровень изоляции
5 .'' ' 7<«*й£ Безопасность 527 ч ''ЧТО dbo.TRANS WITH HOLDLOCK ***-B^y. L"'-r9H-« READ UNCOMMITTED. Кроме того, параметр NOLOCK изменяет тип курсора с DYNAMIC на READ-ONLY. Рассмотрим другой пример: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ declare my_cursor cursor dynamic scroll_locks FOR select * FROM Эта блокировочная подсказка заставит SQL Server удерживать блокировку обновления всех считанных строк, пока транзакция не будет сохранена. В резуль- тате уровень изоляции транзакции вместо REPEATABLE READ станет SERIALIZABLE. Вообще говоря, начинающим не рекомендуется пользоваться блокировочны- ми подсказками. Пока вы не стали экспертом в этом, задавайте уровень изоля- ции и характеристику курсора так, как это принято делать. >-'• К.-., инвиайюр- се строки пб- Безопасность В общих чертах безопасность баз данных обсуждалась в главе 9. Здесь мы вкратце рассмотрим, как эти общие идеи реализуются в системе безопасности SQL Server. Дальнейшую информацию о безопасности в SQL Server можно найти на сайге msdn.microsoft.com. Настройки безопасности SQL Server На рис. 11.20 изображено окно настроек SQL Server. Это окно можно вызвать, щелкнув правой кнопкой мыши на имени сервера в программе Enterprise Manager. Перейдите в этом окне на вкладку Security (Безопасность). Как видно из рисунка, SQL Server предусматривает два режима идентифи- кации. В одном режиме (Windows Only) идентификация производится средства- ми операционной системы Windows. Имя пользователя, указанное при входе в систему, будет передано SQL Server в качестве имени пользователя базы дан- ных. В другом режиме (SQL Server and Windows) SQL Server либо примет имя поль- зователя от операционной системы, либо осуществит идентификацию само- стоятельно, выдав диалог с приглашением ввести имя пользователя и пароль. Этот режим идентификации называется иногда режимом смешанной безопасно- сти (mixed security). Более высокий уровень безопасности достигается при использовании иден- тификации средствами Windows. Однако есть ряд старых программ (например, ERWin), которые требуют идентификации SQL Server. Если необходимо обеспе- чить работу таких программ с SQL Server, следует выбрать режим смешанной безопасности. Обратите также внимание, что неудачные попытки входа в систему необходимо •вписывать н журнал. Как говорилось в главе 9, администратор базы данных
528 Глава 11. Работа с базами данных в SQL Server 2000 _ - ". ......... । ши* должен регулярно проверять этот журнал для выявления телыюсти. иодоэритсльиой Дед. Рис. 11.20. Настройки безопасности SQL Server Winrlmv”611' согласно ряс‘ 1L20, SQL Server должен работать под учетной записью тол1 ко С ИМенем ^Permissions. Это специальная учетная запись, имеющая СУБД п.^,,1ШаЛЬНЬ1И Нйб?Р поли°мочий, необходимых для работы СУБД. Если го nonvqeirMoV П°Д таков Учетн°й записью, то в случае несанкционированно- мальпо воамп- К°НТроля пад SQL Server злоумышленник будет иметь мнни- SOL Server г Прнвилс™” в операционной системе. Никогда не запускайте четных записей, принадлежащих группе Windows Administrator. ад^°2ЙКИ 6бЗОПаснос™ учетной записи На рис. 11.21 показан вид окон в записей SQL Server. Эти окна м' ° °рЫХ настраиваются полномочия учетных значке Security/Logins (Безопас ^110 ™3вать’ Ц[елК|1ун правой кнопкой мыши на брав New Login (Новый пользовав/У°ЛЬ30ватели) « в контекстном меню вы- чмеет имя VRSalesperson и для ЭТеЛЬ'‘ Как 1,оказано на рис. 11.21, а, пользователь тифнкация пользователя ппоиТ™ ПСПОльзУется Домен Windows DBGRV101. Иден- базы данных по умолчанию выбрано7КсРедСТВаМИ Windows> а в качестве имени
Безопасность 529 а б Рио. 11.21. Создание ноиого пользователя: а — задание свойств пользователя; б “ определение баз данных, к которым пользователь имеет доступ
530 Глава 11. Работа с базами данных в SQL Server 2000 На рпс. 11.21. б, изображена вкладка Database Access (Доступ к базе данных) того же окна. Здесь пользователю дано право обращаться к базе данных VR6 в рац ках роли Public. Роль - это предопределенный набор полномочий (роли обсуж- даются далее). По умолчанию роль Public имеет полномочия только на соеди ние с базой данных. Чтобы позволить пользователю данной учетной записи нечто большее, чем просто соединяться с базой данных, необходимо предоставить ему дополнитель- ные полномочия. На рис. 11.22 показан вид окон, в которые настраиваются пол- номочия. Чтобы вызвать окно User Properties (Свойства пользователя), щелкните правой кнопкой мыши на значке Users (Пользователи) в интересующей вас базе данных (в данном случае это база данных VRG) и в контекстном меню выберите Properties (Свойства). В открывшемся окне щелкните па кнопке Permissions (Пол- номочия), и появится окно Permissions, изображенное в правой части рисунка В данном примере пользователю VBSalesperson было дано право выполнять встав обновление и удаление в таблицах ARTIST и CUSTOMER. Этот пользователь также имеет полномочия на запрос данных из представления ArtistWorkNet и выполне- ние хранимой процедуры Customerjnsert. МИ General | папе: D6GRV101\VR ale:psfs$n Peirrussrons. User паи»: VRSalesperson Dalebase rcte merrberxbtp Permfl in Database Pole "j db.owner db_accessadmin db_secufityadmin db_ddladmin dD.backupoperalof 7/ db.dalaeader 3 db_dataw«tef db_denyda»areadei db.denydatawffler OK 1 Cancpf I Рис. 11.22. Задание полномочий пользователя Настройки безопасности ролей Олна'кл пРимеРе присвоили полномочия определенному пользователю- набоп п министратор базы данных может сэкономить свое время, определи® олеи и дав этим ролям необходимые полномочия. Затем когда пользе®*
Резервное копирование и восстановление 531 телю будет назначена определенная роль, этот пользователь унаследует все ее полномочия. Кроме того, когда у роли будет отобрано какое-то полномочие, оно автоматически отберется и у всех учетных записей, имеющих эту роль. На рис. 11.23 показано окно, позволяющее определять роли и назначать их учетным записям. Это окно можно вызвать, щелкнув правой кнопкой мыши на значке Roles (Роли) базы данных VRG (или какой-либо другой базы) и в контекст- ном меню выбрав пункт New Database Role (Создать роль для базы данных). Что- бы присвоить роли полномочия, щелкните на кнопке Permissions (Полномочия), как это было сделано для учетной записи на рис. 11.22. Я Gajaal f) VRSalesperson | Petmrssions... | GalteryStalf Database role Ope: User SQL S eiver supports two types of database roles: standard roles, which contain .members, and application j.pk?.,...Which roguire a password Рис. 11.23. Назначение ролей пользователям Резервное копирование и восстановление Когда вы создаете базу данных SQL Server, генерируются файлы данных и жур- налов. Как объяснено в главе И, следует периодически делать резервные копии этих файлов. Это позволит впоследствии восстановить базу данных после сбоя, скопировав ее из ранее сделанного снимка и воспроизведя изменения, зафикси- рованные в журнале. Чтобы восстановить базу данных, SQL Server берет ранее сделанную резерв- ную копию и на нее накладывает конечные образы из журнала. Когда достигает- ся конец журнала, изменения, вызванные незафиксированными транзакциями, отменяются.
532 Глава 11. Работа с базами данных в SOL Server 2000 Можно также обрабатывать журнал до определенно.о момента времени или Можно также Р н„ПО11Мер выполнение оператора до метки транзакции, например. BEGIN TRANSACTION NewCust WITH MARK .гпжлом запуске этой транзакции в журнале будет ставить- приведет к тому, чт 1 ‘ NewCust. В этом случае можно будет восстановить ся метка транзакци непосредственно до или после самой первой метки журнал до точки, после определенного момента времени. Затем NewCust либо первой журнала можно будет восстановить базу данных, с помощью вое « У такие меткп расходуют место в журнале, по- Типы резервных копий SQL Server поддерживает несколько типов резервных копий. Чтобы увидеть их, откройте Enterprise Manager, откройте папку Databases и правой кнопкой мыши щелкните на имени базы данных. Выберите пункт All Tasks (Все задачи), затем Backup Database (Создать резервную копию базы данных). Появится диалоговое окно, изображенное на рис. 11.24. Теперь вы можете создать резервную копию ба- зы данных (полную или разностную), журнала транзакции или, отдельных фай- лов и групп файлов. Рис. 11.24. Диалоговое окно создания резервной копии ^ВОСС .._ * 5-
Резервное копирование и восстановление 533 Как следует из названия, полная резервная копия (complete backup) — это копия всей базы данных. Разностная резервная копия (differential backup) пред- ставляет собой копию изменений произведенных в базе данных с того момента, как была сделана последняя полная копия. Это значит, что, прежде чем делать первую разностную копию, необходимо сделать полную копию. Поскольку раз- ностные копии делаются быстрее, их можно делать чаще, тем самым снижая вероятность потери данных. С другой стороны, с помощью полных копий, хотя они и требуют более продолжительного времени для снятия, восстанавливать базу данных несколько проще, как вы увидите далее. Журнал транзакций также нужно периодически копировать, чтобы гаран- тировать сохранность его содержимого. Кроме того, журнал транзакций необ- ходимо скопировать перед тем, как использовать его для восстановления базы данных. Резервные копии можно делать на диске или на магнитной ленте. По возмож- ности, их следует делать на иных устройствах, чем те, где хранится действующая база данных с журналами. Использование для этих целей съемных устройств позволяет хранить резервные копии в месте, физически удаленном от центра обработки данных. Это важно для восстановления после разрушений, вызван- ных стихийными бедствиями — наводнениями, ураганами и т. п. Модели восстановления SQL Server SQL Server предусматривает три модели восстановления (recovery models): про- стую, полную и выборочную. Задать модель восстановления можно, щелкнув правой кнопкой мыши на имени базы данных в Enterprise Manager и выбрав Properties (Свойства). Модель восстановления задается во вкладке Options (Пара- метры). Пример изображен на рис. 11.25. При простой модели восстановления (simple recovery) журнал не ведется. Единственный способ восстановить в этом случае базу данных — это активиро- вать последнюю резервную копию. Изменения, сделанные после снятия этой ко- пии, будут потеряны. Простую модель восстановления можно использовать для базы данных, содержимое которой никогда не меняется, — например, для базы данных закрытого кладбища, содержащей имена покойных и сведения о распо- ложении их могил. Это может быть также база данных, используемая для анализа в режиме «только чтение» информации, поступившей из какой-то другой транз- акционной базы данных. При полной модели восстановления (full recovery) в журнал заносятся все из- менения, произведенные в базе данных, а при выборочной модели (bulk-logged recovery) — все, кроме тех, которые приводят к появлению в журнале записей больших размеров Сюда огпося гея изменения в объемных текстовых и графиче- ских элементах данных, действия наподобие CREATE INDEX и некоторые другие операции С большим объемом данных. Организация может использовать выбо- рочный режим веке глновлг пня, ее ш для нее важно жоиомигь место в журналах и если данные, которые используются в указанных выше операциях, сохраняют- ся еще каким-либо обрагом.
----534 Глава 11. Работа с базами данных в SQL Server 2000 < Рис. 11.25. Параметры модели восстановления Восстановление базы данных Если есть должным образом сделанные резервные копии базы данных и журна- лов, восстановление базы данных производится элементарно. Первым делом сле- дует восстановить текущий журнал, чтобы сделать доступными изменения, запи- санные в самом последнем журнале. После этого щелкните правой кнопкой мыши на имени базы данных в Enterprise Manager, выберите пункт ALL Tasks и за- тем Restore Database (Восстановить базу данных). Появится диалоговое окно, изо- браженное на рис. 11.26. В лом примере база данных VRG восстанавливается под именем VRG Restore. Менять имя базы данных не обязательно. Здесь замысел состоит в том, чтобы восстановить базу данных под другим именем, проверить ее, удалить то, что оста- лось oi старой базы, а затем переименовать восстановленную базу данных в VRG. План обслуживания базы данных С целью решения различных задач, среди которых упрощение создания резерв пых копии базы данных и журналов, вы можете создать план обслуживания (maintenance plan) базы данных. Для этой цели в SQL Server существует специаль- ный мастер. Чтобы его вызвать, щелкните правой кнопкой мыши на имени базы
Вопросы, не затронутые в этой главе 535 данных, выберите пункт All Tasks и затем Maintenance Plan (План обслуживания). Этот мастер поможет вам в организации выполнения различных задач по распи- санию. Эти задачи включают в себя реорганизацию индексов и другие связанные с этим действия. Однако важно здесь то, что вы можете организовать автоматиче- ское резервное копирование данных и журналов по расписанию. Рис. 11.26. Восстановление базы данных до состояния на определенный момент времени Вопросы, не затронутые в этой главе Есть несколько важных вопросов, связанных с SQL Server, которые не были за- тронуты в этой главе. Во-первых, в SQL Server имеются утилиты для измерения производительноеги базы данных. Администратор базы данных может исполь- зовать эти утилиты при настройке базы данных. Еще одна возможность, не опи- санная здесь, — это соединение Access с SQL Server. Информацию по этой теме можно найти в документации па Access. Как упоминалось выше, в SQL Server имеются средства для поддержки распре- деленной обработки баз данных, которая в SQL Server называется репликацией (replication). Эти среде та используют модель распределенной обработки «п\б ликация -подписка», которую мы будем рассматривать в главе 15. Тема распре- деленной обработки данных, хотя и важна сама по себе, гем не менее выходит за рамки данной книги. Microsoft предоставляет сервер OLE DB под названием
536 Глава 11. Работа с базами данных i SQL Server 2000 Distributed Transaction Manager (Диспетчер р ипределеиных транзакций), едзд. рып координирует распределенные транзакции. Java поддерживает теадологмк> под названием Enterprise Ja\ i Beans, служащую тем же целям Мы коснемся этих вопросе в в главах 12 и 14. Наконец, в SQL Server имеются средства для представления результатов ра- боты операторов SELECT в виде XML-документов. Эта во >можиость будет обсуж даться нами в главе 13. Резюме SQL Server 2000 может устанавливаться на компьютерах под управлением Win- dows 2000 и Windows ХР. Есть два способа создания таблиц, представлений, ин- дексов и других структур базы данных. Первый способ — использовать средства графического проектирования, подобные имеющимся в Access. Второй способ со- стоит в написании SQL-операторов, создающих эти структуры, и передаче их на выполнение SQL Server с помощью программы SQL Query Analyzer. В SQL Server используются те же самые SQL-операторы, которые рассматрива- лись нами в главах 6-8. Единственным новым выражением является IDENTITY(m,n). Это выражение предписывает SQL Server создать суррогатный ключ с началь- ным значением т и приращением п. Индексы — это специальные структуры данных, используемые для повыше- ния производительности базы данных. SQL Server автоматически создает индекс по всем первичным и внешним ключам. Дополнительные индексы создаются с помощью оператора CREATE INDEX или графического средства Manage Index. SQL Server поддерживает кластеризованные и некластеризованные индексы. SQL Server имеет входной язык под названием TRANSACT-SQL, в котором помимо базовых SQL-операторов предусмотрены программные конструкции — параметры, переменные и логические структуры (IF, WHILE и т. д.). Базы данных SQL Server можно обрабатывать из прикладных программ, на- писанных на стандартных языках программирования, таких как Visual Basic или С#, или посредством хранимых процедур и триггеров. Хранимые процедуры мо- гут вызываться из стандартных языков программирования или из веб-сценариев, написанных на VBScript или JScript. В настоящей главе хранимые процедуры вызывались из программы Query Analyzer. Это следует делать лишь на стадии разработки и тестирования. По соображениям безопасности не следует разрешать доступ к рабочей базе данных SQL Server в интерактивном режиме. В этой главе были приведены примеры триггеров, реализующих бизнес-правило, рассчнты вающих значение по умолчанию, обновляющих представление и реализуюшп ограничение обязательного потомка. Поведение SQL Server при управлении параллельной обработкой ОПРСД^0. ется тремя факторами: уровнем изоляции транзакции, поведением курс кировочными подсказками, данными пользователем в предложении SEL ’ н факторы представлены в табл. 11.1. Поведение также меняется в зависим от того, каким образом происходят изменения — в контексте транзакции, в
Вопросы группы I 537 тексте курсоров пли независимо. Имея блокировочные предпочтения, указанные разработчиком, SQL Server самостоятельно налагает блокировки. Блокировки могут налагаться с различной глубиной детализации, которая в ходе обработки может быть увеличена или уменьшена. SQL S iver поддерживает создание резервных копий журналов, а также пол- ных н разностных резервных копий базы данных. Предусмотрены три модели восстановления, простая, полная и выборочная. При простой модели журнал не ведется и записи из журнала не обрабатываются. При полной модели все опера- ции. выполняемые с базой данных, заносятся в журнал и затем воспроизводятся при восстановлении. В случае выборочной модели при ведении журнала опуска- ются определенные виды транзакций, па запись которых расходуется много места. Вопросы группы I 1. Установите SQL Server 2000 и создайте базу данных под названием MEDIA (мои картинки). Для размеров, имен и местоположения файлов оставьте параметры, задаваемые по умолчанию. 2. Напишите SQL-оператор, создающий таблицу под названием PICTURE (слайд) со столбцами Name (название), Description (описание), DateTaken (дата съемки) и FileName (имя файла). Пусть Name имеет тип char(20), Description — varchar(200), DateTaken — smalldatetime, a FileName — char(45). Кроме того, пусть атрибуты Name и DateTaken являются обязательными. Используйте Name в качестве первичного ключа. Задайте для столбца Description по умолчанию значение ’(None)’ ('(Нет)’). 3. С помощью SQL Query Analyzer выполните оператор из вопроса 2 и соз- дайте в базе данных MEDIA таблицу PICTURE. 4. Откройте базу данных MEDIA в Enterprise Manager и откроите окно проек- тирования базы данных для таблицы PICTURE. В этом окне добавьте в таб- лицу столбец-идентификатор PicturelD, задав для него начальное значе- ние 300 и приращение 25. Поменяйте первичный ключ с Name на PicturelD. 5. С помощью графического средства проектирования таолпц задайте значе- ние по умолчанию для столбца DateTaken равным системной дате. 6. Создайте ограничение под названием Valid_Description (допустимые опи- сания), определяющее следующее множество значений. { Home, Office, ’Family’, 'Recreation', 'Sports', 'Pets'} (дом, работа, семья, отдых, спорт, живот- ные). Ответьте па вопрос 2, по используйте это ограничение для столбца Description. 7. С помощью 1 рафичес кого средства проектирования. 1) сделайie длину столбца Name равной 50 символами; 2) удалите столбец DateTaken; 3) добавыс столбец TakenBy (кто снимал), имеющий тин char(40).
538 Глава 11. Работа с базами данных в SQL Server 2000 8. Создайте таблицу SLIDE-SHOW (презентация), имеющую столбцы ShowID (номер презентации), Name (название), Description (описание), Purpose (цель) Пусть ShowID будет суррогатным ключом. Задайте тип данных для столб- цов Name и Description так, как считаете нужным. Для столбца Purpose ука жпте тип данных Subject. Используйте SQ1 .-опера гор CREATE или средство графического проектирования таблиц. 9. Создайте таблицу SHOW-PICTURE-INT, представляющую собой пересечение таблиц PICTURE и’SLIDE-SHOW. 10. Создайте необходимые связи между таблицами PICTURE и SHOW-PICTURE-INT, а также между таблицами SLIDE-SHOW и SHOW-PICTURE-INT. Установите ре- жим обеспечения ссылочной целостности таким образом, чтобы запретить удаление из таблицы SLIDE-SHOW строк, имеющих связанные с ними стро- ки в таблице SHOW-PICTURE-INT. Обеспечьте также каскадные удаления при удалении строки из таблицы PICTURE. И. Объясните, как установить каскадное удаление для связей из вопроса 10. 12. Напишите SQL-оператор, создающий представление PopularShows (популяр- ные презентации), содержащее столбцы SLIDE-SHOW.Name и PICTURE.Name всех презентаций, у которых столбец Purpose имеет значение 'Ноте' или 'Pets'. Запустите этот оператор на выполнение с помощью SQL Query Analyzer. 13. Откройте средство проектирования представлений и убедитесь, что пред- ставление PopularShows было построено правильно. Модифицируйте это представление, добавив в него столбцы Description и FileName. 14. Может ли SQL-оператор DELETE использоваться с представлением Popular- Shows? Почему? 15. При каких условиях представление PopularShows допускает вставку и мо- дификацию? 16. Создайте индекс по столбцу Purpose. Воспользуйтесь для этого средством графического проектирования Manage Index. 17. Для чего используется переменная ©Count в листинге 11.2? 18. Зачем нужен оператор SELECT, который начинается с SELECT ©Cid? 19. Объясните, как бы вы изменили хранимую процедуру в листинге П-2, чтобы связать клиента со всеми художниками, которые (а) родились до 1900 года ши (б) имеют нулевое значение атрибута BirthDate. 20. Объясните, в чем назначение транзакции на рис. 11.16. 21. Что произойдет, если хранимой процедуре в листинге 11.3 будет передано неправильное значение атрибута Сору? 22. Что произойдет, если в хранимой процедуре из листинга 11.3 будет вы полнен оператор ROLLBACK? 23. Объясните использование оператора JOIN в листинге 11.4. 24. Почему в листинге 11.5 используется функция SUM вместо AVG?
Проекты 539 25. Каковы три основных фактора, определяющих блокировочное поведение SQL Server? 26. Раскройте смысл каждого из четырех уровней изоляции транзакции, пере- численных в табл. 11.1. 27. Раскройте смысл каждого из трех типов поведения курсора, перечислен- ных в табл. 11.1. 28. В чем назначение блокировочных подсказок? 29. Чем полная резервная копия отличается от разностной? В каких случаях рекомендуется делать полные резервные копни, а в каких — разностные? 30. Объясните разницу между простои, полной п выоорочнон моделями вос- становления. Для каждой модели опишите условия, при которых вы бы се выбрали. 31. Когда необходимо восстановление базы данных до состояния па опреде- ленный момент времени? Проекты Для выполнения следующих заданий используйте либо программу Quay Analyzer, либо Enterprise Manager — на ваше усмотрение. 1. Установите SQL Server и создайте базу данных View Ridge. 2. Создайте таблицы согласно листингу 11.1, но не создавайте ограничение NationalityValues. 3. Заполните базу данных информацией. Пусть у вас будет по меньшей ме- ре три клиента, три художника, пять произведений и пять транзакций. Национальность художника должна иметь одно из трех значений: 'German', 'French' или 'English'. 4. Напишите хранимую процедуру для чтения данных из таблицы ARTIST и вы- вода их на экран с помощью команды Print 5. Напишите хранимую процедуру, считывающую данные из таблиц ARTIST и WORK. Ваша процедура должна выводить сведения о первом художнике и всех его работах, затем о следующем художнике, и т. д. Пусть имя худож- ника, информацию о котором нужно вывести, будет входным параметром процедуры. 6. Напишите хранимую процедуру, записывающую в базу данных новый но- мер телефона клиента. Пусть ваша процедура принимает в качестве вход- ных параметров имя клиента, старый код региона, новый код региона, ста- рый номер телефона и новый помер телефона. Прежде всею процедура должна взять имя клиента, старый код региона и старый номер телефона и убедиться, что в базе данных есть только один клиент с такими данными. Если такой клиент не один, процедура должна вывести сообщение об
540 Глава 11 Работа с базами данных в SUL server 2000 ошибке и завершить гною paooiy. В нроишпом случае п|хшедура ДОДкц* записать в базу данных новые код региона и телефон клиента, 7. Создайте таблицу е именем ALLOWED NATIONALITY (допустимая националу ность), содержащую один столбец - Nation. Поместите в эту табли чения 'German', 'French' п 'English' Напишите трш Гер, который при t и обновлении строки в таблице ARTIST будет искат ь новое значение столб- ца Nationality в таблице ALLOWED_NATIONALITY. Если поиск завершился не- удачно, триггер должен вывести сообщение об ошибке и выполнить откат вставки пли изменения. Продемонстрируйте корректную работу триггера, используя Query Analyzer. 8. Создайте представление, содержащее все данные из таблиц WORK и TRANS- ACTION. Напишите для этого представления замещающий триггер вставки, который будет создавать новую строку в таблицах WORK и TRANSACTION Продемонстрируйте корректную работу вашего триггера, используя Query Analyzer. Вопросы к проекту FiredUp Создайте с помощью SQL Server базу данных со следующими четырьмя таблицами: КЛИЕНТ (ИдКлиента, Имя, Телефон, АдресЭлПочты) ГОРЕЛКА (СерийныйНомер, Тип, Версия, ДатаВыпуска) РЕГИСТРАЦИЯ (КлиентСК, СерийныйНомер, Дата Ре г) РЕМОНТ_ГОРЕЛКИ (НомерСчета, СерийныйНомер, ДатаРемонта, Описание, Стоимость. ИдКлирнгпа) Пусть первичные ключи таблиц КЛИЕНТ, ГОРЕЛКА и РЕМОНТ_ГОРЕЛКИ являются суррогатными ключами. Создайте для них последовательности. Создайте связи, реализующие следующие ограничения ссылочной целостности: ♦ значение столбца ИдКлиента в таблице РЕГИСТРАЦИЯ существует среди зна- чений столбца ИдКлиента в таблице КЛИЕНТ; ♦ значение столбца СерийныйНомер в таблице РЕГИСТРАЦИЯ существует среди значений столбца СерийныйНомер в таблице ГОРЕЛКА, ♦ значение столбца СерийныйНомер в таблице РЕМОНТ_ГОРЕЛКИ существует среди значении столбца СерийныйНомер в таблице ГОРЕЛКА: > значение столбца ИдКлиента в таблице РЕМОНТ,ГОРЕЛКИ существует сред» значений столбца ИдКлиента в таблице КЛИЕНТ. Не включайте каскадные удаления Далее проделайте следующее. 1. Заполните ваши таблицы данными и отобразите их па экране. 2. Создайте хранимую процедуру для регистрации горелки. Процедура полУ чает в качестве входных параметров имя, телефон, адрес электронно» п
Вопросы к проекту Twigs Tree 541 чты клиента и серийный номер горелки. Если данный клиент уже имеется в базе данных (имя, телефон и электронный адрес совпадают), записывай- те его ИдКлиента в таблицу РЕГИСТРАЦИЯ. В противном случае создайте для этого клиента новую строку в таблице КЛИЕНТ. Будем предполагать, что го- релка с заданным серийным номером уже существует в базе данных. Если это не так, выведите сообщение об ошибке и отмените изменения, сделан- ные в таблице КЛИЕНТ. Написав процедуру, протестируйте ее. 3. Создайте хранимую процедуру для регистрации ремонта горелки. Про- цедура получает в качестве входных параметров имя, телефон и адрес электронной почты клиента, серийный номер горелки, описание и стои- мость ремонта. Будем предполагать, что заданный серийный номер суще- ствует; если это не так, выведите сообщение об ошибке и не производите в базе данных никаких изменений. Используйте существующую строку в таблице КЛИЕНТ, если имя, телефон и электронный адрес совпадают; в про- тивном случае создайте новую строку в таблице КЛИЕНТ. Предположим, что строка в таблице РЕМОНТ_ГОРЕЛКИ должна быть создана. Зарегистри- руйте горелку, если необходимо. 4. Создайте представление под названием РегистрацияКлиента, содержащее все данные из таблиц КЛИЕНТ, ГОРЕЛКА и РЕГИСТРАЦИЯ. Создайте замещаю- щий триггер вставки для этого представления. Предположим, что пользо- ватель задал значения столбцов ИдКлиента, Имя, Телефон, АдресЭлПочты и СерийныйНомер. Если такого клиента нет в базе данных, создайте для него новую строку в таблице КЛИЕНТ. Зарегистрируйте горелку на этого клиен- та. Если казанный пользователем серийный номер отсутствует в таблице ГОРЕЛКА триггер должен вывести сообщение об ошибке и не предприн J- мать никаких дальнейших действий. Продемонстрируйте корректно ю ра- боту триггера. Вопросы к проекту Twigs Tree Создайте с помощью SQL Server базу данных с тремя таблицами. ВЛАДЕЛЕЦ (ИмяВдидтиа. Телефон, Дом. Улица. Город, Штат. Индекс) РАБОТА ГДатаВыаолнения Описание, Стоимость, Уплачено, ДатаВы- платы) ДОСТАВКА_СТРУЖКИ (Им&ШвнгМ- ДизДэсШКй. Объем. Стоимость. Уплачено, Да- таВыплаты) Создайте связи, реализующие следующие ограничения ссылочной целостности: ♦ значение столбца РАБОТА.ИмяВладельца существует среди значений столб- ца ВЛАДЕЛЕЦ.ИмяВладельца, ♦ значение столбил ДОСТАВКА СТРУЖКИ.ИмяКлиента существует средн значе- ний столбца ВЛАДЕЛЕЦ.ИмяВладельца. Включите каскадное удаление и обновление
542 Глава 11 Работа с базами данных в SQL geiw 2000 Далее проделайте следующее, 1, Заполните ваши таблицы данными и отобразите их на экране 2, Создайте хранимую процедуру, назначающую выполнение работы на деленную дату. Пусть процедура получает псе данные о владельце, «виса* ние работы и дату в качестве входных параметрон. Если клиент уже имеется в базе данных, используйте существующие данные. В противном случаи создайте новую строку в таблице ВЛАДЕЛЕЦ. Добавьте строку в таблицу РАБОТА. Протестируйте вашу процедуру. 3. Создайте хранимую процедуру, назначающую доставку стружки на опре- деленную дату. Пусть процедура получает все данные о владельце, дату доставки, объем груза и стоимость в качестве входных параметров Если клиент уже имеется в базе данных, используйте существующие данные Не назначайте доставку, если у клиента имеется задолженность по рабо- там пли доставке стружки. Выведите в этом случае сообщение об ошибке. Задолженность существует, если столбец Стоимость не пуст, а столбец Упла- чено является пустым. 4. Создайте представление РаботаДляКлиента, содержащее все данные из таб- лиц ВЛАДЕЛЕЦ и РАБОТА. Создайте для этого представления замещающий триггер вставки. Предположим, пользователь предоставит все данные о поль- зователе, а также дату выполнения и описание работы. Если такого клиен- та нет в базе данных, создайте новую строку в таблице ВЛАДЕЛЕЦ. Добавьте строку в таблицу РАБОТА. Продемонстрируйте корректную работу вашего триггера. ч» 0
Часть V Стандарты доступа к базам данных Три главы этой части посвящены стандартам обработки приложений баз данных. Для начала, в главе 12 мы обсудим старые стандарты, такие как ODBC, OLE DB и ADO. Несмотря на то, что их уже давно нельзя назвать передовыми, они и по сей день используются во многих приложениях, и вероятность того, что нам при- дется столкнуться с ними в повседневной практике, весьма велика. В главе 13 речь пойдет об одном из важнейших достижений современности в области пи формационных технологий — слиянии задач обработки баз данных и обработ- ки документов. Вы получите представление об XML и XML Schema, узнаете об особенностях и функциях ADO.NET, в частности, о том, что касается объектов DataSet. Наконец, в главе 14 описывается применение Java-технологий JDBC и Java Server Pages. Здесь же рассказывается о MySQL — программном продукте DBMS с открытым исходным кодом. Надо сказать, что все примеры, описываемые в главе 14, создавались именно с использованием ПО с открытым исходным кодом.
Глава 12 ODBC, OLE DB, ADO и ASP В этой главе рассматриваются стандартные интерфейсы для доступа к серверам баз данных. ODBC (Open Database Connectivity standard, открытый стандарт со- вместимости баз данных) был разработан в начале 1990-х годов с целью обеспе- чить независимый от СУБД способ обработки информации из реляционных баз данных. В середине 1990-х годов компания Microsoft представила OLE DB - объектно-ориентированный интерфейс, имеющий функциональность сервера дан- ных. Как вы узнаете, OLE DB был разработан не только для реляционных баз данных, но и для многих других типов источников данных. Будучи СОМ-интерфей- сом, OLE DB непосредственно доступен из C++, C# и Java, но недоступен из Visual Basic и сценарных языков. Поэтому компания Microsoft разработала ADO (Active Data Objects) — набор объектов, позволяющий использовать OLE DB из любых языков программирования, включая Visual Basic, VBScript и JScript Прежде чем рассматривать эти стандарты, составим сначала представление о том, какое окружение имеет веб-сервер в приложениях баз данных, использую- щих Интернет-технологии. Информационное окружение веб-сервера Окружение, в котором находятся современные приложения баз данных, исполь- зующие Интернет-технологии, весьма многообразно и сложно по составу. Как показывает рис. 12.1, типичный веб-сервер должен публиковать приложения, со- держащие данные из множества различных источников. Пока что мы рассмат- ривали только реляционные базы данных, однако, как вы можете видеть на этом рисунке, существуют и другие типы источников данных. ассмотрим, с какими проблемами сталкивается разработчик серверных прило- жении при интеграции данных из различных источников В качестве таких ис- точников могут выступать база данных Oracle, база данных DB2 для больших М, нереляционная база данных IMS, системы обработки файлов VSAM и ISAM- папки электронной почты и т. д. Каждый из этих продуктов имеет свой соост епиыи программны!! интерфейс, который разработчик должен выучить. Кроме того, каждый из этих продуктов меняется, и со временем будут добавлены новые зможности и функции, что еще больше усложнит задачу' разработчика.
--------------------- Информационное окружение веб-сервера 545 Реляционные базы данных, Oracle, SQL Server, Access, DB2, . Нереляционные базы данных VSAM, ISAM, другие обработчики файлов Электронная почта, другие типы документов Картинки аудиофайлы прочее Рис. 12.1. Разнообразие типов данных Стандарт ODBC был разработан для решения той части данной проблемы, которая относится к реляционным базам данных и источникам данных, имею- щим табличную организацию, например электронным таблицам. Как показано на рис. 12.2, ODBC является интерфейсом между веб-сервером (или другим пользователем базы данных) и сервером базы данных. Он представляет собой набор стандартов, позволяющих, кроме прочего, запускать на выполнение SQL- операторы и возвращать результаты и сообщения об ошибках. Из рисунка по- нятно, что разработчики могут обращаться к серверам данных через «родные» интерфейсы, если таковы их предпочтения (иногда это делается для увеличения производительности), но когда работы слишком много, а время и желание изучать множество библиотек собственных интерфейсов СУБД отсутствуют, то вместо этих библиотек можно пользоваться ODBC. Стандарт ODBC имел большой успех, поскольку чрезвычайно упростил некото- рые задачи, связанные с разработкой баз данных. Как вы узнаете, у него есть существенный недостаток, для преодоления которого Microsoft разработала стандарт OLE DB. На рис. 12.3 представлены отношения между OLE DB, ODBC и другими типами источников данных. OLE DB предоставляет объектно-ориен- тированный интерфейс к источникам данных почти любого типа. Производите- ли СУБД могут заключать фрагменты «родных» библиотек в объекты OLE DB, благодаря чему функции этих библиотек становятся доступными через интерфейс OLE DB. Кроме того, OLE DB можно использовать как интерфейс к источникам Данных ODBC. Наконец, в OLE DB предусмотрена поддержка п нереляционных источников данных.
546 глава 12. ODBC. OLE DB, ADO и ASP Реляционные базы данных, Oracle, SQL Server, Access, DB2,. Нереляционные базы данных VSAM, ISAM, другие обработчики файлов Электронная почта, другие типы документов Картинки, аудиофайлы, прочее Рис. 12.2. Роль стандарта ODBC Реляционные базы данных, Oracle, SQL Server, Access, DB2... Нереляционные базы данных VSAM, ISAM другиа обработчики файлов Электронная почта, другие типы документов Картинки, аудиофайлы' прочее Рис. 12.3. Роль OLE DB
Информационное окружение веб-сервера 547 Так как OLE DB представляет собой объектно-ориентированный интерфейс, он особенно хорошо подходит для использования с объектно-ориентированны- ми языками программирования, такими как C++. Однако многие разработчи- ки приложений баз данных программируют на Visual Basic или на сценарных языках, таких как VBScript и JScnpt, Чтобы и им предоставить доступ к ODBC, компания Microsoft разработала ADO как оболочку для объектов OLE DB (рис. 12.4). ADO позволяет обращаться к функциональности OLE DB практиче- ски из любого языка. Рис. 12.4. Роль ADO Вам может ие поправиться навязчивое присутствие Microsoft в этом повест- вовании Но и OLE DB, и ADO были разработаны и продвинуты Microsoft, и даже ODBC завоевал лидирующие позиции во многом благодаря поддержке Microsoft. Другие производители и комитеты но стандартизации предлагали альтернативы 01 Е DB и ADO, по. поскольку система Microsoft Windows установлена на 904 настольных компьютеров но всем мире, другим организациям трудно продвигать
мв Г»— !£ 0“с’016 конкурирующие стандарты. Кроме гою, в защиту Mi< ruwft ****--утт| ’ OLE DB и ADO отлично выполняют свои функции Оми облегчи,) труд а ботчика бал данных, и, возможно, они одержали бы победу лалг « птд| м рентной борьбе. Однако наши цели имеют более земной характер И «учение ADO »♦>«/, w вам для того, чтобы вы могли создавать качественные приложения баз с использованием Интсрнст-технологий С этих позиций мы и будем i•< рассматривать каждый из этих стандартов Стандарт ODBC Стандарт ODBC — это интерфейс, с помощью которого прикладные лрог-ршемы могут обращаться к SQL-базам данных и обрабатывать их независимым от СУБД способом. Это означает, к примеру, что приложение, которое использует ин- терфейс ODBC, может обрабатывать базу данных Oracle, DB2, элем тройную таблицу и любую другую базу данных, совместимую с ODBC, без каких-либо из- менений в программном коде. Цель состоит в том, чтобы дать разраб-ггшу возможность создать одно приложение, способное обращаться к базам данных, поддерживаемым различными СУБД, без необходимости его менять или даже перекомпилировать. Стандарт ODBC был разработан комитетом производственных экспертов, сформированным из членов комитетов Х/Open и SQL Access Group. Было пред- ложено несколько стандартов, но победителем оказался ODBC, в основном пото- му, что он реализован Microsoft и является важной составной частью Windows. Изначально интерес Microsoft к поддержке этого стандарта был обусловлен же- ланием обеспечить в продуктах, подобных Excel, возможность обращения к раз- личным СУБД без перекомпиляции. Разумеется, с тех пор как стандарт OLE DB был внедрен, интересы Microsoft изменились (глава 13). Архитектура ODBC Диспетчер Драйве^^Х^вХГсУБД3”^^^ °DBC ПРикладная петчеры посылают заплот. Р иаходятСя на сервере приложений. Диа- базы данных. Согласно стямп1СТ°ЧНИКаМ данных> которые находятся на сервере ных, поддерживающая ее СУБUCmo4,lUK данных (data source) — это база дан- точник данных ODBC може б °перационная система и сетевая платформа Пе- ром, например BTrieve и nuL ЫТЬ реЛяционной базой данных, файловым серве- Приложение ин;™у^ХТР°НН0Й ТаблИЦСЙ’ ных, на выполнение SOL-on Ы На СОздание соединения с источником дай ошибок и на начало, фиксацией °Р°В ” полученне Результатов, на обработка Дартный способ для выполнены °Ткат тРаизакций. ODBC предоставляет стан- дартный набор кодов ошибок и сооб^0™ ”3 ЭТ“Х запросов 11 определяет стан-
Стандарт ODBC 549 Веб-сервер Серверы базы данных Приложение может обрабатывать базу данных с помощью любой из трех СУБД Рис. 12.5. Архитектура ODBC Диспетчер драйвера (driver manager) служит в качестве посредника между приложениями и драйверами СУБД. Когда приложение запрашивает соедине- ние, драйвер определяет тип СУБД, которая обрабатывает заданный источник данных ODBC, и загружает этот драйвер в память (если он еще ие загружен). Диспетчер драйвера также обрабатывает определенные запросы на инициализа- цию и проверяет допустимость формата и порядка запросов к ODBC, которые он получает от приложения. В Windows диспетчер драйвера входит в состав опе- рационной системы. Драйвер (driver) обрабатывает запросы к ODBC и передает конкретные SQL- операторы на выполнение заданному источнику данных. Для каждого типа источ- ника данных имеется свой драйвер. Например, есть драйверы для DB2, Oracle, Access и всех других продуктов, производители которых решили поддерживать стандарт ODBC. Драйверы поставляются производителями СУБД и независи- мыми компаниями. Драйвер отвечает за то, чтобы стандартные команды ODBC выполнялись корректно. В некоторых случаях, если сам источник данных не соответствует стандарту SQL, драйверу приходится выполнять значительную работу, чтобы восполнить недостаток функциональности источника данных. В других случаях, когда источник данных имеет полномасштабную поддержку SQL, драйвер толь- ко передает запрос на обработку источнику данных. Драйвер также преобра- зует коды ошибок источника данных и сообщения в стандартные коды и сооб- щения ODBC. ODBC определяет два типа драйверов: одноуровневые и многоуровневые. Одноуровневый драйвер (single tier driver) занимается как обработкой вызовов ODBC, так и выполнением SQL-операторов. Пример одноуровневого драйвера изображен на рис. 12.6, а. В этом примере данные хранятся в файлах Xbasc (это формат, используемый FoxPro, dBase и другими продуктами). Поскольку диспетче- ры файлов Xbasc не поддерживают SQL, преобразование SQL-занросз в коман- ды манипуляции файлами Xbase и обратное преобразование результатов в SQL возлагаются на драйвер.
Компьютер SQL б Рис. 12.6. Типы драйверов ODBC: а — одноуровневый драйвер; б — многоуровневый драйвер Многоуровневый драйвер (multi-tier driver) занимается только обработкой вы- зовов ODBC, а SQL-запросы передает на выполнение серверу базы данных. Он может переформатировать SQL-запрос, чтобы тот соответствовал диалекту кон- кретного источника данных, но выполнение запроса не входит в его функции. Пример использования многоуровневого драйвера показан на рис. 12.6, 6. Уровни соответствия дарпГлшпимТйТ*11 "СТаНДаРТа стояла дилемма. Если они зададут для стан- стоянпп многие пп'1 УР°веиь со™еСтпмостп, поддержать этот стандарт будут всо- ко малую допю Р°113Водптелп- Одндко при этом стандарт будет представлять толь- С другой сгопонп еЛ°ЩИ " выраз;1тельпост». которыми обладают ODBC и SQL. вместимости то пит ” Стандарт ^>'дет предписывать очень высокий уровень со- ли.Х™Х^ производители смогут поддерживать его, а это ODBC принял Mvnnoe п Ы СправнтьСя с Эт°и Дилеммой, комитет по разработке Уровни соответствия оп решение ~ определить уровни соответствия стандарту. И соответствия определяются по отношению к SQL и по отношению к ODBC. Уровень соответствия ODBC можпостп 11 фрподш w™(ODBC conformance level) описывает то, какие воз- драйвера. Интерфейс поик па ч™ Чере3 ИНтеРФейс прикладных программ (АРП торые может вызывать приложение л л°Г₽<ММ драйвеРа ~ это набор функций, юг В приведенной далее ввезкг л Для °^Ращеиия за услугами источника данных, репные в стаидХ ппэ.т ТрН УР°ВНЯ соответствия ODBC, предусмот; мере первый уровень соответП0ЧТП все Драйверы обеспечивают по крайней особого нитересГ С°°ТВСТСТВ1’Я- поэтому базовый уровень не представ Не ^5 % ч ЛЬ
Стандарт ODBC 551 УРОВНИ СООТВЕТСТВИЯ ODBC —-------------------------------------------------- Базовый уровень (Core API): ♦ соединение с источниками данных; ♦ подготовка и выполнение SQL-операторов; ♦ получение данных из набора результатов; ♦ сохранение или откат транзакций; ♦ получение информации об ошибках. Первый уровень (Level 1 API): ♦ соответствие ODBC на базовом уровне; ♦ соединение с источниками данных, содержащих информацию, специфичную для драйвера; ♦ отправка и прием частичных результатов; ♦ получение информации из каталога; ♦ получение информации о параметрах, возможностях и функциях драйвера. Второй уровень (Level 2 API): ♦ соответствие ODBC на базовом и первом уровнях; ♦ обзор возможных соединений и источников данных; ♦ получение «родной» формы SQL; ♦ вызов библиотеки преобразований; ♦ обработка двунаправленных курсоров. Приложение может вызвать драйвер, чтобы определить, какой уровень со- ответствия ODBC он предоставляет. Если приложение требует такого уровня соответствия, который не обеспечивается драйвером, оно может корректно пре- рвать сеанс и выдать пользователю соответствующее сообщение. Можно на- писать приложение так, чтобы оно использовало функции более высокого уровня соответствия, если они доступны, а если нет, реализовывало их само- стоятельно. Например, драйверы второго уровня должны предоставлять двунаправлен- ный курсор. Приложение можно запрограммировать так, чтобы оно использова- ло курсоры, если они доступны, а если нет, реализовывало бы отсутствующую функцию собственными средствами, используя предложения WHERE с сильными ограничениями. Это гарантирует, что за один прием приложению будет возвра- щаться лишь небольшое количество строк, которые будут обрабатываться с по- мощью курсора, поддерживаемого самим приложением. Во втором случае произ- водительность, скорее всего, будет ниже, зато, по крайней мере, приложение будет способно успешно выполнить задачу. Уровни соответствия SQL Уровни соответствия SQL (SQL conformance levels) описывают то, какие SQL- операюры, выражения и типы данных может обрабатывать драйвер. Как явствует из приведенной далее врезки, определены грн уровня соответствия. Возмож го- сти минимально! о сипТаксиса SQL весьма oi раничсны, и большинство др? воров поддерживают по крайней мере базовый синтаксис
552 Глава 12. ODBC. OLE DB, ADO и ASP УРОВНИ СООТВЕТСТВИЯ SQL --------------- Минимальный синтаксис (Minimum SOL Grammar): ♦ CREATE TABLE, DROP TABLE; ♦ простой оператор SELECT (без вложенных запросов); ♦ INSERT, UPDATE, DELETE; ♦ простые выражения (A > В + С); ♦ типы данных CHAR, VARCHAR, LONGCHAR. Базовый синтаксис (Core SOL Grammar): ♦ минимальный синтаксис; ♦ ALTER TABLE, CREATE INDEX, DROP INDEX; ♦ CREATE VIEW, DROP VIEW; ♦ GRANT, REVOKE; ♦ полный синтаксис оператора SELECT (включая вложенные запросы), ♦ встроенные функции: SUM, COUNT, MAX, MIN, AVG; ♦ типы данных DECIMAL, NUMERIC, SMALLINT, REAL, FLOAT. DOUBLE PRECISION Расширенный синтаксис (Extended SQL Grammar): ♦ базовый синтаксис; ♦ внешние соединения; + UPDATE и DELETE с использованием позиции курсора; ♦ скалярные функции: SUBSTRING, ABS; ♦ переменные для даты, времени и временная метка; ♦ пакетная обработка SQL-операторов; ♦ хранимые процедуры. Как и в случае с уровнями соответствия ODBC, приложение может вызвать драй- вер, чтобы определить, какой уровень соответствия SQL он поддерживает. Имея эту информацию, приложение может затем определить, какие SQL-операторы можно передавать на выполнение драйверу. Если необходимо, приложение может прервать сеанс или использовать альтернативные, менее мощные способы получения данных. Задание имени источника данных ODBC Источник данных — это структура данных ODBC, идентифицирующая базу дан- ных и СУБД, которая ее обрабатывает. Источники данных могут также иденти- фицировать другие типы данных — электронные таблицы, другие хранилища данных, не являющиеся базами данных, но нас они здесь не интересуют. Есть три типа источников данных: файловые, системные и пользовательские. Файловый источник данных (file data source) — это файл, который может совместно использоваться пользователями базы данных. Единственное требование состоит в том, чтобы пользователи имели один и тот же драйвер ODBC и одинаковый уровень доступа к базе данных. Файловый источник данных может распро страняться среди потенциальных пользователей посредством электронной по- чты или другими способами. Системный источник данных (system data source) это исючиик данных, являющийся локальным для отдельного компьютера. Сис темный источник данных может использовать операционная система и лкюо
Стандарт ODBC 553 пользователь этой системы (обладающий соответствующими полномочиями). Пользовательский источник данных (user data source) доступен только для того пользователя, который его создал. Вообще говоря, для веб-приложений наилучшим вариантом является созда- ние системного источника данных на веб-сервере. Пользователи обращаются к веб-серверу посредством браузеров, а веб-сервер через системный источник данных устанавливает соединение с СУБД и базой данных. UseDSN. Л Drivers | Treeing: Ccnnecbon | About | System Dele S duxes: |; д ' ч Name..,.3...^ Bach Mu$«c BOAT B0AT4 BDDK1 BUILDINGHISTORY BWLDIMGHISTORY2 ECDCMuse EXI EXAMPLE 1 Miciosof Mtciosof M'lCIOSOf Mtciojof Microserf Microserf Microscrf Hie to serf SGLS&f _ г Micrasdt Praetor. Orrm I'.db) Microsoft Patarfox Tteibet f db) Microsoft T es£ Driver (’txt; * csv) 6 Рис. 12.7. Создание системного источника данных: а — выбор драйвера Oracle: б - задание свойств источника данных
554 Глава 12. ODBC, OLE DB, ADO и ASP На рис 12 7 показан процесс создания сист мною источника данных с по- мощью Администратора источников данных ODBC (ODBC Data Source Administrator Service), который .можно найти на Панели управления (Control Pan< ) Windows. На рис' 12 7 о, пользователь выбирает драйвер для базы данных Oracle. Обратите внимание, что’есть два таких драйвера: один предоставлен Microsoft, а другой ~ Oracle. Эти драйверы могут иметь различные возможности, и пользователю сле- дует обратиться к документации па каждый из них, чтобы определить, какой из них лучше подходит для его приложения. На рисунке показаны также драйверы для Paradox, текстовых файлов и Visual FoxPro. На рис. 12.7, б, пользователь выбирает базу данных. В данном случае это VRG - база данных Oracle, созданная в главе 10. Источник данных для работы с этой базой назван ViewRidge0racle2. Мы будем использовать его далее в этой главе. Кроме того, мы будем использовать файловый источник данных под названием ViewRidgeSS для работы с базой данных SQL Server, созданной в главе И. $ OLE DB OLE DB — это то, на чем основывается доступ к данным в мире M'crosoft. В связи с этим важно понять фундаментальные идеи OLE DB, даже если вы будете рабо- тать только с ADO-интерфейсами, занимающими более высокий уровень. В этом разделе мы изложим основные принципы работы OLE DB. OLE DB является реализацией разработанного Microsoft объектного стандар- та OLE. OLE-объекты являются COM-объектами и поддерживают все требуемые для таких объектов интерфейсы. В сущности, OLE DB разбивает всю совокуп- ность возможностей и функций СУБД на отдельные фрагменты — СОМ-объек- ты с узкой специализацией. Одни объекты выполняют запросы, другие произво- дят обновления, третьи создают структурные элементы базы данных — таблицы, индексы и представления, четвертые занимаются управлением транзакциями — например, устанавливают оптимистическую блокировку. Это свойство OLE DB позволяет преодолеть крупный недостаток ODBC. Чтобы продукт мог считаться соответствующим стандарту ODBC, производи- тель должен создать драйвер почти для всех функций СУБД. Это сложная задача, требующая значительных начальных вложений. Используя же OLE DB, произ- водитель СУБД может реализовывать их функции в продукте частями. Можн >, к примеру, реализовать только обработчик запросов, создать для него интерфейс OLE DB, и в результате продукт будет доступен клиентам, использующим ADO. Позже производитель может добавить другие объекты и интерфейсы OLE DB, расширяющие функциональность продукта. Поскольку данная книга не подразумевает знакомства читателей с объектно- ориентированным программированием, то, прежде чем двигаться дальше, нам следует определить некоторые понятия. В частности, это понятия абстракции, метода, свойства и коллекции. Абстракция (abstraction) — это обобщение чего- Л11бо. Интерфейсы ODBC являются обобщениями «родных» методов доступа к УБД. Когда мы создаем абстракцию, мы теряем детали, но получаем возмож иость работать с более широким диапазоном типов. 3SI&1
OLE DB 555 Например, набор записей (recordset) является абстракцией отношения. В дан- ной абстракции набор записей определен как объект, имеющий ряд характе- ристик, которые присущи всем отношениям. Например, каждый набор записей содержит множество столбцов, которые в абстракции называются полями. На- значение абстракции состоит в том, чтобы передать все существенные черты и отбросить детали, не представляющие важности для тех, кто пользуется этой абстракцией. Так, отношения в Oracle могут иметь некоторое свойство, которым не обладает набор записей, то же самое может быть справедливо и для отноше- ний в SQL Seivei, AS/400, DB2 и других СУБД. Эти уникальные характеристи- ки будут потеряны в абстракции, но, если абстракция является удачной, никто не будет возражать. Теперь переместимся на один уровень вверх. Набор строк (rowset) является в OLE DB абстракцией набора записей. Зачем же понадобилось в OLE DB опре- делять еще одну абстракцию? Дело в том, что OLE DB обращается к источникам данных, которые не являются таблицами, но имеют некоторые из характеристик, присущих таблицам. Рассмотрим совокупность всех адресов электронной почты, содержащихся в вашей адресной книге. Можно ли назвать эту совокупность отношением? Нет, но у нее есть определенные характеристики, свойственные отношениям. Каждый адрес электронной почты представляет собой группу се- мантически взаимосвязанных элементов данных. Подобно строкам таблицы, они упорядочены: есть первый адрес, второй, третий и так далее. Но, в отличие от строк отношения, они не принадлежат к одному и тому же типу. Некоторые из них являются адресами людей, а некоторые — списками рассылки. Таким обра- зом, на наборе строк нельзя выполнить ни одного действия с набором записей, требующего, чтобы все элементы набора имели одинаковый тип. Двигаясь от общего к частному, OLE DB определяет набор свойств и признаков набора строк. Более того, OLE DB определяет набор записей как подтип набора строк. Наборы записей обладают всеми свойствами и признаками, свойственны- ми наборам строк, плюс еще некоторыми характеристиками, которые являются уникальными для наборов записей. Абстракции распространены и весьма полезны. Вы можете услышать об абст- ракциях управления транзакциями, абстракциях запросов, абстракциях интер- фейсов. Это просто означает, что некоторые характеристики набора вещей опре- делены формально как тип. Объект в объектно-ориентированном программировании — это абстракция, определяемая своими свойствами и методами. Например, объект, представляю- щий набор строк, имеет свойство Al lowEdit, свойство RecordsetType и свойство EOF. Эти свойства (properties) представляют характеристики абстракции набора за- писей. Объект характеризуется также действиями, которые он способен выпол- нять. Эти действия называются методами (methods). Наоор записей имеет такие методы, как Open, MoveFirst, MoveNext и Close. Строго говоря, определение абстракции объекта называется объектным клас- сом (object class) или просто классом. Объектом же называется экземпляр объ- ектною класса — например, конкретный набор записей. Все объекты одного класса имеют одни и те же методы и свойства, по значения этих свойств различ- ны у разных объектов.
556 Глава 12. ODBC, OLE DB, ADO и ASP Остался последний термин, которому предстои. дать опреда м*яме • иымио коллекция. Коллекция (collection) - »то объект, содержащий группу другим объ- ектов. К примеру, набор записей содержит i руину объектов, назы магмы» пллям* (fields). Коллекция имеет свойства и менты Одно из свойств всех доллемиЯ называется Count. Это свойство описывает количеств» объ-кгов в коллекции Так’ recordset.Fields.Count представляй количество нолей в коллекции В ADO и OLE DB имена коллекций образуются как форма множественного числа от имен объектов, в них содержащихся. Например, имеется коллекция Fields состоя- щая из объектов Field, коллекция Errors, состоящая из объектов Error, коллекция Parameters, состоящая из объектов Parameter, и т. д. Важным методом коллекций является метод iterator, который осуществляет перебор элементов коллекции или идентифицирует их каким-либо иным образом. Если вас испугали определения, не отчаивайтесь. Практическое исполь v кл иие этих понятий вы увидите в конце этой главы. Цели создания OLE DB Основные цели, преследовавшиеся при создании OLE DB, перечислены во врез- ке. Во-первых, как уже говорилось, OLE DB разбивает функциональность СУБД на объектные кусочки. Это разделение обеспечивает большую гибкость как для потребителей данных (data consumers) — пользователей функциональности OLE DB, так и для поставщиков данных (data providers) — производителей про- дуктов, которые предоставляют доступ к функциональности OLE DB. Потреби- тели данных имеют дело только с теми объектами и функциями, которые им нуж- ны, поэтому мобильное устройство для чтения базы данных может иметь малые габариты. В отличие от случая с ODBC, поставщикам данных требуется реализовать только некоторый фрагмент функциональности СУБД. Это разделе- ние означает также, что поставщики данных могут предоставлять доступ к воз- можностям и функциям СУБД через множество различных интерфейсов. ЦЕЛИ СОЗДАНИЯ OLE DB ------------------------------------------------------- 1. Создание объектных интерфейсов для элементов функциональности СУБД — запрос обновление, управление транзакциями. 2. Увеличение гибкости: ♦ дать потребителям данных возможность использовать только те объекты, которые им нужны; ♦ дать поставщикам данных возможность открывать доступ к элементам функциональ- ности СУБД; ♦ обеспечить возможность доступа к функциональности с помощью множества раз- личных интерфейсов; ♦ сделать эти интерфейсы стандартизированными и расширяемыми. 3 Создание объектных интерфейсов для любых типов данных: реляционных баз данных (через ODBC или собственные интерфейсы СУБД), нереляционных баз данных, систем обработки файлов (VSAM и др ), электронной почты и многого другого. 4. Реализация такой стратегии, при которой данные не должны преобразовываться в дру- гие Форматы или перемещаться из того места, где они находятся.
OLE DB 557 Последнее утверждение требует пояснений. Объектный интерфейс представ- ляет собой как бы упакованный набор объектов. Интерфейс (interface) — это на- бор объектов плюс свойства и методы, доступ к которым они предоставляют. Объект не обязан открывать в интерфейсе все свои свойства и методы. Так, в ин- терфейсе запроса набор записей будет поддерживать только чтение, а в интер- фейсе обновления — создание, обновление и удаление. То, как объект поддерживает интерфейс, называется реализацией (implemen- tation) штерфейса. Реализация полностью скрыта от пользователя. Фактически разработчики объекта вольны менять ее, когда захотят. Однако если им вздума- ется изменить интерфейс, то заслуженное презрение со стороны пользователе^ будет им обеспечено! OLE DB определяет стандартизированные интерфейсы. Однако поставщики данных свободны в том, чтобы добавлять интерфейсы в дополнение к базовым стандартам. Такая расширяемость имеет первостепенное значение для достиже- ния следующей цели — предоставить объектный интерфейс для любых типов данных. Реляционные базы данных могут обрабатываться с помощью объектов OLE DB, использующих ODBC или собственные драйверы СУБД. В OLE DB предусмотрена поддержка и других типов данных, как указано выше. Побочным следствием этих целевых установок является то, что данные не нуж- но ни преобразовывать из одного формата в другой, ни перемещать из одного ис- точника данных в другой. Веб-сервер на рис. 12.1 может использовать OLE DB для обработки данных в любом из форматов прямо в том месте, где эти данные находятся. Это означает, что транзакции могут затрагивать множество источников данных и быть распределенными по различным компьютерам. Для этого в OLE DB предусмотрено средство под названием MTS (Microsoft Transaction Server, сер- вер транзакций Microsoft), но его обсуждение выходит за рамки данной книги. Основные конструкции OLE DB Как явствует из приведенной ниже врезки, в OLE DB имеются два типа постав- щиков услуг. Поставщики табличных данных (table data providers) представляют свои данные через наборы строк. Примерами являются СУБД, электронные таб- лицы и обработчики файлов ISAM, подобные dBase и FoxPro. Кроме того, в виде наборов строк могут быть представлены и другие типы данных, например сооб- щения электронной почты. Поставщики табличных данных привносят в мир OLE DB данные определенного типа. ТИПЫ ПОСТАВЩИКОВ ДАННЫХ OLE DB------------------------------- Поставщик табличных данных: ♦ предоставляет доступ к данным через наборы строк; ♦ примеры: СУБД, электронные таблицы, системы ISAM, электронная почта. Поставщик услуг: » не имеет своих данных; ♦ преобразует данные с помощью интерфейсов OLE DB, • является одновременно и потребителем, и поставщиком данных; ♦ примеры, обработчик запросов, генератор XML-документов.
558 Глава 12 ODBC. OLE DB, ADO и ASP Поставщик уст/г (service provider) минмается п|к-иЛрелаваняем дяяимх По- ставщики услуг принимают данные О1 Е DB от поставщика табличных АММП и некоторым образом их преобразуют Поставщики услуг являются и лямн данных (исходных), и поставщиками данных (преобразованных) В качест- ве примера поставщика услуг можно принести службу, которая получает данные от реляционной СУБД и преобразует их в XML-локумвиты Объект, называемый набором строк (rowset), играет фундаментальную роль в OLE DB: набор строк эквивалентен тому, что мы называли курсором в главе 9 и эти два термина фактически синонимичны Во врезке «Интерфейсы б и строк» перечислены основные интерфейсы, поддерживаемые набором строк. Ия терфейс IRowSet предоставляет методы для последовательного передвижения по набору строк только в прямом направлении. Когда вы объявляете последователь- ный курсор в OLE DB, вы вызываете интерфейс IRowSet Интерфейс lAccessor используется для связывания программных переменных с полями набора строк. При использовании ADO этот интерфейс в значительной степени скрыт, потому что он используется сценарным ядром в его работе. Но, если вы работаете с биб- лиотеками типов в VB, вы можете использовать методы этого интерфейса. ИНТЕРФЕЙСЫ НАБОРА СТРОК--------------------------------------------------------- ♦ IRowSet- методы для последовательного перебора строк. ♦ lAccessor: методы для установления связей между набором строк и переменными программы- клиента ♦ IColumnsInfo. методы для получения информации о столбцах набора строк. » Прочие интерфейсы: двунаправленные курсоры; создание, обновление и удаление строк, прямой доступ к конкретным строкам (закладки); явные блокировки; и так далее.. Интерфейс IColumnsInfo имеет методы для получения информации о столбцах набора строк. Мы будем использовать этот интерфейс в двух примерах примене- ния ADO в конце этой главы. IRowSet, lAccessor и IColumnsInfo являются базовы- ми интерфейсами набора строк. Другие интерфейсы предназначены для более сложных операций — манипуляций с двунаправленными курсорами, обновления, прямого доступа к конкретным строкам, явных блокировок и многого другого. Рассмотрим эти интерфейсы в контексте двух наборов строк — один из них взят из обычного отношения, а другом содержит коллекцию адресов электрон- ной почты. Первые три интерфейса могут быть непосредственно использован с обоими наборами строк. Функции и возможности последних трех интерфей- сов, скорее всего, будут различаться для этих двух наборов, а некоторые из них могут быть вообще не определены для какого-то из наборов. Последнее замена-
ADO 559 иие: наборы строк могут содержать указатели на объекты, так что с их помощью можно создавать весьма сложные структуры. ADO ADO (Active Data Objects) это простая объектная модель, которую могут ис- пользовать потребители данных для обработки любых данных OLE DB. К пен можно обращаться из сценарных языков, таких как J Script и VBScript, а также из Visual Basic, Java, C# и C++. Благодаря абстракциям OLE DB и объектной структуре, объектная модель ADO и ее интерфейсы остаются одними и темп же независимо от типа обраба- тываемых данных. Таким образом, разработчик, изучающий ADO применитель- но к обработке реляционных баз данных, сможет использовать эти знания и для обработки папки с сообщениями электронной почты. Характеристики ADO пере- числены во врезке. ХАРАКТЕРИСТИКИ ADO ----------------------------------------------------- ♦ Простая объектная модель для потребителей данных OLE DB. ♦ Может использоваться из VBScript, JScript, Visual Basic, Java, C#, C++. ♦ Единый стандарт Microsoft для доступа к данным. ♦ Объекты доступа к данным остаются одними и теми же для всех типов данных OLE DB. Вызов ADO из ASP-страниц В этой главе мы будем вызывать ADO па веб-сервере, используя ASP-страницы. Такие страницы содержат смесь DHTML (или XML) и программных конструк- ций на языках VBScript или JavaScript. В этой главе мы будем использовать VBScript. ASP-страницы можно писать в любом текстовом редакторе, но легче их писать в редакторе FrontPage и подобных ему продуктах для создания веб- страниц. IIS (Internet Information Server, информационный сервер Интернет) — это веб-сервер, встроенный в операционные системы Windows 2000 Professional и Windows ХР Professional. ASP является ISAPI-расширенпем IIS. С практиче- ской точки зрения это означает, что всякий раз, когда I1S получает файл с рас- ширением .asp, он посылает этот файл программе ASP для обработки. Все опера горы языков программирования, заключенные между символами <%...%>, будут обрабатываться па компьютере веб-сервера. Остальные операто- ры будут переданы па выполнение браузеру пользователя. Весь код, который мы будем писать в этой главе, будет обрабатываться на веб-сервере. Для вызова ASP-ci раниц поместите их в какой-цибуль каталог, например C:\MyDirectory Затем откройте I1S и создайте виртуальный каталог, указываю- щий на гот катало!, в который вы поместили наши ASP-страницы. Это можно сделать, щелкнув правой кнопкой мыши на значке Default Web Site (Сайт по умол- чанию) в окн” Internet Information Server. Выберите команду New ► Virtual Directory
560 Глава 12. ODBC. OLE DB, ADO и ASP (Создать ► Виртуальный катален). в резулынте чего запустите» мастер предложит вам дать имя виртуальному каталогу и указать его реальное место** ложение (здесь C:\MyDirectory). На третьей панели мастера выберите Read (Чте- ние) и Run Scripts (Выполни।ь сценарии). Для примеров в этой главе мы будем использовать виртуальную панку с именем ViewRidgeExamplel Нет необходимости в том, чтобы СУБД и веб сервер находились на одной и ТОЙ же машине. Когда вы задаете имя источника данных ODBC, вы можете выбрать базу данных, которая находится на другом компьютере и доступна с » шьвмм веб-сервера. Это будет проще, если другой компьютер работает под у।ipaa.icmacft Windows, но можно сделать это и для дру! их операционных систем Кроме то- го. ничто, разумеется, не запрещает веб-серверу и СУБД находиться на о । машине. Объектная модель ADO Объектная модель ADO, показанная на рис. 12.8, является надстройкой к объект- ной модели OLE DB. Объект Connection, представляющий соединение с источни- ком данных, — это первый объект ADO, который необходимо создать и который является основой для всех остальных. Имея соединение, разработчик может создать один или несколько наборов записей (объект RecordSet) и одну или не- сколько команд (объект Command). Все ошибки, которые генерируются в процессе создания любого из этих объектов и работы с ним, ADO будет помещать в специ- альную коллекцию Errors. Рис. 12.8. Объектная модель ADO Каждый объект RecordSet имеет коллекцию полей (Fields); каждое поле (объ- ект Field) в этой коллекции соответствует столбцу в наборе записей. Кроме того, каждая команда имеет коллекцию параметров (Parameters), элементы которой представляют переданные команде параметры.
ADO 561 Объект Connection Следующие операторы VBScript запущенные из веб-страницы, создают объ- ект-соединение Connection. После их выполнения переменная objConn будет указывать на объект, связанный с источником данных ODBC под названием ViewRidgeSS: <1 Di objConn Set objConn = Server.CreateObject ("ADDDB.Connect!on") objConn.Isol atlonLevel = adXactReadCommitted ' используем ADOVBS objConn.Dpen "ViewRidgeSS" В этом фрагменте кода оператор Ser ver. CreateObject вызывает метод CreateObject ASP-объекта Server. Тип объекта — здесь ADODB.Connect!on — передается в качест- ве параметра. После выполнения этого оператора переменная objConn указывает на новый объект Connection. Далее для этого соединения устанавливается уро- вень изоляции с помощью константы из файла ADOVBS. Данный файл можно сде- лать доступным для сценария с помощью следующего оператора: <!-#include virtual = "ViewRidgeExaniplel/AOOVBS.inc->" Этот оператор должен быть в ASP-файле, но вне скобок <%...%>. Чтобы он сработал, вы должны скопировать файл ADOVBS.inc в свой каталог (найди- те файл с помощью команды Search (Найти) в главном меню Windows). Так- же следует поменять имя виртуальной папки, если оно у вас отличается от ViewRidgeExamplel. Имена и значения важных констант ADOVBS перечислены в табл. 12.1-12.3. Использование имен констант вместо их значений делает ваш код более удобо- читаемым. Это также облегчает адаптацию кода, если Microsoft вдруг изменит смысл этих значений (что маловероятно, по все-таки возможно). Таблица 12.1. Константы уровней изоляции в ADO Уровень изоляции Имя константы Значение «Г чтение adXactReadUncommitted 256 Завершенное чтение adXactReadCommitted 4096 Воспроизводимое чтение adXactRepeatableRead 65536 Сериализуемость adXactSeriBiizable 1048576 Таблица 12 2 Константы типов курсоров в ADO Тип курсора Имя константы Значение Последовательный adOpenForwardOnly 0 клклнн» .и adOpenKoyset 1 Динамический adOpenDynainic 2 Статический adOpenStetic 3
562 Глава 12. ODBC, OLE DB, ADO и ASP Таблица 12.3. Константы типов блокировок в ADO Тип блокировки Имя константы Значение Только чтение adLockReadOnly 1 Пессимистическая блокировка adLockPessimistic 2 Оптимистическая блокировка adLockOptimistlc 3 Оптимистическая блокировка с массовыми обновлениями adBatchOptimistic 4 Последний оператор открывает источник данных ODBC, вызывая метод Орел объекта Connection. Имя источника данных передается ему в качестве параметра. В данном случае СУБД не передается ни имя пользователя, ни пароль. Вместо этого используется идентификация средствами операционной системы По умол- чанию ASP будет использовать имя вида IUSR ИмяМашины; в данном случае это будет IUSR_DBGRV1O1. Этой учетной записи в SQL Server должны быть даны полномочия па чтение и обновление таблиц базы данных VRG. Итак, мы установили соединение с СУБД через источник данных ODBC, и база данных открыта. С помощью указателя objConn можно обращаться ко всем осталь- ным методам объекта Connection (см. рис. 12.7), включая методы создания и исполь- зования объектов RecordSet и Command. Кроме того, через этот указатель можно работать с коллекцией Errors. Объект RecordSet Имея соединение с открытой базой данных, создадим объект RecordSet (здесь и далее символы <% и °/о> будут опускаться, но все приведенные ниже примеры должны помещаться между ними, иначе код не будет выполняться на веб-сервере): Dim objRecord. varSql varSQL = "SELECT * FROM ARTIST" Set objRecordSet = Server.CreateObject ("ADODB.RecordSet") objRecordSet.CursorType = adOpenStatic objRecordSet.LockType = adLockReadDnly objRecordSet.Open varSql. objConn Тип курсора (свойство Cursor Type) и тип блокировки (свойство LockType) мо- гут также передаваться в качестве параметров методу open, как показано здесь: Dim objRecord. varSql varSOL = "SELECT * FROM ARTIST" Set objRecordSet = Server.CreateObject ("ADODB.RecordSet") objRecordSet.Open varSql, objConn. adOpenStatic. adLockReadDnly Так или иначе, эти операторы приводят к выполнению SQL-оператора, запи- санного в переменной varSql, с использованием курсора, являющегося статиче- ским и предназначенного только для чтения. Все столбцы таблицы ARTIST будут вредетавлены полями в наборе записей. Если бы в операторе SELECT были указа- ны только два столбца, например SELECT ArtistID. Nationality FROM ARTIST только огда эти два столбца были бы включены в качестве полей в набор записей
ADO 563 Между прочим, в SQL Server, если имя таблицы имеет пробелы или другие необычные символы либо является зарезервированным словом SQL, оно заклю- чается в квадратные скобки. Однако Oracle не воспринимает имена таблиц в квад- ратных скобках вместо этого нестандартные имена следует заключать в кавыч- ки. Таким образом, если в вашей базе данных есть такие таблицы, вам придется писать различный код в зависимости от того, чью базу данных вы используете - Oracle или SQL Server. Коллекция Fields При создании набора записей создается экземпляр коллекции Fields. Работать с этой коллекцией позволяет следующий код: Dim varl. varNumCols. objField varNumCols = objRecordSet.Fields.Count For varl = 0 to varNumCols - 1 Set objField = objRecordSet Fields(varl) ' теперь objField.Name содержит имя поля. ' a objField.Value содержит его значение ' здесь можно выполнять с ними некоторые действия Next Во втором операторе в переменную varNumCol s записывается количество столб- цов в наборе записей, для чего считывается значение свойства Count коллекции Fields. Затем идет цикл, в котором перебираются элементы коллекции. Свойство Fields(O) указывает на первый столбец набора строк, поэтому переменная цикла пробегает значения от 0 до Count -1. С самими объектами-полями в этом примере никаких действий не произво- дится. В реальном приложении имя поля можно определить с помощью свойства objField.Name, а значение поля — с помощью свойства objField.Value. В следую- щих примерах вы увидите, как это делается. Коллекция Errors Всякий раз, когда происходит ошибка, ADO создает экземпляр коллекции Errors. Это должна быть именно коллекция, поскольку один оператор ADO может вы- звать несколько ошибок. Эту коллекцию можно обрабатывать тем же способом, что и коллекции Fields: Dim varl. varErrorCount. objError On Error Resume Next varErrorCount - objConn.Errors.Count If varErrorCount > 0 Then For varl - 0 to varNumCols 1 Set ObjError - objConn.Errors(varl) ‘ теперь objError Description содержит ' описание ошибки Next End If
564 Глава 12 ODBC, OLE DB, ADO и ASP В цикле объектному указателю objError присваиваются значения objConn Errors(varl). Обратите внимание, что эта коллекция принадлежит соединению (objConn), а не набору записей (objRecordSet). Свойство Description объекта Error можно использовать для возвращения пользователю сообщения об ошибке К сожалению, VBScript имеет очень ограниченные возможности для обработ- ки ошибок. Код проверки ошибок (начинающийся с On Error Resume Next) необхо- димо помещать после каждого оператора ADO, который может вы шать ошиб Так как это может вызвать нежелательное увеличение объема кода, лучше было бы написать функцию обработки ошибок и вызывать ее после каждого вызова объекта ADO. Объект Command ADO-объект Command используется для запуска запросов и хранимых процедур, находящихся в базе данных. Коллекция Parameters объекта Command предназначена для передачи параметров. Предположим, например, что в базе данных, соедине- ние с которой мы установили в objConn, имеется хранимая процедура FindArtist, принимающая один параметр — национальность художников, данные о которых нужно предоставить. Следующий код вызывает эту процедуру с параметром «Spanish» и создает набор записей objRs, в который помещаются результаты ее выполнения: Dim objCommand. objParam. objRs Создаем объект Command, соединяем его с objConn и задаем его формат Set objCommand = Server.CreateObject("ADODB.command") Set objCommand.ActiveConnection = objConn ObjCommand.CommandText = "{call FindArtist (?)}" задаем значение параметра Set objParam = objCommand.CreateParameter ("Nationality". adChar, adParamlnput. 25) objCommand.parameters.Apend objParam objParam.value = "Spanish" запускаем хранимую процедуру Set objRs = objCommand.Execute В этом примере сначала создается объект типа ADODB.command, затем для него указывается активное соединение — objConn. Далее в свойстве CommandText задает- ся формат вызова хранимой процедуры. Это свойство используется для указа- ния имени хранимой процедуры и количества ее параметров. Параметр обозна- чается знаком вопроса. Если бы было три параметра, текст команды был бы таким: {call FindArtist (?. ?, ?)}. Далее создается объект Parameter. Константы adChar и adParamlnput взяты из файла ADOVBS и указывают на то, что параметр имеет тип char и что он является для процедуры входным. Максимальная длина параметра установлена равной 25 символам. Создав параметр, его необходимо присоединить к команде, для чего служит метод Append. Наконец, с помощью метода Execute происходит вызов хра- нимой процедуры. Итак, мы создали набор записей objRs, содержащий результаты выполнения хранимой процедуры.
Примеры использования ADO 565 Примеры использования ADO Следующие пять примеров показывают, как вызывать ADO из VBScript с по- мощью ASP. Упор в них делается на использование ADO, а не на графическое представление, внешний вид или последовательность действий. Если вы хотите, чтобы ваше приложение выглядело и вело себя лучше, вы должны уметь соответ ствующим образом модифицировать эти примеры. Сейчас вам следует просто на- учиться использовать ADO. Все эти примеры работают с базой данных View Ridge. В некоторых из них мы соединяемся с источником данных ViewRidgeSS — базой данных SQL Server, в других используем ViewRidgeOracle — базу данных Oracle. В последнем примере требуется изменить всего одни оператор, чтобы переключиться с SQL Server па Oracle! Это удивительно, и это как раз то, на что надеялись разработчики специ- фикации ODBC. Состояние транзакции поддерживается ASP-процсссором. Для каждой транз- акции он хранит набор сеансовых переменных. В этих примерах мы будем ис- пользовать сеансовые переменные для сохранения соединений. Оператор Set SessionC'abc') = "Wowzers" создает сеансовую переменную с именем "abc" и присваивает ей строковое зна- чение «Wowzers». Более полезные примеры последуют далее. Чтобы запустить любую из этих ASP-страниц, откройте браузер и введите следующий URL, если страница находится на том же компьютере, где запущен сервер IIS: http://local host/ADOExamples/MMHjparina. asp Здесь имя_файла — это имя ASP-страницы. Если вы запускаете ASP-странпцу не с того компьютера, где работает IIS, а с какого-то другого, вместо localhost следует ввести адрес вашего сервера. Пример 1 — чтение конкретной таблицы В листинге 12.1 приведен текст ASP-страницы, отображающей содержимое таб- лицы ARTIST. Листинг 12.1. Artist.asp <HTML> <HEAD> <МЕТА HTTP EQUIV="Content-Type" CONTENT="text/html:charset=windows-1252"> <TITLE>ArtiSt</TITLE> </HEAD> <1nclude virtua1=”VIewRi dgeExamplel/adovbs.i nc "-> <BODY> Dim objConn, objRecordSet. varSql продшжеиие^
566 Глииа 12. ODBC, OLE DB. ADO и ASP Листинг 12.1 (продолжении) If lsObject(Sess1on('H_conn )) Thon 'если соединение уже установлено, и пользуем его Set objConn - Session!\conn") Else 1 устанавливаем соединение Set objConn - Server.CreateObject!"ADODB connection") ' открываем базу данных VRG с системной идентификацией objConn,open "ViewRidgeSS ' избегаем "грязного" чтения objConn. Isolat1 onLevel - adXactReadCommitted Set Session("_conn") - objConn End If 'создаем объект recordset Set objRecordSet-Server,CreateObject("ADDDB.Recordset") 'текст SQL-оператора varSql - "SELECT ArtistName. Nationality FROM ARTIST" 'курсор статический, обновление не требуется objRecordSet.Open varSql, objConn, adOpenStatic. adLockReadOnly <TABLL BORDER- 1 BGCOLOR-#ffffff CELLSPACING-5> <FONT ГАСЕ-"Arial" COLOR-#OOQOOO> <CAPTION><B>ARTIST</B></CAPTION> </FDNT> <THEAD> <1R> <TH BGCOLOR-#cOcOcO BORDERCOLOR-#OCOOOO> ''FONT SIZE-2 FACE-"Arial" COLOR-#OOOODO>Name</FONT> </TH> <TH BGCOLOR-#cOcOcO BORDERCOLOR-#OOOOCO > <FONT SIZE-2 FACE-"Anal" COLOR-#WOOOOO>Nat1onality</FONT> </TH> </TR> </THEAD> <TBOOY> <% On Error Resume Next ObjRecordSet,MoveFIrst do while Not objRecordSet.eof <TR VALIGN-TOP> <T0 BOROERCOLOR-#cOcOcO > <FONT SIZE-2 FACE-"Ar1al" COLOR-#OCOOOO> ^-Server. HTMLEncode(objRecordSet( "ArtistName" ))^><BR> </FONT> </TD>
__________________________________Примеры использования ADO 567 <TD BORDERCOLOR=#cOcOcO> <FONT SIZE=2 FACE="Arial" CC)LOR=#000000> <£=Server.HTMLEncode(obj RecordSet("Nationality"))£><BR> </FONT> </TD> </TR> objRecordSet.MoveNext loop$> </TBDDY> <TFOOTx/TFOOT> </TABLE> </BODY> </HTML> Начинается страница co стандартных конструкций HTML. Первый раздел серверного кода создает объект Connection, а затем объект RecordSet, содержащий результаты выполнения следующего SQL-оператора: SELECT Name. Nationality FROM ARTIST Поскольку соединения используют большое количество ресурсов, как в смыс- ле времени, требуемого на их создание, так и в смысле количества потребляемой ими памяти, объект Connection в этом примере сохраняется в сеансовой перемен- ной conn. В первый раз, когда пользователь вызовет ASP-странпцу. соедине- ние еще не будет существовать. В этом случае результатом вызова функции IsObject(”_conn") будет значение fal se, так как переменная _сопп еще не указы- вает ни на какой объект. Код, следующий за оператором Else, создает объект Connection. Далее создается объект RecordSet для оператора SELECT в перемен- ной varSql. Следующий раздел ASP-страницы содержит HTML-код, предназначенный для браузера. За ним следует несколько фрагментов серверного сценарного кода, перемешанного с HTML. Оператор On Error Resume Next отменяет обработку ошибок сценарным ядром ASP, предписывая продолжать выполнение сценария. Хоро- шая ASP-страница в этом случае обеспечила бы обработку ошибок. Пос хедняя часть страницы просто создает HTML-код п вставляет в него по- лученные значения. Цикл objRecordSet.MoveFirst.. .MoveNext представляет стан- дартную логику последовательной обработки файла. Результат выполнения этой ASP-странпцы показан па рис. 12.9. В этой стра- нице и в породившем ее ASP-файле пет ничего впечатляющего, за исключением следующего обстоятельства: если бы эта страница находилась в Интернете, ес Могли бы видеть более 250 миллионов человек во всем мире! При этом им не понадобилось бы никакою программного обеспечения, кроме того, что уже уста новлеио на их компьютерах.
568 Глава 12 ODBC, OLE DB. ADO и ASP Рис. 12.9. Результат выполнения ASP-страницы Artist.asp Пример 2 — чтение таблицы обобщенным способом В первом примере объекты, составляющие объектную модель ADO, использова- лись по минимуму. Мы можем расширить этот пример за счет использования коллекции Fields. Предположим, мы хотим задавать имя таблицы в качестве параметра, а на выходе получать содержимое всех столбцов этой таблицы, за исключением суррогатного ключа. ASP страница в листинге 12.2 выполнит эту задачу с той оговоркой, что имя лицы удет задаваться в переменной varTabl eName. В следующем примере бу- fl т показано, как организовать ввод имени таблицы через HTML-форму. Листинг 12.2. CustomerOracle.asp <HTML> <HEAD> <Т1Т1Е>ТаЬ1е0п^щ'СОПоеП1'ТуРе'' CONTENT-'text/html:charset=w1ndows-1252"> <uiLE>Fable Display Page</TITLE> </HEAD> <BODY> <!-#include vi rtua1="ViewRi dgeExamplei/adovbs.inc Dim objConn. objRecordSet, objField
Примеры использования ADO 569 И. 33 да®1 Dim varNumCols, varl. varSql Dim varTableName. varKeyName varTablename = "CUSTOMER" varKeyName = "CUSTOMERID" If IsObject(Session("_conn")) Then ' если соединение уже установлено, используем его Set objConn = Sess1on("_conn“) Else ’ устанавливаем соединение Set objConn = Server.CreateObject!"ADODB.connection") 'открываем ODBC-файл Oracle из-под учетной записи DK1 с паролем objConn.open "ViewRidgeOracle". "system", "manager" ' избегаем "грязного" чтения objConn.I solationLevel = adXactReadCommitted Set Session!”_conn" = objConn End If Set objRecordSet = Server.CreateObject!"ADODB.Recordset") varSQL = "SELECT * FROM " & varTableName ' тип курсора и тип блокировки не поддерживаются драйвером Oracle objRecordSet.Open varSql. objConn X> «TABLE BORDER=1 BGCOLOR=#ffffff CELLSPACING=5> «FONT FACE="Arial" COLOR = #000000> <CAPTION><B><$varTableName^> (in Oracle database) </B></CAPTION> </FONT> <THEAD> <TR> <% varNumCols = objRecordSet.Fields.Count For varl = 0 to varNumCols - 1 Set objField = objRecordSet.Fields(varl) If ObjField.Name <> varKeyName Then ' опускаем суррогатный ключ X> «TH BGCOLOR=#cOcOcO BORDERCOLOR=#000000 > «FONT SIZE=2 FACE="Arial" COLOR=#OODOO> «^“ObjField. Name %> </FONT> </TH> <% End If Hext %> «/TO </THEAD> <TBODY> продолжение,^
570 Глава 12. ODBC, OLE DB, ADO и ASP Листинг 12.2 (продолжение) On Error Resume Next objRecordSet MoveFirsC do while Not objRecordSet.eof <TR VALIGN=TOP> <% varNumCols = objRecordSet.Fields.Count For varl = 0 to varNurnCols - 1 Set objField = objRecordSet .Fiel ds(varl) If objField.Name <> varKeyName Then ' опускаем суррогатный ключ Я> <TD BORDECOLOR=#cOcOcO > <FONT SIZE = 2 FACE="AriaT' COLOR=#OOGOOO> <2=Server.HTMLEncode (objField.Value 1X><BR> </FONT> </TD> <% End If Next </TR> <% objRecordSet.MoveNext 1oop £> </TBODY> <TFOOT></TFOOT> </TABLE> </BODY> </HTML> в листинге ‘1СТЬ СС^1!СР1,ОГО сценария содержит ту же функцию, что находится к источнику данн^’01™°е РЙЗЛИЧИе состоит в том- что обращение происходит (&j — onern-mn varSql задается с помощью переменной varTableName. Амперсанд ся следующая с’трокаЛ,ЯЮПи'И СТр0КИ’ РезУльтатом этого выражения являет- SELECT * FROM CUSTOMER мощыо^ода <САРП0ыГп Таблицы включено в заголовок HTML-таблицы с по- нриведст к тому, что в заго'ювок СИМВ“Н с% ременной varTableName. Н МЬтабл1щы бУлст вставлено значение пе- Пер^меииоГ^г£со1Г обрабатывает коллекцию Fields, и затем элемн.п-г, ,г. „ шв-ются значение свойства Count коллекции Fields, ким образом T-ITMI * ‘ ®КЦИ11 персбнраются в цикле. Обратите внимание, ка в HTML — как R i» 1аз Росли в серверном коде (или серверный код разбросан <*1 юлыне правится) Ранее в переменную varKeyName было
Примеры использования ADO 571 записано имя суррогатного ключа, и цикл проверяет, не совпадает ли имя теку- щего столбца с именем суррогатного ключа. Если нет, генерируется HTML-код, создающий заголовок таблицы. Аналогичный цикл используется на следующей странице для заполнения таблицы значениями из набора записей. Преимущество этой страницы заключается в том, что она может обрабаты- вать любую таблицу, а не только какую то конкретную Фактически, если ис- пользовать введенную ранее терминологию, мы можем сказать, что страница из листинга 12.2 является абстракцией страницы из листинга 12.1. Результаты об- работки этой страницы показаны на рис. 12.10. Столбец CustomerlD не показан, как мы и ожидали. Рис. 12.10. Результат обработки ASP-страницы CustomerOracle.asp Пример 3 — чтение любой таблицы На рис 12.11, и, показана 1 ITML-форма, куда клиент может ввести имя таблицы, которая сю ин icpecyci (Волге удачным было бы решение, при котором клиенту выдавался бы раскрывающийся спнеок с возможными вариантами выбора, но /то уводит нас от обсуждения ADO ) 11оль.ювагель цвел в форму имя artist. Пре. i положим теперь, чю, koi да пользователь щелкает мышью на кнопке Show Table (Показать таблицу), форма должна запустить сценарий на сервере, который отобразит содержимое таблицы ARTIST в том же сеансе браузера Допустим так же, что суррогатный ключ оюбражаи> не нужно. Желаемые результаты пока- заны На рис 12 11, б
572 Fnjtaw 12 ODBC, OLE DB, ADO и ASP 6 Рис. 12.11. Отображение содержимого произвольной таблицы а— форма для ввода имени таблицы; б — вид таблицы на экране Для выполнения этой задачи требуются две ASP-страницы. Первая, приве енная в листинге 12.3, представляет собой HTML-страницу с тегом FOWt <FORM METHOD" "post" ACTION="GeneraHable.asp">
Примеры использования ADO 573 Этот тег определяет на странице форму, в которую пользователь будет вво- дить данные. Здесь вводится только один элемент данных — имя таблицы. Ме- тод POST — это Н PML-процесс, посредством которого данные из формы (в нашем случае имя таблицы artist) передаются ASP-серверу и помещаются в объект под названием Form, Альтернативным методом является GET, при котором значения данных передаются в качестве параметров. Это различие здесь для нас не слиш- ком важно. Вторым параметром тега FORM является ACTION, значение которого — строка «GeneralTable.asp». Этот параметр предписывает IIS по получении отклика от формы передать файл GeneralTable.asp на обработку ASP-процессору. Значе- ния из формы будут помещены в объект Form. Остальная часть страницы представляет собой стандартный HTML. Обрати- те внимание, что полю для ввода текста присвоено имя textl Листинг 12.3. ViewRidgeTables.asp <HTML> <HEAD> <МЕТА HTTP-EQUIV='Content-Type'' CONTENT=”text/litml ;charset=windows-1252"> <TITLE>Table Display Form</TITLE> </HEAD> <BDDY> <FORM METHOD-''post" ACTION="GeneralTable.asp"> <P><STRONG><FGNT color=purple face-'"' size=5>8nbsp. &nbsp; Table Display Selection Form</FONT></STRONG> <px/p> <P>&nbsp;</P> <PxF0NT style="BACKGROUND-COLOR: #ffffff"><FONT color-forestgreen face-"" Style=“BACKGROUND-COLOR: #f f f ff f ”>Enter TableName </FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp:</FONT></P> <px/p> <P><FONT style=”BACKGROUND-COLOR #ffffffff”x/FDNT>&nbsp; <INPUT id-textl name*textlx/p> <P><FONT style-"BACKGROUND-COLOR: <1NPUT id-subimtl name-submitl type-submit value=''Show table” >&nbsp,Snbsp;&nbsp. <INPtrr id-reset 1 name-resetl type-reset value-=“Reset Values"x/FONTx/p> </FORM> </BODY> В листинге 12.4 показана ASP-страннца GeneralTable.asp, которая вызывается, ко- гда ASP-npojicccopy приходи г отклик or с границы с формой, изображенной в лис- тинге 12.3 Первый выполняемый сценарный оператор имеет следующий вид: WTfibleName - Request Forml"textl")
574 Глава 12. ODBC, OLE DB. ADO и ASP Request. Form - ло имя объекта, который (одержит значения, зером. В лом случае textl будет содержать значение "artist" посланные брау Листинг 12.4. GeneralTable.asp <HTHL> <HEAD> <НЕТА HTTP-EQUlV=”Content-Type" CONTENT-"text/html .charset-windows 1252“» <TITLE>Table Display Page</TITLE> </HEAD> <BODY> <!-#include virtual = "ViewRedgeExamplel/adovbs inc"-> <% Dim objConn. objRecordSet, objField Dim varNumCols. varl. varSql Dim varTableName. varRecordSetName. varKeyName Dim varTableNameFirst. varTableNameRest varTablename = Request. Form ("textl") ' Формируем имя ключа как имя таблицы в нижнем регистре ’ с заглавной первой буквой + символы ID. например CustomerlD varTableNameFirst = UCase(Left(varTableName. 1)) varTableNameRest = LCase(Right(varTableName. Len(varTableName)-D) varKeyName = varTableNameFirst & varTableNameRest &”ID" ' используем для сохранения указателя на набор записей varRecordSetName = "_rs_" & varTableName If IsObject(Session(”_conn")) Then Set objConn = Session!"_conn") Else Set objConn = Server.CreateObject("ADODB.connection”) ' избегаем "грязного" чтения objConn.IsolationLevel = adXactReadCommitted objConn.open "ViewRidgeSS". "sa" Set Session!”_conn") = objConn End If If IsObject(Session(varRecordSetName)) Then ' используем сохраненный набор записей, если это возможно Set objRecordSet = Session(varRecordSetName) objRecordSet.Requery Else ' Заключаем имя таблицы в скобки, если оно содержит пробелы и т. п varSql = "SELECT * FROM " & “[" & varTableHame & "J" Set objRecordSet = Server.CreateObject("ADODB.Recordset )
Примеры использования ADO 575 ' В следующем операторе обратите внимание на использование ' типов курсора и блокировок ’ разрешаем обновление objRecordSet.Open varSql. objConn. adOpenDynamic. adLockOptinristlc Set Session(varRecordsetHame) = objRecordSet End If «> <TABLE BORDER-1 BGCOLOR=#ffffff CELLSPACING=O> <FONT FACE-"Arial" COLOR=#OODOOO> <CAPTION><B><«=UCase (varTableName) «> (In SQL Server Database)</B>< CAPTION> </FONT> <THEAD> <TR> <% varNumCols - objRecordSet.Fields.Count For varl = 0 to varNumCols - 1 Set objField = objRecordSet.Fields (varl) If objField.Name о varKeyName Then %> «TH BGCOLOR=#cOcOcO EOROERCOLOR=#00000 > «FONT SIZE-2 FACE-'Arial" COLOR-#000000> <«=obj Field.Name«> </F0NT> </TH> <« End If Next«> </TR> </THEAD> <TBODY> <% On Error Resume Next objRecordSet.MoveFi rst do while Not objRecordSet.eof %> <TR VALJGN-TOP> <% varNumCols = objRecordSet.Fields.Count For varl - 0 to varNumCols - 1 Set objField - objRecordSet.Fields(varl) If objField.Name <> varKeyName Then %> «TD BORDERCOLOR #c0c0c0 > «FONT SIZE-2 FACE-"Ar al" COLOR=#ODOOOO> ««-Server HTMLEncode (objField.Value) «><BR> «/FONT? </TD>
576 Глава 12, ODBC. OU DB. ADO и ASP листинг 12.4 (продолжение) End If Nextfc* </TR> <X objRecordSet MoveNext loop <BR><BR><A HREF-”V1ewRidgeTables asp''>V1ew Another Table</A> </TB0DY> <TFOOT></TFOOT> </TABLE>’ </BODY> </HTML> Эта версия GeneralTable.asp обрабатывает базу данных View Ridge для SQL Server. Имена суррогатных ключей в SQL Server представлены в виде ArtistID а не ARTISTID. Поскольку сравнения строк в VBScript чувствительны к регистру букв, нам нужно убедиться, что переменная varKeyName содержит имя суррогат- ного ключа в требуемом формате. Пользователь мог ввести ARTIST, artist, Artist или, скажем, aRtlsT, поэтому мы не можем просто присоединить буквы ID к введен- ному имени таблицы. Три оператора, начинающиеся с varKeyNameFirst, используют функции UCase и LCase для придания правильного формата значению varKeyNaee. Остаток этой страницы имеет тот же вид, что и в странице Customer.asp, пока- занной в листинге 12.2. Снова обратите внимание, что в переменную varXeytiaee будет записано имя суррогатного ключа ArtistID, значения которого мы не хотим выводить. Пример 4 — обновление таблицы пример демонстп!Щпх “римеРах Рассматривается чтение данных. Следующий вставки повой гт 1РУеУ.° Новление данных в таблице средствами ADO путем и национальное Р°КИ' а рис- 1212, а, показана форма, в которую вводится имя только в ней им НОВОГО хУдожника. Эта страница аналогична ViewRidgeTables.asp. ' н ются два поля ввода вместо одного. Когда пользователь щелкает на кнопке Save New ArtRt »ике добавляется в базу лаш НОВОГ° хУДОЖН11ка)’ запись о худож- страница, представленийре3ультат является успешным, выводится лепного списка) bi.hi с. 12 12, 6. Ссылка See New List (Просмотр обнов- траницу Artist.asp, которая выводит содержимое таб- лицы ARTIST с повой строкой, как показано па рис. 12.12, в. ексты соответствующих ASP-страниц приведены в листингах 12.5 и 12.6. ервая страница представляет собой форму для ввода данных с двумя полями, в одно из которых вводится имя художника (ноле Name), а в другое — его на циоиалыюсть (поле Nation). Когда пользователь щелкает па кнопке Submit (Пол твердить), эти данные посылаются обратно I IS, которая, в свою очередь, переда ctjtx вместе со страницей AddArtistasp ASP обработчику.
Примеры использования ADO 577 в Рис. 12.12. Добавление данных в таблицу ARTIST: а — форма для ввода данных; б — страница сообщения об успешной вставке; в — вид таблицы ARTIST
578 Глава 12. ODBC, OLE DB, ADO и ASP Листинг 12.5. NewArtist.asp <HTML> <HEAD> <META HTTP-EQUIV=''Content-Type“ CONTENT=“text/html:charset=windows-1252"> <TITLE>New ARTIST Entry Form</TITLE> </HEAD> <B0DY> <FORM METH0D="pOSt" ACTION="AddArtist,ASP"> <P><STRONG><FONT color=purple face='"' size=5>&nbsp:&nbsp: New Artist Data Form</FQNT></STRONG> <P></P> <P>&nbsp:</P> <P><FONT style=“BACKGROUND-COLOR: #ffffff"><FONT color=forestgreen face=“ sty1e=“BACKGROUND-COLOR. #ffffff>Artist Name:</F0NT>&nbsp.&nbsp;&nbsp,&nbsp:&nbsp, <INPUT id=text 1 name=Name style="HEIGHT: 22px; WIDTH: 164px"></FDNT></P> <P><FONT color=forestgreen face="“ Styl e=''BACKGROUND-COLOR: National ity:&ntasp: &nbsp: &nbsp: Snbsp; &nbsp; &nbsp; &nbsp; <INPUT id=text2 name=Nation style="HEIGHT: 22px; WIDTH 167px”></FONT></P> <P>&nbsp;</P> <P><FONT style='BACKGROUND-COLOR #ffffff"> <INPUT id=submitl name=submitl type=submit value=''Save New Artist">&nbsp:&nbsp;&nbsp: <INPUT id-resetl name=resetl type=reset value=”Reset Values"></FONT></P> </FORM> </B0DY> </HTML> Листинг 12.6. AddArtist.asp <HTML> <HEAD> <META HTTP-EQUIV=”Content-Type" CONTENT=”text/html;charset=windows-1252”> <TITLE>Add ARTIST Example</TITLE> </HEAD> <BODY> <!-#include virtual=',ViewRidgeExample/adovbs.1nc"-> <% Dim objConn. objRecordSet. objField Dim varNumCols. varl, varSql Set objConn = Server.CreateObject (“ADODB connection") пользуемся системной идентификацией
Примеры использования ADO 579 objConn.open "VlewRidgeSS” ' избегаем "грязного” чтения objConn. IsolationLevel = adXactReadCommitted varSql = "SELECT * FROM [ARTIST]" Set objRecordSet = Server.CreateObject ("ADODB.Recordset" ) В следующем операторе обратите внимание на использование типов ’ курсора и блокировок objRecordSet.Open varSql. objConn. adOpenDynamic. adLockOptimlstic objRecordSet.AddNew objRecordSet ("ArtistName”) = Request.Form ("Name”) objRecordSet ("Nationality") = Request.Form ("Nation") objRecordSet.Update On Error Resume Next varErrorCount = objConn.Errors.Count If varErrorCount > 0 Then For varl = 0 to varErrorCount - 1 Response.Write "<BR><I>” & objConn.Errors (varl).Description & "</IxBR>" Next End If objRecordSet.Close objConn.Close Response.Write "<BR>Data has been added. Thank you!<BR>" Response. Write “<A HREF="& .... &”artist -asp” & ....& ">See New List</A>" l> <BRxBR> </B0DY> </HTML> Страница AddArtist.asp (приведенная в листинге 12.6) создает объекты Connection и Recordset. При этом не делается попыток сохранить указатели на эти объекты в сеансовых переменных. (Предполагается, что за один сеанс будет добавлен только один художник, поэтому сохранение не потребуется.) Если указатели все-таки нужно сохранить, это можно сделать по аналогии с предыдущими при- мерами. Основная отличительная особенность данной страницы заключается в сле- дующих операторах: objRecordSet.AddNew ObjRecordSet!"Name") - Request.Form!"Name”) objRecordSet!"Nationality”) - Request.Form("Nation") objRecordSet.Update
580 Глава 12. ODBC. OLE DB. ADO и ASP a 6 Рис. 12.13. Добавление нового клиента с помощью хранимой процедуры, а т1д2,,Ма для ввода данных о клиенте; б — вид соединения таблиц CUSTOMER и ART га
Примеры использования ADO 581 Первый оператор создает новую строку в объекте objRecordSet. Затем в нее за- писываются значения полей Name и Nationality, считанные из формы. Обратите внимание, что имена столбцов нс обязаны совпадать с именами полей формы Здесь второй столбец называется Nationality, а значение поля формы - Nation Вызов функции objRecordSet. Update производит обновление базы данных. Обра- тите внимание на код обработки ошибок, который выводит сообщения об ошиб- ках с помощью оператора Response.Write (этот метод принадлежит встроенному ASP-объекту Response). Завершается страница двумя вызовами этого же метода, первый из которых отправляет пользователю подтверждающее сообщение, а второй создает ссылку на страницу Artist.asp, перейдя по которой, пользователь может увидеть таблицу с новыми данными. Пример 5 — вызов хранимой процедуры Мы создали две версии хранимой процедуры Gusto merjnsert: одну для Oracle, другую для SQL Server (в главах 10 и 11 соответственно). В обоих случаях храни- мая процедура принимает в качестве параметров имя нового клиента, код региона, местный номер телефона и национальность художников, работами которых инте- ресуется данный клиент. Процедура создает новую запись в таблице CUSTOMER и добавляет соответствующие строки в таблицу пересечений. Чтобы вызвать хранимую процедуру из ASP-страницы, мы создадим веб- форму (рис. 12.13, а), в которую будут вводиться данные клиента. Когда пользо- ватель нажмет кнопку Add Customer (Добавить клиента), будет вызвана ASP-стра- ница, которая, в свою очередь, вызовет хранимую процедуру, передав ей данные из формы. Чтобы пользователь мог убедиться, что данные были добавлены кор- ректно, ASP-страница затем запросит представление, соединяющее имена кли- ентов с именами и национальностями художников. Результат представлен на рис. 12.13, б. В листинге 12.7 приведен код формы для ввода данных. Полям ввода даны имена textl-text4. Когда пользователь щелкает на кнопке Add Customer (Добавить клиента), данные из формы передаются ASP-странице CustomerlnsertOracle, ука- занной в операторе FORM METHOD (листинг 12.8). Листинг 12.7. NewCustomerOracle.asp <HTML> <HEAD> u <META HTTP-EQ(JlV-"Content-Type" CONTENT="text/html ;charset-windows-1252 <TITLE>Table Display Form</TITLE> </HEAD> <BOOY> «FORM METHOD»''post" ACT10N-"CustonierInsert0racle.ASP"> <₽><STRONG><FOWT color-purple face-"" size-5>&nbsp;&nbsp: View Ridge 6a11ery</F0NT></STR0NG>
582 Глава 12. ODBC, OLE DB, ADO и ASP Листинг 12.7 (продолжение) <P>&nbsp. &snbsp, &nbsp,<strong><font color»"purple“ face 51«**5*> Customer Form</font></strong><P><font style-“background color |fffff** color-"forestgreen" face>&nbsp. &nbsp: &nbsp. Name &nbsp. &nbsp </font><FONT style-”BACKGROUND COLOR #ffffff">&nbsp: &nbsp: &nbsp. Snbsp. Snbsp. &nbsp, Rnbsp, &nb$p, &nfe«p vfctp &nbsp: &nbs p. &nbsp. &nbsp. &nbsp. &nbsp. &nbsp. &nbsp, &nbsp &nb$p bOfO &nbsp. &nbsp: </FONT><INPUT icl-textl name-textl></P> <P>&nbsp:<font style»"background color. #ffffff" col or»"forestgreen" face>&nbsp; &nbsp; &nbsp:AreaCode<font style»"background~color #ffffff">:&nbsp Snbsp; &nbsp ;</font>&nbsp; Snbsp; &nbsp. &nbsp, &nbsp. y- &nbsp :&nbsp: &nbsp: &nbsp: &nbsp: &nbsp: &nbsp: Snbsp &nbsp. &nbsp. &nb$p </font><INPUT id=text2 name-text2 size-"6"x/p> <P><font style="background-color: #ffffff" col or»”forestgreen" face>8nbsp &nbsp: &nbsp; Phone: &nbsp: &nbsp: Snbsp: &nbsp; &nbsp: Snbsp; &nbsp. &nbsp. &nbsp &nbsp: &nbsp; &nbsp;&nbsp: &nbsp: &nbsp: &nbsp: &nbsp: &nbsp: &nbsp. &nbsp &nbsp &nbsp: &nbsp: &nbsp. &nbsp.&nbsp: </font><lNPUT id=text3 name=text3 size=”20">&nbsp; &nbsp: &nbsp: Snbsp: &nbsp: &nbsp: &nbsp: &nbsp. </P> <P>&nbsp: &nbsp- &nbsp <font style=,’background-color color="forestgreen" face>Nat1опа1ity of Artists: &nbsp; &nbsp: </font>&nbsp; &nbsp: <INPUT id=text4 name=text4 s1ze=,’17”></p> <P>&nbsp:<FONT style=”BACKGROUNO-COLOR: #ffffff"> &nbsp: &nbsp:&nbsp: </FONT>&nbsp: &nbsp: &nbsp: &nbsp: <FONT style=”BACKGROUND COLOR: #ffffff> <INPUT id=submitl name=sutmtl type=submit value=''Add Customer" >&nbsp: &nbsp: &nbsp <INPUT id=resetl name=resetl type=reset value=”Reset Values“x/FONTx/p> </FORM> </BODY> </HTML> Листинг 12.8. CustomerlnsertOracle.asp <HTML> <HEAD> <META HTTP-EQUIV=”Content-Type“ CONTENT="text/html;charset=windows-1252"> <TlTLE>Customer Update Display Page</TITLE> </HEAD> <BODY> <P> <STRONG><FONT color=purple face=“" size=5>
Примеры использования ADO 583 &nbsp;&nbsp: Customers and Interests After Update </F0NTx/STR0NG> <!"#include vi rtual=”ViewRidgeExamples/adovbs.inc”-> <« Dim objConn. objCommand. objParam. oRs Dim objRecordSet. obj Field Dim varl. varSql. varNumCols. varValue If IsObject(Session("_conn")) Then ' используем текущий сеанс, если это возможно Set objConn = Session(”_conn“) Else Set objConn = Server.CreateObject("ADODB. connection”) ' хранимая процедура установит свой собственный уровень изоляции objConn.open "DSN=ViewRidge0racle2:UID=DKl; PWD=Sesame" ’ а это можно было бы использовать для обновления ' через SQL Server: 'objConn.open "ViewRidgeSS". "sa" Set Session("_conn") = objConn End If ' создаем объект command Set objCommand = Server.CreateObjectCADODB.Command”) ' устанавливаем соединение для объекта command Set objCommand. ActiveConnection = objConn ' готовим вызов хранимой процедуры objCommand.CommandText="{call Customer_Insert (?. ?. ?. ?)}“ 12 ' Присваиваем необходимые значения четырем параметрам Set objParam = objCommand.CreateParameterC'NewName". adChar. adParamlnput. 50) objCommand. Parameters. Append objParam objParam. Value f Request. FormCtextl") Set objParam - objCommand.CreateParameter("AreaCode". adChar. adParamlnput. 5) objCommand. Parameters. Append objParam ObjParam Value - Request.Form("text2”) Set objParam - objCommand. Create Parameter("PhoneNumber". adChar. adParam nput. 8) objCommand. Parameters. Append objParam objParam. Value - Request.Form("text3“) Set ObjParam - objCommand.CreateParameterf’Nationality". adChar. adParamlnpul. 25) ObjCommand Parameters Append objParam ObjParam Value - Request.Form(’text4") продолже>мп&
584 Глава 12. ODBC. OLE DB. ADO и ASP Листинг 12.8 (продолжение} ' Вызываем хранимую процедуру Set oRs - objCommand Execute ' теперь читаем данные из представления, содержащего ' таблицы CUSTOMER and ARTIST. ’ используя соединение через таблицу пересечений varSql - "SELECT * FROM CUSTOMERINTERESTS" Set objRecordSet - Server.CreateObjectC'AOOOB Recordset" objRecordSet.Open varSql. objConn %> <TABLE BORDER=1 BGCOLOR=#ffffff CELLSPACING=5> <FONT FACE="Arial" COLOR-#OOOOCO> <CAPTION><B><CUSTOMERS AND INTERESTS</Bx/CAPTION> </FONT> <THEAD> <TR> <« varNumCols = objRecordSet.Fields.Count For varl = 0 to varNumCols - 1 Set objField = objRecordSet.Fields(varl) %> <TH BGCOLOR=#cOcOcO BORDERCOLOR =#000000 > «FONT SIZE=2 FACE=”Arial" COLOR=#ODOOOO> <S=objField.Name$> </FONT> </TH> </TR> </THEAD> <TBODY> <% On Error Resume Next ObjRecordSet.MoveFi rst do while Not objRecordSet eof %> <TR VALIGN=TOP> <X varNumCols = ObjRecordSet.Fields Count For varl = 0 to varNumCols - 1 Set objField = objRecordSet.Fields(varl) If objRecordSet.Fields(varl).Type = adNumeric then varValue=CDbl(objField.Value) varValue = convert(char. varValue) else va rVa1ue=Server.HTMLEncode(objField.Va1ue) End If
Примеры использования ADO 585 %> <TD BORDERCOLOR=#cOcOcO > <FONT SIZE=2 FACE="Arial" COLOR=#OOOOQO> <3=(varValue)X><BR> </FONT> </TD> <« varValue=”” NexU> </TR> objRecordSet.MoveNext loop %> </TBODY> <TF00Tx/TF00T> </TABLE> </BODY> </HTML> Эта страница ищет сохраненный объект Connection и, если не находит тако- вого, создает новое соединение, как показано в предыдущих примерах. Затем она создает команду objCommand и связывает ее с соединением objConn. После этого задается шаблон вызова хранимой процедуры Customer insert строкой «CommandText="{call Customer_Insert(?, ?, ?, ?)}». Четыре знака вопроса указыва- ют на то, что процедуре будет передано четыре параметра. Далее создаются пара- метры и присоединяются к объекту-команде. В конце происходит запуск коман- ды, что приводит к вызову хранимой процедуры. Уровень изоляции транзакции и свойства курсора не задаются, так как хранимая процедура установит их само- стоятельно. После выполнения команды создается набор записей, содержащий все столб- цы представления CUSTOMERINTERESTS, и данные из него отображаются в браузере так же, как показано в предыдущих примерах. В обеих базах данных — как Oracle, так и SQL Server — представление CUSTOMERINTERESTS было определено как соединение таблиц CUSTOMER и ARTIST через таблицу пересечения. Для Oracle использовался следующий синтаксис: CREATE VIEW CUSTOMERINTERESTS AS SELECT CUSTOMER NAME CUSTNAME. ARTIST.NAME ARTISTNAME. ARTIST.NATIONALITY FROM CUSTOMER. CUSTOMER_ARTIST_INT. ARTIST WHERE CUSTOMER.CUSTOMERID = CUSTOMER_ARTIST_INT.CUSTOMERID AND ARTIST ARTISTID = CUSTOMER_ARTIST_INT.ARTISTID ORDER BY CUSTNAME Эта страница интересна тем, что различие между приведенной здесь версией Для Oracle и версией для SQL Server заключается в имени источника данных ODBC, имени учетной записи и пароле. Обратите внимание на строку коммен- тария под оператором objConn.Open- все особенности конкретных СУБД содер- жатся в хранимых процедурах, и разработчику ASP-страницы ничего не нужно знать о них.
586 Глава 12. ODBC. OLE DB. ADO и ASP Эти примеры дают представление об использовании ADD Лучший послб узнать об этом больше - написать несколько страниц самостоятельно В длине главе описаны все основные методики, которые вам потребуются Вам пришлось немало потрудиться, чтобы дойти до этого места, и если вы понимаете достаток но для того, чтобы написать собственную ASP-сграпицу, то вас можно поздра- вить — вы многого достигли с первой главы! 1 11 Резюме Приложения баз данных находятся в богатом и сложном по составу окружении Кроме реляционных баз данных существуют также нереляционные базы данных, системы обработки файлов, подобные VSAM, электронная почта и другие типы данных — изображения, звуковые файлы и т. д. Для облегчения труда приклад- ных программистов был разработан ряд стандартов. Стандарт ODBC предназ; - чен для работы с реляционными базами данных, а стандарт OLE DB позволяет работать как с реляционными, так и с нереляционными базами данных. С целью обеспечения более легкого доступа к функциональности OLE DB для програм- мистов, не знакомых с ООП, был разработан стандарт ADO. ODBC, или открытый стандарт взаимодействия баз данных, предоставляет интерфейс, с помощью которого программы на веб-сервере могут обращаться к реляционным источникам данных и обрабатывать данные из них независимым от СУБД способом. Стандарт ODBC был разработан производственным комитетом и реализован многими производителями, в том числе Microsoft. ODBC включает в себя прикладные программы, диспетчер драйвера, драйвер СУБД и компоненты источника данных. Существуют два типа драйверов: одноуровневые и многоуров- J.. невые. Есть также три типа источников данных: файловые, системные и пользо- вательские. Системные источники данных рекомендуются для веб-серверов. При определении системного источника данных необходимо указать тип драйве- ра и идентификатор используемой базы данных. OLE DB — это то, на чем основан доступ к данным в мире Microsoft. Данный стандарт реализует спецификации Microsoft OLE и СОМ и доступен объектно- ориентированным программам через данные интерфейсы. OLE DB разбивает возможности и функции СУБД на объекты, что упрощает для производит» реализацию функциональности по частям. Ключевыми терминами являются стракция, метод, свойство и коллекция. Набор строк является абстракцией набо ра записей, который, в свою очередь, является абстракцией отношения. Объекты имеют свойства, описывающие их характеристики, и методы — действия, кото рые они могут выполнять. Коллекция — это объект, содержащий группу ДР-'Т.11Х объектов. Цели OLE DB перечислены во врезке «Цели создания OLE *• Интерфейс — это объект, предоставляющий доступ к некоторому множеств^ свойств и методов набора объектов. Различные интерфейсы могут предос доступ к разным методам и свойствам одного и того же набора объектов. еа> зация — это способ выполнения задач объектом. Реализация скрыта от вне1^Уе^(- мира, и ее можно изменять, не затрагивая пользователей объектов. Пятеро* не должен меняться никогда.
Вопросы группы I 587 Поставщики табличных данных представляют данные в виде наборов строк. Поставщики услуг преобразуют данные в другую форму; такие поставщики одно- временно являются и потребителями данных. Набор строк эквивалентен курсору. Основными интерфейсами набора строк являются интерфейсы IRowSet, lAccessor и IColumnsInfo. Есть и другие интерфейсы, которые предоставляют различные до- полнительные возможности. ADO — это простая объектная модель, используемая потребителями данных OLE DB. К ее объектам можно обращаться из любого языка программирования, поддерживаемого Microsoft. Основными объектами ADO являются Connection, RecordSet и Command, а также коллекция Errors. Объект Recordset имеет коллекцию полей Fields, а объект Command имеет коллекцию параметров Parameters. Объект Connection устанавливает соединение с поставщиком данных и источ- ником данных. Соединения имеют режим изоляции. После того как соединение установлено, с его помощью можно создавать наборы записей (объект RecordSet) и команды (объект Command). Объект RecordSet представляет курсор и имеет свой- ства CursorType и LockType. Наборы записей можно создавать с помощью SQL- операторов. Для индивидуальной обработки полей набора записей используется коллекция Fields объекта RecordSet. Коллекция Errors содержит сообщения об ошибках, произошедших в резуль- тате выполнения операции ADO. Объект Command используется для запуска пара- метризованных запросов или хранимых процедур. Введенные данные можно пе- ресылать ASP-странице на обработку посредством HTML-тега FDRM. Обновления в таблицах производятся с помощью метода Update объекта RecordSet. Вопросы группы I 1. Объясните, в чем состоит сложность окружения, в котором находятся веб- серверы. 2. Какова связь между ODBC, OLE DB и ADO? 3. Объясните, чем автор оправдывает то, что он уделяет столь большое вни- мание стандартам Microsoft. Согласны ли вы с ним? 4. Перечислите компоненты стандарта ODBC. 5. Какую роль играет диспетчер драйвера? Кто его предоставляет? 6. Какую роль играет драйвер СУБД? Кто его предоставляет? 7. Что такое одноуровневый драйвер? 8. Что такое многоуровневый драйвер? 9, Есть ли что-нибудь общее в том, как термин уровень используется по отно- шению к архитектуре компьютерных систем (трехуровневая архитектура) и в ODBC? 10 Зачем нужны уровни соответствия? 11 Дайте краткую характеристику грех уровней соответствия интерфейса прикладных программ ODBC.
Tim— It ОМС. OLfc Pt) APQ ** _ 12. Дайте краткую хармтгрмггшгу три» УР"'в*в* e’*er’r^*-*' «рмшамм Цд_ 13 Объясните разницу между tjk-мя типами источников имяыь 14. Какой тип hctohhhkj данных роюмундутя ДМ « • i— v*? 15. Какие два лейст мня необходим- - ими >• 1НМТВ1ЦШ п«н<*м мм» алищ кд данных ODBC? 16. В чем назначение OLL DB? 17. Какой недостаток ODBC преодплеиагтся в OI f DB? 18. Определите термин аСкщюсцм и,Лми>мите< *’* °” оиюсккл к OLE (ж 19. Приведите пример абстракции с набором строк. 20. Что такое свойства и методы объекта? 21. В чем разница между объектным классом и объектом? 22. Кто такие пот}>ебители и поставщики данных* 23. Что такое интерфейс? 24. В чем разница между интерфейсом и реализацией*’ 25. Объясните, почему реализация может меняться, а интерфейс ие доовм меняться никогда. 26. Перечислите цели OLE DB. 27. Что такое MTS и каковы его функции? 28 Чем отличается поставщик табличных данных от поставщика услуг? Кто из них занимается преобразованием данных OLE DB в XXfL-лвгг- менты? 29. В чем разница между набором строк и курсором в контексте OLE DB' 30. Какие языки можно использовать с ADO? 31. Перечислите объекты, составляющие объектную модель ADQ. и укажите их взаимосвязи. 32. Какова функция объекта Connection? 33. Напишите фрагмент кода па VBScript, создающий объект Connection 34. Какова функция объекта RecordSet? 35. Напишите фрагмент кода на VBScript, создающий объект RecordSet 36. Что содержится в коллекции Fields? Приведите пример ситуация, кото" рой вы использовали бы эту коллекцию. 37. Напишите фрагмент кода на VBScript, обрабатывающий коллегии к» FitMi 38. Что содержится в коллекции Errors? Приведите пример ситуация я «о*®" рои вы использовали бы эту коллекцию. 39. Напишите фрагмент кода на VBScript, обрабатывающий коллекцию Сгивгх 40. Каково назначение объекта Command? 41. Напишите фрагмент кода на VBScript, который запускал бы п*ря*"Ф-*' ванный хранимый запрос с двумя параметрами - Ай В
Вопросы группы II 589 42. Объясните назначение тегов <% и %> в ASP-страницах. 43. Объясните назначение переменной conn в листинге 12.1. 44. Для чего нужен код, создающий переменную varKeyName в листинге 12.4? 45. Объясните назначение параметра ACTION тега FORM в листинге 12.3. 46. Объясните, что произойдет, если в ASP-страпице в листинге 12.4 будет выполнен следующий оператор: varTableName = Request.Form("textl”) 47. Напишите фрагмент кода на VBScript, добавляющий новую запись в на- бор записей objMyRecordSet. Пусть имеется два поля — А и В — со значе- ниями «AValue» и «BValue» соответственно. 48. Какой цели служит оператор Response.Write? Вопросы группы II 49. Корпорация Microsoft прилагает много усилий для продвижения стандар- тов OLE DB и ADO. Однако она не получает непосредственной прибы- ли от этих стандартов. IIS поставляется бесплатно в составе Windows ХР и Windows 2000. На сайте Microsoft имеется множество статей в помощь разработчикам, и все это находится в свободном доступе. Как вы думаете, почему Microsoft это делает? Какая цель преследуется? 50. В тексте ASP-страницы в листинге 12.6 устанавливается динамический тип курсора. Какое воздействие это окажет на обработку этой страницы и стра- ниц Customer.asp и Artistasp? Как, по вашему мнению, должны быть заданы уровень изоляции, тип курсора и тип блокировки в приложении, вклю- чающем все эти страницы? 51. Объясните, как следует изменить ASP-страницу из листинга 12.1, чтобы она работала с источником данных ViewRidgeOrade. Объясните, как следует изменить ASP-страницу из листинга 12 2, чтобы опа работала с источником данных ViewRidgeSS. Хотя простота таких изменений представляет интерес с технологической точки зрения, является ли эта возможность сколько- нибудь важной в мире коммерции? 52, Если вы установили Oracle, запустите с помощью браузера ASP-страницу из листинга 12.2. Теперь откройте SQL*Plus и удалите две строки из таб- лицы CUSTOMER с помощью SQL-онерагора DELETE. Снова запустите ASP- страницу в браузере. Объясните полученные результаты. 53. Если вы установили SQL Server, запустите с помощью браузера ASP-стра- ницу из листинга 12.1. Теперь откроите SQL Query Analyzer и удалите две строки и । таблицы CUSTOMER с помощью SQ1 -оператора DELETE Снова запустите ASP страницу в браузере. Объясните полученные результаты Если вы ответили на вопрос 52, объясниic различия в результатах, если таковые были
590 Глава 12. ODBC, OLE DB, ADO и ASP Вопросы к проекту FiredUp Создайте базу данных FiredUp с помощью Oracle или SQL Server, если вы еще не сделали этого. Следуйте указаниям и конце главы 10 или 11 соответствен 1. Создайте ASP-страницу, отображающую таблицу ГОРЕЛКА 2. Создайте ASP-страницу, отображающую любую таблицу в базе данных FiredUp. За образец возьмите листинги 12.5 и 12.6 3. Создайте ASP-страницу, позволяющую ввести данные новой горелки. Обос- нуйте ваш выбор уровня изоляции курсора. 4. Создайте ASP-страницу, позволяющую клиенту зарегистрировать свою горелку. Предположим, что информация о клиенте и горелке уже присут- ствует в базе данных. Обоснуйте ваш выбор уровня изоляции курсора. 5. Создайте хранимую процедуру, позволяющую ввести данные о ремонте горелки. 6. Создайте ASP-страницу, вызывающую хранимую процедуру, которая была создана в предыдущем вопросе. За образец возьмите листинги 12 7 и 12.8 Я Вопросы к проекту Twigs Tree Создайте базу данных Twigs Tree с помощью Oracle или SQL Server, если вы еще не сделали этого. Следуйте указаниям в конце главы 10 или 11 соответственно. 1. Создайте ASP-страницу, отображающую таблицу ВЛАДЕЛЕЦ. 2. Создайте ASP-страницу, отображающую любую таблицу в базе данных Twigs Tree. За образец возьмите листинги 12.5 и 12.6. 3. Создайте ASP-страницу, позволяющую ввести данные о новом клиенте. Обоснуйте ваш выбор уровня изоляции курсора. 4. Создайте ASP-страницу, позволяющую клиентам заказывать работы. Вво- дить следует только дату и описание работы. Обоснуйте ваш выбор уров- ня изоляции курсора. 5 Создайте хранимую процедуру, позволяющую ввести данные о новом клиенте. 6 Создайте ASP-страницу, вызывающую хранимую процедуру, которая была создана в предыдущем вопросе. За образец возьмите листинги 12.7 п 12 8.
Глава 13 XML и ADO.NET В этой главе обсуждается одна из самых важных, а может, и самая важная техноло- гия сегодняшнего дня, возникшая на стыке двух предметных областей — обработ- ки баз данных и обработки документов. В течение более 20 лет эти две области развивались независимо друг от друга. Однако с появлением сети Интернет они неожиданно встретились, и произошло то, что некоторые эксперты описывают как «крушение технологического поезда». Полная картина результатов до сих пор не ясна, можно лишь определенно сказать, что каждый месяц появляются но- вые продукты, возможности, технологические стандарты и методики разработки. Важность XML Обработка баз данных и обработка документов неразрывно связаны друг с дру- гом. При работе с базами данных часто приходится иметь дело с документами: на- пример, чтобы пользователь мог просмотреть представление базы данных, не- обходимо оформить его в виде документа. И наоборот, обработка документов нередко включает в себя работу с базами данных — например, хранение и различ- ного рода манипуляции с данными, содержащимися в документе. Но очевидной эта связь стала только после того, как завоевал популярность Интернет. Первое время содержимое веб-сайтов было в основном статическим. По мере того как Интернет стал использоваться более широко, у организаций появилось желание сделать свои сайты более функциональными, чтобы на них можно было отобра- жать (азатем и обновлять) информацию из баз данных. С этого момента веб-раз- работчики стали всерьез интересоваться SQL, вопросами производительности, безопасности и прочими аспектами баз данных. Наблюдая появление огромной армии веб-разработчиков, интересующихся базами данных, профессионалы в этой области стали задаваться вопросом: кто эти люди и чю им нужно? Сообщество разработчиков баз данных начало знако- миться с языком HTML, который используется для разметки документов, ото- бражаемых в браузерах. Поначалу отношение к HTML в этой среде было пре- небрежительным из за свойственных ему ограничений, по постепенно пришло осознание того, что HTML является приложением другого, более универсального языка обработки документов — SGML (Standard Generalized Markup Language —
592 Глава 13. XML и ADO NET «стандартный обобщенный язык размсчки») Важность SGML трудно переоцр нить: этот язык столь же важен для обработки документов, сколь важна была ре- ляционная модель для баз данных. Какую же роль суждено было сьирать этому языку в проблеме отображения информации из баз данных? Результатом вс тройного движения двух про<|х-ссионалы1ых сообществ в начале 1990-х годов явилось создание ряда стандартов. относящихся к языку под назвали ем XML (extensible Markup Language — «расширяемый язык разметки») XML является подмножеством SGML, по благодаря ряду дополнительных стандартов и возможностей сегодняшняя XML-технология представляет собой гибрид обра- ботки документов и обработки баз данных. Фактически по мере эволюции XML- стандартов стало очевидно, что разные профессиональные сообщества в течение длительного времени работали над различными аспектами одной и той же про- блемы. Они даже использовали одинаковые термины, но придавали им разные значения. Из этой главы вы узнаете, как в XML используется термин схема Здесь этот термин имеет абсолютно иное значение, чем в мире баз данных. XML предоставляет стандартизированный, но при этом гибкий способ описания содержимого документов. Как таковой оп может использоваться для описания любого представления базы данных, по в стандартной форме. Как вам предстоит узнать, XML-представлеппя, в отличие от SQL-представлений, не ограничены од- ним многозначным маршрутом. Существует стандарт XML Schema, который позволяет автоматически гене- рировать XML-документы на основе информации, хранящейся в базе данных, а также автоматически извлекать эту информацию из XML-документов. Более того, имеются стандартизированные способы определения взаимного соответст- вия между компонентами документа и элементами схемы базы данных. Постепенно и остальная часть компьютерного сообщества обратила внимание на XML. Появился основанный на XML стандарт SOAP, описывающий удаленный вызов процедур через Интернет. Изначально аббревиатура SOAP расшифровы- валась как Simple Object Access Protocol (простой протокол доступа к объектам). В качестве транспортного механизма SOAP предполагалось использовать прото- кол HTTP, но, после того как Microsoft, IBM, Oracle и другие компании объеди- нили усилия в поддержку стандарта SOAP, от этого решено было отказаться, и SOAP был определен как обобщенный стандартный протокол, используемый для передачи любых сообщений по любому транспортному протоколу. Так или иначе, XML стал находить огромное множество применений в инду- стрии информационных технологий. Одним из наиболее важных среди них яв- ляется определение документов и передача их для обработки через Интерне XML играет ключевую роль в инициативе .NET корпорации Microsoft, а Билл Гейтс в 2001 году назвал XML «универсальным языком эпохи Интернета» Обсуждение XML мы начнем с того, что рассмотрим его использование для материализации веб-страниц. Как вы узнаете позже, область применения XML простирается далеко за рамки данной отдельной задачи. Возможно, в денстви дельности материализация веб-страниц является наименее важным примененн ем XML Мы начнем с нее только потому, что она представляет собой удобны! пример дня знакомства е XML-докумеитами. После этого мы рассмотрим стаи ** iM»Q 305. IS итйТМ fes esasasa jKS
XML как язык разметки 593 дарт XML Schema и обсудим его использование для обработки баз данных. В за- ключение мы приведем примеры интегрированной обработки информации из базы данных и XML с использованием Microsoft ADO.NET. Знакомясь с материалом этой главы, имейте в виду, что на сегодняшний день эта область находится на переднем крае технологий баз данных. Стандарты, про- граммные продукты и их возможности непрерывно эволюционируют. Чтобы быть в курсе этих изменений, следите за сайтами www.w3c.com,www.xml.org, msdn.microsoft.com, www.ibm.com и сайтами других производителей. Старайтесь узнать как можно больше об XML и обработке баз данных — это один из лучших способов заложить основы успешной карьеры. XML как язык разметки В качестве языка разметки XML имеет значительные преимущества перед HTML. Этому есть несколько причин. Во-первых, создатели языка XML обеспечили чет- кое разделение между структурой документа, его содержимым и материализацией. В XML предусмотрены средства для определения каждой из этих трех состав- ляющих, и природа этих средств такова, что они не могут смешиваться, как эго было в HTML. Кроме того, хотя XML стандартизирован, этот стандарт может расширяться разработчиками, как следует из названия. В XML вы не ограничены фиксиро- ванным набором элементов вроде <TITLE>, <Н1> и <Р>, а можете определять свои собственные элементы. Одной из проблем HTML является то, что он предоставляет слишком боль- шую свободу. Рассмотрим следующий HTML-код: <Ь2>Здравствуй, мир!</Ь2> Хотя тег <h2> может обозначать заголовок второго уровня в структуре доку- мента, его также можно использовать для того, чтобы просто вывести слова «Здравствуй, мир!» определенным стилем. Из-за этого обстоятельства мы не мо- жем положиться на теги в деле определения истинной структуры HTML-страни- цы. Использование тегов носит слишком произвольный характер: <h2> может означать заголовок, а может не означать ничего. Как вы увидите, в XML структура документа формально определена. Если мы находим lei <street>, мы знаем точно, где этот тег расположен и как он соотно- сится с друшми тегами в структуре документа. Таким образом, про XML-докумен- гы творят, то оцр в точное! и передают семантику содержащихся в них данных. XML-документ и DTD В листинге 13 1 приведен пример XML документа. Обратите внимание, что доку мент имеет два раздела. В первом разделе определяется структура документа: >тггг рАздсд Пазы пае гея определением типа документа, пли DVD (Document Тхре D<< lar.itioii) Второй раздел содержит соб< ilicuno данные.
594 Глава 13. XML и ADO.NET Листинг 13.1. XML-документ Customer с вложенным определением тиле <?xml version="1.0" encoding-"UTF-8‘'?* «(-edited with XML Spy v3.5 NT (http.//www.xmlspy.com) by David Kroenke (private)-* «!DOCTYPE customer [ <!ELEMENT customer (name, address)* «’ELEMENT name (firstname. lastname)* <!ELEMENT firstname (#PCDATA)> «’ELEMENT lastname (#PCDATA)> «’ELEMENT address (street*. city, state, zip)* «’ELEMENT street (#PCDATA)> «’ELEMENT city (#PCDATA)> «!ELEMENT state (#PCDATA)> «’ELEMENT Zip (#PCDATA)> )> «customer* «name* <firstname*Mlchel1e«/firstname* «1 astname*Correl1i </1astname* «/name* «address* «street>1824 East 7th Avenue«/street> «street*Suite 700«/street> <city*Memphi s«/city> «state*TN«/state* «zip*32123-7788«/zip> «/address* «/customer* DID начинается с ключевого слова DOCTYPE, за которым следует имя типа документа — customer. Далее идет описание содержимого документа customer. В нем есть две группы: name и address. Группа name состоит из двух элементов — firstname и lastname. Эти элементы определены как йРСОАТА, то есть строки сим- вольных данных. Ниже описывается элемент address, состоящий из четырех эле- ментов: street, city, state и zip. Каждый из этих элементов также определен как символьные данные. Знак + после имени элемента street указывает на то, что ЗЮ1 элемент обязан иметь по крайней мере одно значение, но может иметь не- сколько значений. Экземпляр данных типа customer, показанный в листинге 13.1, соответствует TD, поэтому данный документ называется XML-документом, допустимым по типу (type-valid XML document). Если бы он не соответствовал DTD, он назы- вался бы недопустимым по типу документом (not-type-valid XML document). Недопус1имые по типу документы могут тем не менее быть абсолютно правиль- ными с ючки зрения XML: они просто не являются допустимыми экземплярами своего типа. Например, если бы документ в листинге 13.1 содержал два элемента city, он был бы по-прежнему правильным с точки зрения XML, но недопустн мым по типу.
XML как язык разметки 595 Хотя DTD почти всегда желательны, они не являются обязательными в XML- документах. Документ, не имеющий DTD, по определению является недопусти- мым по типу, поскольку не существует типа, относительно которого можно было бы проверить его допустимость. Раздел DTD не обязательно должен содержаться в самом документе. В лис- тинге 13.2 изображен документ типа customer, в котором DTD берется из файла C:\DB9E\First Draft\Chapter 13\XML\Docs\customer.dtd. Преимущество внешнего хра- нения DTD в том, что можно проверять допустимость множества документов от носительно одного и того же DTD. Листинг 13.2. XML-документ Customer с внешним определением типа <!DOCTYPE customer SYSTEM "С \DB9e\First Draft\Chapter 13XXML Docs\customer.dtd"> <customer> <name> <fi rstname>Mi chelIe</f1rstname> <lastname>CorreHi</lastname> </name> <address> <street>1824 East 7th Avenue</street> <street>Suite 700</street> <ci ty>Memphi s</city> <state>TN</state> <Zip>32123-7788</zip> </address> </customer> Создатель DTD может определять любые элементы по своему желанию. Сле- довательно, XML-документы могут расширяться, но расширяться стандартизи- рованным и контролируемым способом. Материализация XML-документов с помощью XSLT В XML-документе из листинга 13.1 определены структура и содержимое. Однако ничто в документе не указывает на то, как его следует материализовывать. Разра- ботчики XML обеспечили четкое разделение структуры, содержимого и формата. Наиболее популярный способ материализации XML заключается в использова- нии XSLT (extensible Style Language for Transformations, расширяемый язык сти- лей для преобразований). XSLT — это мощный и надежный язык преобразова- ний Его можно использовать для материализации XML-документов в HTML, а также для множества друг их целей. Одно из популярных применений XSLT — преобразование ХМ L-документа из одного формата в другой. Например, с по- мощью XSLT компания может преобразовать накладную, представляющую собой XML документ в некоюром внутреннем формате, в эквивалентный XML-доку- Мсит в формате клиента. Есть много возможностей и функций XSLT, которые мы иг имеем возможности здесь описать. Информацию о них вы можете найти на сайге www.w3.org
596 Глава 13 XML и ADO NET Яи,!К XSLT является, во-первых, декларативным, а во-вторых, преобразова- тельным Декларативным он является потому, что вместо указания процедуры магерпалпзацнп элементов документа вы создаете набор правил, которые опре деляют как будет материализоваться документ. Преобразовательным же он яв ляется потому, что с его помощью документ, задаваемый на входе, преобразуется в другой документ. ~ Листинг 13.3 содержит DTD документа, представляющего собой список кли ентов, а листинг 13.4 - XML-документ, соответствующий этому DTD Оператор DOCTYPE в листинге 13.4 указывает на файл, содержащий DTD (см. листинг 133) Следующий оператор в XML-документе указывает местоположение еще одного документа, называемого таблицей стилей (stylesheet). Таблица стилей изобра- жена в листинге 13.5. Таблицы стилей указывают программе-обработчику XSLT правила, по которым элементы XML-документа должны преобразовываться в дру- гой формат; в данном случае исходный документ будет преобразован в HTML- документ, пригодный для отображения в браузере. Листинг 13.3. Внешний DTD-документ для XML-документа CustomerList <?xml version='1.0’?» <!-edited with XML Spy v3.5 NT (http://www.xmlspy.com) by David Kroenke (private)-» «'ELEMENT customerlist (customer+)> <!ELEMENT customer (name, address) > <!ELEMENT name (firstnarne. lastname)» <! ELEMENT firstnarne (#PCDATA)> <! ELEMENT lastname (#PCDATA)» «‘ELEMENT address (street+. city, state, zip)» «'ELEMENT----------------- «'.ELEMENT «!ELEMENT «'ELEMENT zip (#PCDATA)> «Ж® street (#PCDATA)> city (#PCDATA)> state (#PCDATA)> Листинг 13.4. Документ CustomerList с данными о двух клиентах «?xml version='1.0'?> «!-edited with XML Spy v3.5 NT (http-//www.xmlspy.com) by David Kroenke (private)-» «1DOCTYPE customerlist SYSTEM “C:\DB9e\First DraftXChapter 13XXML DocsXcustomerli st.dtd"» «?xml-stylesheet type="text/xsl” href="C:\DB9e\First DraftXChapter 13XXML OocsXCustomerLi st.xsl”?> «customerlist» «customer» «name» «fi rstname>Michelle«/fi rstnarne» «1 astname»Correl11«/1astname» «/name» «address»
XML как язык разметки 597 «street>1824 East 7th Avenue«/street> <street>Suite 700</street> «с 1ty>Memph i s</city> <state>TN«/state> <zip>32123-7788«/zip> «/address> «/customer» «customer» «name» <firstname»Lynda«/firstname> <lastname»Jaynes</fastname» «/name» «address» <street>2 Elm Street«/street» «city»New York City</city> <state»NY«/state» <zip»02123 7445</zip> «/address» «/customer» «/customer]ist» Листинг 13.5. Таблица стилей XSLT для документа CustomerList <?xml version="1.0"?> «HTML xml ns:xsl ="http://www.w3.org/TR/WD- xsl "> «BODY STYLE="font-family.Arial, Helvetica, sans-serif: font-size:14pt: background-color:teal"> «xsl:for-each select="customerlist/customer"> <DIV STYLE=”background-color:purple: color white- padding:4px"> «SPAN STYLE="font-weight:bold: color:white"> «xsl:value-of select="name/lastname"/> «/SPAN» - <xsl value-of select="name/firstname'7> </DIV> <xsl:for-each select="address/street"> <DIV STYLE="margin left:20px margin-bottom:lem; font size:10pt font- style: bold; color:blue"> «xsl :value-of select="node()'7> <DIV> «xsl:for-each> <DIV STYLE="margin-left:20px; margin-bottom:lem; font-size:12pt: font- style:bold"> <xsl :value-of select=''address/city‘7>. <xsl -.value of select="address/state'7> </DlV> <DIV STYLE="margin-left:20px: margin bottom lem font-size:14pt: color:red"> <xsl value of select="address/zip'7> продомкение^
596 Глава 13 XML и ADO.NET Листинг 13.5 (продолжение) </DlV> <х$1:for-each> «/BODY* «/HTML* Программа-обработчик XSLT копирует элементы таблицы стилей, пока не встретит команду в формате {шаблон, действие}. Обнаружив такую команду программа ищет в документе фрагменты, удовлетворяющие заданному шаблону и для каждого из найденных фрагментов осуществляет указанное действие. Так, первый оператор xst <xsl:for-each select="customerlist/customer”/> инициирует поиск в документе элемента, обозначенного как customerlist Найдя такой элемент, программа ищет внутри него элемент с именем customer. Если он найдется, будут выполнены действия, указанные в цикле, завершающемся опера- тором </xsl:for-each> (третий снизу оператор в таблице стилей). В этом цикле всем элементам документа customerlist присваиваются стили. Результат применения таблицы стилей из листинга 13 5 к исходному XML-до- кументу из листинга 13.4 показан в листинге 13.6. Проанализируйте документ и таблицу стилей и поймите, как получаются результаты. Листинг 13.6. Результат применения таблицы стилей XSLT — текст HTML-документа «HTML xml ns:xsl=“http://www.w3.org/TR/WD-xsl”> «BODY STYLE="font-family:Arial. Helvetica, sans-serif: font-size: 14pt: background-color: teal"* <DIV STYLE=’’background-col or: brown: col or: white: padding:4px"> «SPAN STYLE=”font-weight .-bold: color: white">Correlli«/SPAN> - Michelle </DIV> «DIV STYLE-"margin-1 eft:20px; margin-bottom:lem: font-size: lOpt; font-style: bold; color:yellow"> 1824 East 7th Avenue </DIV> <DIV STYLE="margin-left:20px: margin-bottom: lem; font-size: lOpt: font-style: bold; color:yellow"> Suite 700 </DIV> «DIV STYLE="margin-left:20px; margin-bottom:lem; font-size: 12pt: font-style: bold"* Memphis. IN «/DIV* «DIV STYLE="margin-left :20px; margin-bottom: lem: font-size: 14pt: color .-blue"* 32123-7788 «/DIV* «DIV STYLE="background-color: brown; color:white: padding:4px"> «SPAN STYLE="font-weight:bold: color:white">Jaynes</SPAN> Г •’ГС.
XML как язык разметки 599 - Lynda </DlV> <DIV STYLE-"margin-left:20px; margin-bottom: lem: font-size: lOpt: font-style: bold; color:yellow’’> 2 Elm Street </DIV> <DIV STYLE-"margin-left:20px; margin-bottom lem. font-size: 12pt; font-style- bold" > New York City. NY </01V> <DIV STYLE-"margin-left:20px: margin-bottom: lem: font-size: 14pt: color-btue"> 02123-7445 </DIV> </B0DY> </HTML> Программы-обработчики XSLT являются контекстно-ориентированными - каждый оператор выполняется в контексте найденного соответствия шаблону поиска. Так, оператор <xsl :value-of sei ect="name/lastname’'/> действует в контексте вхождения шаблона customerlist/customer, найденного в до- кументе. Нет необходимости писать <xs 1 seiect="customerl1 st/customer/name/1astname"/> поскольку контекст customerlist/customer уже задан. На самом деле, если бы опера- тор select был записан так, то ничего бы не было найдено. Аналогичным образом, поиск <xsl:select="lastname"/> ничего бы не обнаружил, поскольку элемент Lastname появляется только в контексте customerlist/customer/name, но не в контексте customerlist/customer. Эта ориентация на контекст объясняет необходимость в операторе <xsl:value-of select-"node()”/> (в середине таблицы стилей). Этот оператор находится в контексте customerlist/ customer/address/street. Таким образом, текущим узлом (node) является элемент street, и данное выражение предписывает выдать значение этого элемента. Обратите также внимание на то, что таблицей стилей было произведено не- большое преобразование. В исходном документе элемент Lastname следовал за firstname, а в выходном потоке они расположены в обратном порядке. Документ в листинге 13.6 — это XML-документ из листинга 13.4, с которого Мы начинали, но преобразованный в HTML. Материализация этого документа в браузере показана на рис. 13.1. Большинство современных браузеров имеют встроенный обработчик XSLT. Таким образом, достаточно предоставить браузеру документ и таблицу стилей, а он уже сам выполни! преобразование с использованием этой таблицы и авто- матически отобразит результаты, как на рис. 13.1.
600 Глава 13 XML и ADO NET Рис. 13.1. Результат применения таблицы стилей XSLT — вид в браузере XML Schema 1андарт XML Schema используется для определения содержимого и структуры ymtTk°B’ И В ЭТОМ отношении он играет роль, аналогичную DTD. Однако L schema имеет ряд усовершенствований по сравнению с DTD. XML Schema yThTi1 определИ1Ь набор символов и их взаимосвязи. Иногда говорят, что с ema представляет способ создания пользовательских словарей. nnnvrHee ПЫ узнали’ что XML-документ, удовлетворяющий DTD, называется ПО 1ИПУ’ Аналогичным образом, документ, соответствующий XML но птпм азь1вается Допустимым по схеме. XML-документ может быть формаль- В отпии^1М’. ЭТ0М допустимым по типу и по схеме. Schemn 01 е ’ имеЮц1ИХ СВОЙ собственный синтаксис, документы XML ния схемы пы° Се >е являются XML-документами. Это значит, что для определе- ХМТ -nrikvx.p М°Жа.1е использовагь тот же самый синтаксис, что и для других провепят! "Г '° 03начает также, что и сам документ XML Schema можно ....... mrrvJn ОПУС1ИЛ1ОС1Ь по отношению к его схеме. Если вы еще не потеряли ли документы'xML0Schem^Te ЗДеСЬ класснческУю проблему курицы и яйца. Бе- мент ппп-жим ' ета сами являются XML-документами, то какой доку- ДОКУМРИТ использопа,ься в качестве схемы для всех остальных схем? Такой д 1вигельно существует: прародительница всех схем находится на
XML Schema 601 сайте www.w3.org. Все документы XML Schema проверяются на допустимость по отношению к этому документу. XML Schema — обширная и сложная тема. Были написаны десятки книг вну- шительного размера, посвященные одному только этому стандарту. Очевидно, что в рамках этой главы мы не сможем охватить даже самых главных его аспек- тов. Вместо этого мы сосредоточимся на нескольких основных понятиях и идеях и покажем, как эти понятия и идеи используются в обработке баз данных. Имея этот фундамент, вы сможете глубже изучить данную тему самостоятельно. Проверка допустимости по схеме В листинге 13.7 показан простой документ XML Schema, представляющий оди- ночную строку из таблицы ARTIST в базе данных галереи View Ridge. Первая стро- ка указывает, какая схема должна использоваться для проверки допустимости этого документа. Поскольку данный XML-документ является схемой, его допус- тимость необходимо проверять относительно прародительницы всех схем — той схемы, которая находится на сайте www.w3.org. Эта же самая ссылка будет ис- пользоваться во всех схемах, в каждой компании, по всему миру (Между прочим, указанный в ней адрес используется только для целей идентификации. В связи с тем, что данная схема столь широко используется, в большинство программ проверки допустимости по схеме встроена ее копия.) Листинг 13.7. XML-схема Artist <xsd:schema xml ns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="Artist"> <xsd:complexType> <xsd:sequence> <xsd:element name="Name"/> <xsd:element name="National!ty"/> <xsd:element name="B1rthDate" nrin0ccurs=''0'7> <xsd:element name= DeceasedDate" min0ccurs="0'7> </xsd:sequence> <xsd:atri bute name=”ArtStyle"/> </xsd:complexType> </xsd element> </xsd.schema> Первый оператор не только определяет документ, относительно которого будет проверяться допустимость схемы, но и задает помеченное пространство имен. Пространства имен — отдельная сложная тема, и мы нс будем касаться ее в этой главе; объясним только, как используются метки. Итак, первый оператор при по- мощи выражения xmlnstxsd определяет пространство имен (xml name space — про- странство имен XML) с меткой xsd. Обратите внимание, что все остальные строки документа используют эту метку. Выражение xsd:complexType просто предписывает программ- проверки допустимости обратиться к пространству имен xsd (в тай- ном случае определенному в http://www.w3.org/2001/XMLSchema) н найти гам определение элемента complexType.
602 Глава 13. XML и ADO NET Элементы и атрибуты Как можно видеть в лист.е 13.7, схемы состоят из элементов (element) и атри- бутов (attribute). Есть два типа элеменпш простые и сложные Простыеэлементы содержат одиночные значения. В листнш е 13 7 .темен! ы Name, Nationality BirthDate и DeceasedDate являются простыми. По умолчанию кардинальность как простых, так н сложных элементов равна 1.1, то есть требуется ровно одно значение. не больше и нс меньше В схеме из листинга 13 7 выражения mmOccurs-'O указыва- ют, что элементам BirthDate и DeceasedDate присваивается кардинальность отлич- ная от заданной по умолчанию, так что их значения задавать не требуется Эт< аналогично ограничению NULL в определении схемы базы данных в SQL. Сложные элементы (принадлежащие к типу complexType) могут содержать один или несколько простых или сложных элементов. Здесь имеется сложный элемент Artist, все составляющие элементы которого являются простыми Как вы увидите далее, некоторые сложные элементы содержат в себе другие сложные элементы. Кроме того, сложные элементы могут иметь атрибуты. В листинге 13 7 сложный элемент Artist имеет атрибут под названием ArtStyle. Обратите также внимание, что схема в листинге 13.7 определяет не только список элементов, но и их порядок: теги <xsd:sequence>...</xsd:sequence> указывают, что элементы долж- ны следовать в том же порядке, в каком они перечислены в схеме. У вас может возникнуть вопрос, в чем различие между элементом и атрибу- том. Что касается XML-приложений баз данных, практическое правило таково, элементы используются для хранения данных, а атрибуты — для хранения мета- данных. Например, у нас может быть элемент ItemPrice, содержащий цену то- вара, — скажем, 12.50, а у этого элемента может иметься атрибут Currency, опре- деляющий, в какой валюте исчисляется цена — US$, Aus$ или Euro. В нашем примере атрибут ArtStyle содержит данные, характеризующие произведение ху- дожника. В стандарте XML нет ничего, что требовало бы использовать элементы и ат- рибуты именно таким способом. Это вопрос стиля, и в последующих разделах мы покажем, как можно заставить SQL Server помещать значения столбцов только в атрибуты либо только в элементы либо, следуя определенному правилу, по- мещать одни столбцы в атрибуты, а другие — в элементы. Таким образом, эти решения принимаются на основе предпочтений проектировщика, а не какого-ли- оо стандарта XML. Большинство профессионалов согласятся с описанным выше практическим правилом. В листинге 13.8 показан XML-документ, который является допустимым ог- осительно схемы, изображенной в листинге 13.7. Обратите внимание, что зна- ки ие атрибута ArtStyle задается в заголовке элемента Artist. Также обратите внимание, что в документе определено пространство имен xsi. Это пространст- во имен используется лишь один раз — для атрибута noNamespaceSchemaLocation е задумывайтесь, что означает имя этого атрибута: это просто способ сооб- щить синтаксическому анализатору XML, где искать XML-cxeMv для данного документа.
Плоские и структурированные схемы 603 Листинг 13.8. Допустимый по схеме XML-документ Artist <Artist xmlns xsi-"http://www.w3.org/2001/XMLSchema-instance' xsi .nonamespaceSchemaLocation="C:\DB9e\First DraftVChapter 13\ XML DocsXArtistl.xsd” ArtStyle»"Modern"> <Name»Miro«/Name» <Nationality»Spani sh</Nat 1i ona11ty> <BirthDate>1893</BirthOate> «DeceasedDate»1983«/DeceasedDate» </Artist> Плоские и структурированные схемы В листингах 13.9 и 13.10 показаны XML-схема и XML-документ, представляю- щие столбцы таблицы CUSTOMER из базы данных галереи View Ridge. Как видно из листинга 13.9, элементы Country и EmailAddress являются необязательными, а значения остальных элементов должны быть заданы. Документ в листинге 13.10 содержит одну из строк таблицы CUSTOMER. Листинг 13.9. XML-схема документа Customer <xsd schema xmlns xsd-“http://wwvLw3.org/2001/XMLSchema"> <xsd element name="Customer"> «xsd complexType» «xsd sequence» «xsd element name»"Customer ID" type="xsd:int"/> «xsdelement name="Name" type»"xsd.string"/» «xsd element name="Street" type= "xsd:string"/» <xsd element name=”City’ type="xsd.string"/» <xsd element name=’State" type»’xsd:string"/» «xsd element name»"ZipPostalCode" type» xsd:string > «xsd element name»"Country" type="xsd:string minOccurs» 0 > «xsd element name»"AreaCode” type»"xsd:string"/». «xsd element name-'PhoneNumber type» xsd string /> ,,nu/. <x$d element name-"EmailAddress" type»’xsd:string’ minOccurs- </xsd sequence» </xsd complexType» </xsd element» </ztd schema» Листинг 13.10 Допустимый по схеме XML-документ Customer XML Doc$\Art1$tl xsd"> «Custwr 1 (M 000</Customer 10» «Name»Jeffrey Janes«/Name> «Street>123 И Eln St«/Street>
6Q4 Глава 13. XMI и AD0.NET Листинг 13.10 (продолжение) <City*Renton</City* «State*WA«/State> <ZipPostalCode>98123</ZipPostalCode> <AreaCode>206</AreaCode* <PhoneNumber>555 1234</PhoneNunber* «EmailAddress*CustomcrlOOO0somewhere.com</£mai1Address* «/Customer* XML-схем i, подобная топ, которая показан i в липшие 13.9, иногда имы- ваегся плоской, потому что псе ее ............ распола1аю1ся на одном урони< На рис. 13.2 изображена диаграмма, нарисованная ХМ1 редактором, под назва- нием XML Spy. (Болес подробно об лом замечательном продукте, выпускаемом маленькой компанией, которая пока еще не куплена Microsoft или какой-нибудь другой гигантской корпорацией, вы можете узнать на сайте www.xmlspy.com ) Рисунок 13.2 наглядно показывает, почему данная схема называется плоской Обратите также внимание, что необязательные элементы изображены в пунк- тирных прямоугольниках. Рис. 13.2. Графическое представление структуры схемы, построенное программой XMLSpy Если вы внимательно посмотрите на изображенную тдесь схему, то увидите, что определенные аспекты семантики элементов в ней упущены. В частности, все элементы группы {Street, City, State, ZipPostalCode, Country} относятся к теме «адрес». Кроме того, группа элементов {AreaCode, PhoneNumber} относится к теме «телефон». Дело в том, что, как вам известно, в реляционной модели все столб- цы считаются равноправными, поэтому какого-либо способа для представления этих тем не существует. Однако XML позволяет моделщювать такие группы. В схеме, показанной в лис- тинге 13.11, две упомянутые выше группы столбцов образуют сложные типы Address и Phone. XML-документ, в котором одна из строк таблицы CUSTOMER пред- I’t <• f Д’- м*- 4 i '• Г- Л. |(.
Плоские и структурированные схемы 605 ставлена в данном формате, приведен в листинге 13.12. Графическое представле- ние схемы из листинга 13.11 изображено на рис. 13.3. Листинг 13-11. Структурированная схема документа Customer <xsd schema xmlns:xsd="http //www w3 org/2001/XMLSchema” elementFormDefault="qua1i ft ed’> «xsd:element name="Customer"> <xsd.complexType* <xsd:sequence* <xsd:element name="CustomerID" type="xsd:int'7> «xsd:element name="Name" type="xsd:string'7* «xsd:element name="Address" type="xsd:string'7> <xsd:complexType* «xsd:element name="Street" type="xsd:string"/* <xsd:element name="City" type=''xsd:string"/> <xsd:element name=“State“ type="xsd:string"/> «xsdrelement name="Z pPostalCode" type-'xsd string"/* <xsd:element name= Country" type="xsd:string" m n0ccurs=“0'7> </xsd:complexType* «xsd.element* <xsd:element name="Phone" type="xsd:string"/* <xsd:complexType* «xsd.element name="AreaCode" type="xsd.string"/* <xsd:element name=“PhoneNumber" type="xsd:stnng"/* </xsd:complexType> «xsd:element* «xsdelement name=“EmailAddress" type="xsd:string" minOccurs=“0“/> «/xsd.sequence* </xsd.complexType* </xsd:element* </xsd schema* Листинг 13.12. Допустимый по схеме XML-документ Customer «Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xsi:nonamespaceSchemaLocation="C:\0B9e\First DraftXChapter 13\ DocsXArtistl.xsd"* «CustomerID*1000«/CustomerID> <Name*Jeffrey Janes«/Name> «Address* «Street>123 W.Elm St«/Street> «City*Renton«/City> «State*WA«/State> <ZipPostalCode*98123«/Zi pPostalCode* «/Address* «Phone* «AreaCode*206«/AreaCode* «PhoneNumber*555-1234«/PhoneNumber* «EmailAddress*CustomerlOOOPsomewhere.com</EmailAddress* «/Customer*
606 Глава 13 XML и ADO Ni Г Рис. 13.3. Графическое представление структуры схемы из листинга 13.11, построенное программой XML Spy Схемы, подобные этой, называются иногда структурированными, поскольку они организуют столбцы таблицы в виде некоторой структуры. Такая модель не- сет дополнительную смысловую нагрузку для пользователя, поэтому она превос- ходит реляционную модель с описательной точки зрения. Глобальные элементы Допустим, мы хотим с помощью XML Schema определить документ, который, по- мимо данных о клиенте из листинга 13.11, содержал бы также сведения о том, за каким продавцом закреплен этот клиент. Предположим, что адреса и телефоны есть как у клиентов, так и у продавцов. Такую схему можно было бы создать, ис- пользуя описанные выше методы, по в этом случае нам пришлось бы продубли- ровать определения телефона и адреса. В реляционном мире дублирование данных беспокоит нас не столько из-за напрасной траты пространства на физическом носителе, сколько из-за вероятности возникновения несогласованности в данных, когда одна копия данных изменяется, а друтая нет. Аналогичным образом, в мире обработки документов дублирования определений элементов стараются избегать, поскольку всегда есть шанс, что дан- ные станут несогласованными, если изменения не будут внесены синхронно. то ы исключить дублирование определений, элементы можно объявить как 1ло >альные и затем использовать многократно. Например, в листинге 13.13 группа элементов, описывающая адрес, объявлена как глобальный элемент AddressType. I уппа элементов, описывающая телефон, — как глобальный элемент PhoneType. отласно стандарту XML Schema, эти элементы являются глобальными, потому то они располагаются на верхнем уровне схемы. исследова,|Ие листинга 13.13 покажет, что как элемент Customer, так и рЬапотТ Э ®X|3Grson В1|УТРИ него используют глобальные определения AddressType е уре. Ссылки па эти определения выглядят так; type-"AddressType". При
Плоские и структурированные схемы 607 использовании глобальных определений, если PhoneType или AddressType изме- нится, то элементы Customer и Salesperson унаследуют это изменение. Еще одна модификация заключается в том, что кардинальность группы Phone элемента Customer была изменена на 1.3. Это означает, что требуется по меньшей мере одна такая группа, а допускается максимум три. Как вы знаете из главы 2, представление таких многозначных атрибутов в реляционной модели требует введения идентификационно-зависимой сущности. Эта сущность далее преобра- зуется в таблицу в реляционной модели. Мы не будем рассматривать здесь дан- ный вопрос. Эта запись показана только для того, чтобы вы смогли увидеть, как в XML Schema представляются многозначные элементы. На рис. 13.4, а, изображено графическое представление глобального элемента PhoneType в программе XML Spy, а на рис. 13.4, б, показано, как представляется ссылка элементов Customer и Salesperson на элемент PhoneType. name="AddressType"> Листинг 13.13. XML-схема с глобальными элементами <xsd schema xml ns: xsd="http: / /www. w3. org/2001 /XMLSchema" elementFormDefault=”qualified"* <xsd:complexType <xsd:sequence* <xsd:element <xsd:element <xsd:element <xsd:element <xsd:element </xsd:sequence* </xsd:complexType* <xsd:complexType name="PhoneType”* </xsd:sequence* <xsd:element name="AreaCode" type="xsd:string'7> <xsd:element name="PhoneNumber” type=”xsd:string”/* </xsdsequence* </xsd:complexType* <xsd element name=“Customer"> <xsd-complexType* <xsd sequence* <xsd'element <xsd:element <xsd.element <xsd.element <xsd element <xsd element <xsd complexType* <xsd'sequence* <xsd:element name=“Name"/> <xsd element name- <xsd element name' </xsd.sequence* <xsd attribute name-" </xsd:complexType* name="Street" type="xsd:string"/* name="City" type="xsd:string"/> name-"State" type="xsd:stri ng"/> name="ZipPostalCode" type="xsd:string"/> name=“Country" type=”xsd:string'' minOccurs-'O"/* name="CustomerlO'' type- "xsd:integer"/> name="Name'7> name="Address" type=“AddressType7> name="Phone" type-"PhoneType" maxOccurs="3'7* name="EmailAddress" type="xsd:string" minOccurs="O'7> name-“Salesperson"* "Address" type=”AddressType"/* "Phone" type-”PhoneType'7* "SalespersonlD" type-''xsd. string"/*
608 Глава <3. XML >< ADO NET ЛИСТИНГ 13.13 ('XUUUWfMW) xsd element» < xsd.sequence» - xsd compl exType» «- xsd;element» < xsd:schema» Рис. 13.4. Глобальные элементы в программе XML Spy; а — элемент PhoneType, б — представление ссылок на элемент PhoneType Создание XML-документов на основе информации из базы данных Как в Oracle, так и в SQL Server имеются средства для генерации ХМ L-документов на основе содержимого базы данных. В Oracle эти средства требуют использования Java. Поскольку мы не предполагаем наличия у читателя навыков программиро- вания на Java, мы не будем обсуждать здесь этот вопрос. Если вы программируете на Java, вы можете узнать подробнее о средствах работы с XML в Oracle на сайте http://www.oracle.com, (Далее в этой главе мы продемонстрируем, как можно генери- ровать XML-документы из данных в Oracle с использованием ADO.NET. Но в этом случае Oracle поставляет данные в собственном формате, а не в формате XML: преобразование данных в XML осуществляется наборами данных ADO.NET.)
Создание XML-документов на осноае информации из базы данных 609 Средства работы с XML в Oracle и SQL Server быстро эволюционируют ® .Cp/T4cq S^L Server в версию 7.0 было добавлено выражение FOR XML ТО SQL SELECT. Это выражение было унаследовано версией SQL Server 2000. В 2002 году возможности SQL Server были расширены за счет SQLXML - библиотеки клас- сов. которую можно загрузить с сайта msdn.microsoft.com. Эта библиотека, создан- ная группой разработчиков SQL Server, отличается от ADO NET Скорее всего в будущем возможности SQLXML и ADO.NET будут объединены. SELECT...FOR XML Рассмотрим следующий SQL-оператор: SELECT * FROM ARTIST FOR XML RAW: Выражение FOR XML RAW предписывает SQL Server создать XML-документ, в котором непустые столбцы результата запроса будут играть роль атрибутов. В листинге 13.14 приведен пример результата выполнения такого оператора. Как и ожидалось, каждый столбец, значение которого задано, становится атрибутом элемента под названием ARTIST1. Листинг 13.14. Пример использования выражения FOR XML RAW <MyData> «ARTIST ArtistID="3" Name="Miro " Nationality="Spanish " BirthDate="1870" DeceasedDate="1950”/> «ARTIST ArtistID="4" Name="Kandinsky «ARTIST ArtistID=”5" Name="Frings «ARTIST ArtistID-"6" Name="Klee «ARTIST ArtistID="8" Name="Moos " Nationality=“Russian " BirthDate="1854" DeceasedOate-"1900"/> “ Nationality=''US " Birth0ate="1700" DeceasedDate="1800"/> " Nationality="German " BirthDate="1900"/> " Nationality="US ’•/> «ARTIST ArtistID-"14“ Name-"Tobey " Nationality="US “/> «ARTIST ArtistID-"15" Name="Matisse " Nationality="French "/> «ARTIST ArtistID-"16" Name="Chagall " Nationality=“French “/> </MyOata> ....лдела были омлапы VB.NET-приложет^. которое ' ' ' ссгсгт слихм! riwnciiiiMii KTaceaSqlXMLCommand библиотеки SQLXMLh со- кызьимло опера-Юры SELECT...FOR XML < рсдслымп ими» rv»r.,t»TnStr»>am Это поило := =— —— библиотеку XML н и (учите документацию и учебные материалы по mil. 1 Если уж раскрыпать псе, то лиеннпи лого раа
610 Глава 13. XML и ADO.NET Можно заставить SQL Server помещать значения столбцов не в атрибуты, а в элементы XML-документа, как это сделано в листинге 1315 Подобный доку- мент можно создать при помощи следующего оператора: SELECT * FROM ARTIST FOR XML AUTO. ELEMENTS: Листинг 13.15. Пример использования выражения FOR XML AUTO, ELEMENTS «MyData» «ARTIST» <ArtistID»3«/ArtiStID> < Name> Miro «/Name» «Nationality» Spanish </Nationality> < Bi rthDate»lB70«/BirthDate> «DeceasedDate»1950«/DeceasedDate> «/ARTIST» «ARTIST» < Arti stID»4«/Arti stID> «Name» Kandinsky </Name> «Nationality» Russian «/Nationality» «Bi rthDate»lB54«/Bi rthDate» «DeceasedDate»1900«/DeceasedDate> «/ARTIST» «ARTIST» <ArtistID»5«/ArtistID> «Name» Frings «/Name» «Nationality» US «/Nationality» «Bi rthDate»1700«/Bi rthDate» «Decea sedDate»lBOO«/DeceasedDate> «/ARTIST» «ARTIST» <ArtistID»6«/ArtistID> «Name» Klee «/Name» «Nationality» German «/Nationality» «BirthDate»1900«/Bi rthDate» «/ARTIST» «ARTIST» «ArtistID>8«/ArtistID» «Name» Moos «/Name» «Nationality» US «/ARTIST» «ARTIST» «ArtistID»14«/ArtistID> «/Nationality» «Name» Tobey «/Name» «Nationality» US «/ARTIST» «ART ST» «ArtistID»15«/ArtistID> «/Nationality»
Создание XML-документов на основе информации из базы данных 611 «Name* Matisse «Nationality* French «/ARTIST* «ARTIST* «ArtistID*16«/ArtistID* «Name* Chagall «Nationality* French «/ARTIST* «/MyData* «/Name* «/Nationality* «/Name* «/Nationality* Используя выражение FOR XML EXPLICIT, разработчик может указать SQL Server, какие столбцы результата должны играть роль элементов, а какие — атрибутов. Можно, например, сделать так, чтобы значения всех столбцов, кроме суррогатного ключа, помещались в элементы XML-документа, а значения суррогатного ключа — в атрибуты. Обоснование такого решения состоит в том, что значения суррогат- ного ключа не имеют смысла для пользователей, поэтому они больше похожи на метаданные, чем на данные. Описание того, как это сделать, выходит за рамки на- шего обсуждения. Информацию об этом вы найдете в документации по SQL Server. SELECT...FOR XML для нескольких таблиц Возможности оператора SELECT...FOR XML не ограничиваются однотабличными за- просами. Рассмотрим следующий запрос, соединяющий таблицы CUSTOMER и ARTIST: SELECT CUSTOMER.Name. ARTIST Name FROM CUSTOMER. CUSTOMER_ARTIST_INT, ARTIST WHERE CUSTOMER. CustomerlO = CUSTOMER_ARTIST_INT. CustomerlO AND CUSTOMER_ARTIST_INT.ArtistID = ARTI ST. Art 1st ID ORDER BY CUSTOMER.Name FOR XML AUTO. ELEMENTS; Результатом этого запроса будет XML-документ, приведенный в листинге 13.16. Листинг 13.16. Результат запроса FOR XML AUTO, ELEMENTS для таблиц CUSTOMER и ARTIST «MyData xml ns: xs1="http: //www. w3. org/2000/10/XMLSchema -1 nstance" xsi noNamespaceSchemaLocation="C:\DB9e\First draft\Chapter 13\ CustomerArt 1 st I nt. xsd ''* «CUSTOMER* «Name*Chris Wilkens «ARTIST* «Name*Frings «/ARTIST* «ARTIST* <Name*Tobey «/ARTIST* «/CUSTOMER* «CUSTOMER* «/Name* «/Name* «/Name* продолжение^
612 Глава 13. XML и ADO.NET Листинг 13.18 (продолжение) <Name>Donald G.Gray «ARTIST* <Name*Tobey «/ARTIST* «/CUSTOMER* «CUSTOMER* <Name*Fred Smathers «ARTIST* <Name*Tobey «/ARTIST* «/CUSTOMER* «CUSTOMER* <Name*Jeffrey Janes «ARTIST* <Name>Tobey «/ARTIST* «/CUSTOMER* «CUSTOMER* <Name*Lynda Johnson «ARTIST* <Name*Moos «/ARTIST* «ARTIST* <Name*Tobey «/ARTIST* «ARTIST* <Name*Frings «/ARTIST* </CUSTOMER> «CUSTOMER* <Name*Malinda Gliddens «ARTIST* <Name*Chagal1 «/ARTIST* •^/CUSTOMER* •^CUSTOMER* <Name*Mary Beth Frederickson <artist> «Name>Frings </ARTIST> <ARTIST> <Name*Moos </ARTlST> «ARTIST* <Name*Tobey </ARTlST> </CUSTOMER> «/Name* «/Name* «/Name* r «/Name* «/Name* «/Name* «/Name* «/Name* «/Name* </Nanj£> «/Name* «/Name* «/Name* «/Name* </Name> «/Name*
Сокине ю в1з <CUST0MER> <Name>M1chael Bench <ARTIST> <Name>Moos </ARTIST> <ARTIST> <Name>Frings </ARTIST> <ARTIST> <Name>Tobey </ARTIST> </CUST0MER> <CUST0MER> <Name>Selma Warning <ARTIST> <Name>Mi ro </ARTIST> <ARTIST> <Name>Tobey </ARTIST> </CUST0MER> <CUST0MER> <Name>Tiffany Twilight <ARTIST> <Name>Tobey </ARTIST> <ARTIST> <Name>Chagal1 </ARTIST> <ARTIST> <Name>Frings </ARTIST> </CUST0MER> </MyData> </Name> </Name> </Name> </Name> </Name> </Name> </Name> </Name> </Name> </Name> </Name> SQL Server определяет иерархическое положение элементов в создаваемом XML-документе по порядку следования таблиц в предложении FROM. Здесь па верхнем уровне находится элемент CUSTOMER, а на следующем уровне — ARTIST. Таблица CUSTOMER_ARTIST_INT не фигурирует в документе, поскольку ни один столбец этой таблицы не указан в операторе SELECT. С помощью выражения FOR XML AUTD, XMLDATA можно заставить SQL Server выводить перед XML-документом его схему. Однако для понимания полученной таким образом схемы нам пришлось бы затронуть ряд вопросов, которые выхо- дят за рамки этой главы, поэтому мы не будем касаться данной темы. Создать схему для XML-документа можно также с помощью программы XML Spy, ис- пользуя документ в качестве примера. Схема в листинге 13 17 была получена именно таким образом Обратите внимание, что элемент MyData может содержать неограниченное число элементов CUSTOMER, а каждый элемент CUSTOMER может иметь неограниченное число элементов ARTIST — по одному на каждого худож-
Й14 Глава 13. XML и AIX3.NET ______________________________________________ ника которым интересуется клнст Нл рис 13.5 изображено графи----------------- пред ставпенпе »топ схемы. Обозначение I .w показы ннст, чю тр-буп.я но меньшей мерс один элемент CUSTOMER, а допускается шчнраничениос их количе. тио Листинг 13.17. XML-схема, полученная с помощью программы XML Spy <xsd:schema xmlns:xsd-"http //wwww3.org/2001/XMLSchema" elementFormDefault-"qual1 tied"* <xsd:element name-"MyData,,> <xsd:complexType* <xsd:sequence* <xsd:element name="CUSTOMER" maxOccurs-"unbounded"> <xsd:complexType* <xsd:sequence* <xsd element ref="Name"/> <xsd:element name=”ARTIST” max0ccurs""unbounded“* <xsd complexType* <xsd:sequence* <xsd:element ref="Name"/> </xsd-sequence* </xsd:complexType* </xsd element* </xsd;sequence* </xsd:complexType* <xsd:element* </xsd:sequence* </xsd complexType* </xsd:element* <xsd:element name-'Name" type=”xsd:string"/* </xsd:schema* 1 ARTIST E О .«л Рис. 13.5. Графическое представление схемы из листинга 13.17 XML-схема, клиентов описывающая все покупки ках клиентов СОЗДать А°кУмемт, содержащий данные обо всех покуп- WORK и ARTIST м , f “аМ Иеобх°Димо соединить таблицы CUSTOMER, TRANS. ДУ^щий Ж * ИИТСРеСУ1°ЩИе "ас ЭгУ 3^ачу выполнит еле- SELE° Transaction!!). Ss? S [“°RK1 T,t’=- A«T!ST ArtistID.
XML-схема, описывающая все покупки клиентов 615 FROM CUSTOMER. TRANS. [WORK], ARTIST WHERE CUSTOMER.CustomerlD = TRANS.CustomerlD AND TRANS WorkID = [WORK].WorkID AND [WORK],ArtistID = ARTIST.ArtistID ORDER BY CUSTOMER.Name FDR XML AUTO. ELEMENTS: В листинге 13.18 показана схема XML-докумепта, создаваемого приведенным выше запросом. Она была создана программой XML Spy на основе XML-доку- мента, созданного SQL Server. Графическое представление этой схемы изобра- жено на рис. 13.6, а. Листинг 13.18. XML-схема, описывающая все покупки (создана при помощи XML Spy) <!- edited with XML Spy v.3.5 NT (http://www.xmlspy.com) by David Kroenke (private) -> <!- W3C Schema generated by XML Spy v.3.5 NT (http://www.xmlspy com) -> <xsd:schema xml ns :xsd=” "http://www.w3 org/2001/XMLSchema" elementFormDefault="qualified"> <xsd:element name=“MyData"* <xsd:complexType* <xsd:sequence* <xsd:element name=•'CUSTOMER" maxDccurs="unbounded"* <xsd:complexType> <xsd:sequence* <xsd:element ref="Name“/> <xsd.element name="TRANS" min0ccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="Sa1esPri ce" /* <xsd:element name="WORK"> <xsd:complexType> <xsd:sequence* <xsd:element name=''Title" type= xsd.string /* <xsd:element name="Copy" type= xsd:string /> <xsd:element name="ARTIST"> <xsd:complexType> <xsd:sequence* <xsd:element ref="Name'/* </xsd:sequence* </xsd;complexType* </xsd.element* </xsd sequence* </xsd.complexType* </xsd element* </xsd.sequence* </xsdcomplexType* </xsd.element* щмЛояжтис^ </xsd sequence*
616 Глава 13 XML и ADO.NET Листинг 13.18 (продолжение) </xsd:complexType* </xsd:element* </xsd:sequence* </xsd:complexType* </xsd:element* <xsd element name="Name“ type”"xsd:string"/* </xsd.schema* Эта схема близка к истине, но не совсем верпа. В соответствии с ней доку- мент MyData содержит неограниченное (но не меньшее одного) число элементов CUSTOMER, а элемент CUSTOMER — неограниченное (но не меньшее одного) число элементов TRANS. Последнее утверждение не соответствует действительности, согласно нашей модели данных, у клиента может не быть ни одной транзакции, а по схеме требуется по крайней мере одна. Эта ошибка произошла потому, что для построения схемы мы воспользова- лись существующим XML-документом, созданным в результате внутреннего со- единения таблиц CUSTOMER и TRANS. Поскольку соединение было внутренним, в XML-документ вошли данные только о тех клиентах, у которых имеются стро- ки в таблице TRANS. Поэтому вышло так, что у каждого клиента в получившемся документе наличествует по меньшей мере однд строка в таблице TRANS. Если бы для создания XML-документа использовалось не внутреннее, а внешнее соеди- нение, при котором в результат включаются сведения обо всех клиентах, в том числе о тех, у кого нет ни одной транзакции, то в документе встречались бы элементы CUSTOMER, не содержащие ни одного элемента TRANS, и программа XML Spy указала бы правильную кардинальность для элемента TRANS. Нам же, вместо того чтобы переделывать запрос, можно исправить схему непосредствен- но в XML Spy1. Согласно исправленной схеме (рис. 13.6, б), элемент CUSTOMER имеет не огра- ниченное сверху число элементов TRANS, большее или равное нулю. Кардиналь- ности остальных элементов схемы были правильно определены программой XML Spy из нашего XML-документа. Элемент TRANS имеет ровно один элемент WORK, а элемент WORK — ровно один элемент ARTIST. Схема с двумя многозначными маршрутами Предположим теперь, что мы хотим построить XML-документ, содержащий все данные о клиентах галереи View Ridge. Такое представление не может быть по- строено при помощи одного SQL-оператора, потому что в нем содержатся два многозначных маршрута. Необходимо два оператора: один будет извлекать все данные о покупках, а другой — данные об интересе клиентов к различным ху- дожникам. На самом деле точно такая же ошибка имела место при построении схемы па рис. 13.5, описываю- щей объединение таблиц CUSTOMER и ARTIST. Эта ошибка также была исправлена в XML Spv. а здесь приведена правильная версия.
XML-схема, описывающая все покупки клиентов 617 * жгвеешз- i wrm. 8 ТОМ ГТЖЧИКТ & 6 Ж |ШКНиж жжрегпв- Рис. 13.6. Графическое представление схемы из листинга 13.18 а — первоначальная версия; б — версия с исправленной кардинальностью Однако в XML Schema такое ограничение отсутствует. XML-документ может иметь столько многозначных маршрутов, сколько требуется для нужд приложе- ния. В нашем случае все, что требуется сделать, — это объединить схемы из лис- тингов 13.17 и 13 18. Мы можем также добавить суррогатные ключи для каждой таблицы. Результат такого объединения (выполненного путем копирования и вставки if' текста в XML Spy!) показан в листинге 13.19, а его графическое представление — на рис. 13.7. Обратите внимание, что документ MyData на рисунке может содер- жать произвольное (но не меньшее единицы) число элементов CUSTOMER, а каж- дый такой элемент, в свою очередь может иметь неограниченное положительное число элементов TRANS и Artistinterests. Все простые элементы в этой схеме явля- ются обязательными. Листинг 13.19. XML-схема документа с двумя многозначными маршрутами <’- edited with XML Spy v 3 5 NT (http://www xmlspy.com) by David Kroenke (private) -> <'- W3C Schema generated by XML Spy v.3.5 NT (http://www xmlspy com) <xsd schema xmlns.xsd-""http://www.w3.org/2001/XMLSchema" elementFormDefau1t-"qua11fied" > продолжение# ' * ''Tw-i Sl fU JMf. . i :! I ii ji
618 Глава 13. XML и ADO N T Листинг 13.19 (продолжение) <xsd element name="MyData"> <xsd:compI exType* <xsd sequence* <xsd:element name="CUSTOMER" maxOccurs= unbounded > <xsd:complexType* <xsd:sequence* <xsd:element ref="CustomerID" type»“xsd:Integer"/* <xsd:element ref=''Name'7> <xsd:element name="TRANS" minOccurs=”O" maxOccurs=''unbounded"> <xsd:complexType* <xsd:sequence* <xsd:element name=''TransactionID" type="xsd:integer"/* <xsd:element name="SalesPrice"/> <xsd:element name=”W0RK"> <xsd:complexType* <xsd:sequence* <xsd element name="WorkID" type="xsd:integer"/* <xsd:element name="Title" type="xsd:string"/* <xsd:element name-'Copy" type="xsd:string"/* <xsd:element name="ARTIST”> <xsd complexType* <xsd:sequence* <xsd:element name="ArtistIO" type="xsd:integer"/* <xsd:element ref-'Name"/* </xsd:sequence* </xsd:complexType* </xsd:element* </xsdsequence* </xsd.complexType* </xsd:element* </xsd:sequence* </xsd:complexType* </xsd:element* <^Helemei?t !2anie "ArtistInterests" min0ccurs="0” maxOccurs="unbounded"* <xsg:complexType> <xsd:sequence* <xsd:element name=”ArtistIO" type=" <xsd:element ref="Name"/* <xsd:element name="Natiопа1i ty"/> </xsd-sequence* xsd:integer"/* </xsd:complexType* </xsd:element* </xsd;sequence* </xsd:complexType* </xsd:element* </xsd:sequence* </xsd:complexType* </xsd element*
—L'CxeMa °ЛИСЬ|вающая все покупки клиентов 619 Рис. 13.7. Графическое представление схемы из листинга 13.19 Значение XML Теперь вы имеете некоторое представление об XML и связанных с ним стандар- тах. Вы знаете, что XML обеспечивает четкое разделение структуры, содержимо- го и материализации. Структура определяется DTD или XML-схемой. Содержи- мое находится в ХМ L-документе, а материализация определяется таблицей стилей XSLT. Также вам известно, что для создания XML-документов можно ис- пользовать операторы SQL, но только в том случае, если документ содержит не более одного многозначного маршрута, иначе для заполнения его данными по- требуется несколько SQL-операторов. У вас может возникнуть вопрос: все эти идеи чрезвычайно интересны, но ка- ково их значение? Что такого важного они в себе содержат? Ответ заключается в том, что XML предоставляет стандартизированный способ описания, проверки и материализации произвольного представления базы данных. Вернемся к галерее View Ridge. Допустим, галерея хочет поделиться данны- ми о своих клиентах с другой галереей — например, в связи с программой со- вместных продаж. Если обе галереи договорятся об использовании XML-схемы, подобной той, что приведена в листинге 13.19, они могут подготовить док\ менты с данными о клиентах в соответствии с этой схемой. Прежде чем отправить документ, необходимо выполнить автоматическую процедуру проверки его до- пустимости по схеме Это гарантирует, что будут отправлены только корректные данные. Разумеется, этот процесс работает в обоих направлениях- галерея View Ridge проверяет не только исходящие, но и входящие документы, чтобы удосто- вериться, что принимаемые ею документы являются допустимыми. Самое замечательное, что программы проверки допустимости по схеме явля- ются общедоступными и бесплатными для галере! так что галереям не придется писать для этою собственную программу. Кроме Чою, каждая галерея может разработать свой собственный набор таблиц стилей XSLT для материализации документов в любой желаемой форме. Одна таблица стилей может п|я.*Л№1 ш еииься для отображения данных на компьютерах клиентов, другая и i компьютерах продавцов, 1ретья - на мобильных устройст нах клиентов, когда они находя гея и дороге, и i »к далее. Благодаря этому данные будут отображаться одинаково ине зависимости от тою на какой галереи они взяты.
620 Глава 13. XML и ADO.NET Теперь распространим эту идею па целую отрасль бизнеса. Предположим что индустрия недвижимости установила единую XML-схему для документов, содер. жащих перечень имущества в доме. Каждое агеитспю недвижимости, способное создавать документы согласно этой схеме, получит возможность обмениваться перечнями имущества со всеми остальными такими агентствами. С помощью этой схемы каждая компания может удостовериться, что все исходящие и входя щие документы являются допустимыми. Более того, каждое aieiircTBo может разработать свой собственный набор таблиц стилей XSLT для материализации документов в любой желаемой форме. Имея такие таблицы стилей, любое агент- ство сможет материализовать в удобном для себя виде перечень имущества, полученный от любого агента. В табл. 13.1 перечислены некоторые стандарты XML, разрабатываемые различными отраслями. Таблица 13.1. Некоторые отраслевые стандарты XML Отрасль производства Примеры стандартов Бухгалтерский учет Архитектура и строительство Автомобильная промышленность Банковское дело Электронный обмен данными Кадровые ресурсы American Institute of Certified Public Accountants (AICPA): Extensible Reporting Markup Language (XFRML) [Первая страница OASIS] Open Applications Group (OAG) Architecture, Engineering and Construction XML Working Group (aecXML Working Group) ConSource.com: Construction Manufacturing and Distribution Extensible Markup Language (cmdXML) Automotive Industry Action Group (AIAG) Global Automedia MSB: Standards for information interchange in the engineering process (MEDOC) The Society of Automotive Engineers (SAE): XML for the Automotive Industry — SAE J2008 [Первая страница OASIS] Banking Industry Technology Secretariat (BITS): [Первая страница OASIS] Financial Services Technology Consortium (FSTC): Bank Internet Payment System (BIPS) [Первая страница OASIS] Open Applications Group, Inc (OAG) Data Interchange Standards Association (DISA): [Первая страница OASIS] EEMA EDI/EC Work Group [Первая страница OASIS] European Committee for Standartization / Information Society Standartization System (CEN/ISSS; The European XML/EDI Pilot Project [Первая страница OASIS]) XML/EDI Group [Первая страница OASIS] DataMain: Human Resources Markup Language HR-XML Consortium [Первая страница OASIS]: JobPosting, Candidateprofile, Resume Open Applications Group (OAG): Open Applications Group Interface Specification (OASIS) [Первая страница OASIS] Tapestry.Net: JOB markup language (JOB) Open Applications Group, Inc (OAG)
XML-схема, описывающая все покупки клиентов 621 Отрасль Примеры стандартов — производства Страхование rrb2RD' Property and Casualty [Первая страница OASIS], Life (XMLife) [Первая страница OASIS] J 1лмите) Lexica: iLingo Недвижимость страница :OASIS?,a,e Mana0ement Sys,em (OpenMLS) [Первая 4)Tn^’XS,andardS W°rking GrOup (RETS): Real Estate Transa tion Standard [Первая страница OASIS] Программное обеспечение IBM: [Первая страница OASIS] Flashline.com: Software Component Documentation DTD Flashline.com: INRIA: Koala Bean Markup Language (KBML) [Первая страница OASIS] Marimba и Microsoft’ Open Software Description Format (OSD) [Пеовая страница OASIS] H Object Management Group: [Первая страница OASIS] Автоматическое управление технологическим процессом Internet Engineering task Force (IETF): Simple Workflow Access Protocol (SWAP) [Первая страница OASIS] Workf ow Management Coalition (MfMC): Wf-XML [Первая страница OASIS] Теперь рассмотрим другой пример — электронную коммерцию. Предполо- жим, сеть супермаркетов Wal-Mart хочет рассылать заказы своим поставщи- кам в виде документов определенного формата и получать извещения о до- ставке товаров также в определенном стандартном формате. Для этого Wal-Mart разрабатывает две XML-схемы: одну для заказов, другую для поставок. Эти схемы публикуются на сайте, к которому поставщики имеют доступ. Таким образом, все поставщики смогут определить, в каком формате они будут по- лучать заказы от Wal-Mart и в каком формате им следует отправлять извещения о доставке. Эти схемы могут также использоваться поставщиками и Wal-Mart для про- верки допустимости отправляемых и принимаемых XML-докуменгов. Более то- го, Wal-Mart может разработать набор таблиц стилей XSLT для преобразования заказов и извещений о поставке в различные форматы, требуемые бухгалтерией, операционным отделом, отделом маркетинга и высшим менеджментом. Эти таб- лицы стилей будут работать с любым заказом или извещением о доставке от лю- бого поставщика. Все эти примеры объединяет следующее: после того как подготовлены XML- схемы и таблицы стилей XSLT, все операции по проверке допустимости и мате- риализации документов выполняются автоматически. Соответственно, отпадает потребность в каком-либо человеческом вмешательстве с момента, когда заказ вы- писывается в Wal-Mart, до момента, когда он принимается на складе поставщика. Таким образом, последнее, с чем нам остается разобраться, это заполнение XML-документов информацией из базы данных в соответстви с актуальной XML- схемой. Можно использовать для этого SQL, но только в том случае, если схема документа содержит не более одного многозначного маршрута, а это слишком
622 Глава 13 XML и ADO NET большое ограничение. Необходимо нечто большее какая-то новая технология которая бы упростила преобразование информации, содержащейся в базе дан ных, в XML-документы, и наоборот - нлилеченис ин<]к>рмации из XML-дою мента н запись ее в базу данных. Такая техношн ия существует, и называется он ADO.NET. ADO.NET ADO NET — это новая, усовершенствованная и значительно расширенная вер- сия ADO, разработанная Microsoft в рамках инициативы .NET. Она включает в себя функциональность ADO и OLE DB, которые обсуждались в главе 12, но помимо этого содержит еще множество интересных возможностей. В частности, ADO.NET упрощает преобразование X ML-доку ментов в конструкции реляцион- ной базы данных и наоборот. Кроме того, ADO.NET предоставляет возможность создавать и обрабатывать базы данных, целиком располагающиеся в оперативной памяти. Такие базы данных носят название наборов данных (datasets). Роль ADO.NET в обработке баз данных поясняет рис. 13.8. Как можно ви- деть, ADO.NET служит в качестве посредника между всеми типами приложений .NET и СУБД с базой данных. ADO.NET может работать с любой OLE DB-со- вместимой СУБД, и существуют специальные высокопроизводительные драй- веры для SQL Server и Oracle. Рис. 13.8. Роль ADO.NET Поставщик данных ADO.NET — это библиотека классов, предоставляющая услуги ADO.NET. Как показано на рис. 13.9, в настоящий момент имеются три поставщика данных, предоставляемых Microsoft. Поставщик данных OLE DB может использоваться для обработки посредством ADO.NET любого OLE совместимого источника данных. Поставщик данных SQLClient предназначен специально для обработки баз данных SQL Server, а поставщик OracleClient для обработки баз данных Oracle. Все эти поставщики данных разработаны Microsoft. Однако информа необходимая организациям для создания поставщиков данных, находится в от крытом доступе. Не исключено, что к моменту, когда вы будете читать эту глав- будут существовать поставщики данных от Oracle Corporation, IBM и друг” компаний.
ADO NET 623 Поставщики данных .NET: •OLE DB •SQLCIient •OracleClient •Прочие Рис. 13.9. Компоненты поставщика данных ADO.NET На рис. 13.9 показаны основные компоненты поставщика данных ADO.NET. Объект Connection, представляющий соединение, аналогичен одноименному объ- екту ADO, обсуждавшемуся в главе 12, за тем исключением, что источником данных не является ODBC. Вместо этого, как вы увидите позже, указывается имя поставщика данных и базы данных. После установления соединения создается объект Command (команда), при- надлежащий этому соединению. Считыватель данных (data reader) обеспечивает быстрый последовательный доступ к базе данных только для чтения. Считыватели данных используются в тех приложениях, потребности которых сводятся только к последовательному запросу данных Помимо выполнения запросов с помо- щью считывателя, приложение также может читать информацию и записы- вать ее в базу данных, используя объект Command аналогично тому, как делалось в главе 12. Эта возможность представлена на рисунке двунаправленной стрелкой в середине объекта Command. Таким же образом можно вызывать и хранимые процедуры. Хотя эти возможности ADO.NET являются важными, они представляют со- бой лишь расширения и дополнения существующих возможностей и функций ADO. То, что действительно отличает ADO.NET от старых технологий доступа к данным, — это набор данных — компонент, который мы рассмотрим в следую- щем разделе. Именно набор данных предоставляет возможности, необходимые для преобразования информации из базы данных в XML-документы и наоборот. Набор данных ADO.NET Набор данных (dataset) - эго база данных, целиком располагающаяся в опера- тинной памяти. Наборы данных обладают всеми характеристиками, возможно* стями и функциями, присущими обычным базам данных. Они могут содержать
624 Глава 13 XML и ADO.NET множество таблиц, эти таблицы могут имст ь связи. Таблицы в набо,« данных ио- гут иметь внешние ключи, для них также актуально понятие ссылочной целост ности и могут быть определены процедуры се обеспечения. I аблины могут Иметь суррогатные ключи, значение которым будет присваивать ADO NLГ, а не СУБД. Столбцы таблиц набора данных могут быть определены как уникальные Связи между таблицами в наборе данных могут обрабатываться точно так же, как и связи в обычной базе данных. Пример использования связи для вычисле- ния значения столбца вы увидите далее в этой главе. Таблицы набора данных могут иметь представления. Данные, содержащиеся в наборе данных, не связаны с какой-либо обычной базой данных. Для заполнения набора данных не требуется предварительно за- писывать информацию в обычную базу данных. Более того, если информация, содержащаяся в наборе данных, была ранее считана из базы данных, то в даль- нейшем эта информация не синхронизируется с исходной базой данных. Набор данных является независимой полнофункциональной базой данных, работаю- щей в оперативной памяти. Информация, содержащаяся в наборе данных, может быть получена из различных баз данных, обрабатываемых разными СУБД. После того как набор данных построен, его содержимое может быть отформа- тировано в виде XML-документа одной командой. Точно так же одной командой можно создать XML-схему для набора данных. Этот процесс работает и в обрат- ном направлении. С помощью XML-схемы можно создать структуру набора дан- ных, а заполнить ее можно, считывая данные из XML-документа. У вас может возникнуть вопрос: а зачем все это нужно? Для чего нужны базы данных в оперативной памяти? Ответ заключается в представлениях баз данных, подобных тому, что изображено на рис. 13.7. Не существует стандартизирован- ного способа описания и обработки таких структур данных. Поскольку данное представление содержит два многозначных маршрута, проходящих по схеме базы данных, для его описания не может использоваться SQL. Чтобы получить пред- ставление, нам необходимо выполнить два SQL-оператора, после чего опреде- ленным образом исправить результаты. Средства для обработки подобных представлений существовали в течение многих лет, но все они являлись чьей-то собственностью и использовались для частных нужд. Всякий раз, когда возникала необходимость в обработке такой структуры, разрабатывались специальные программы для создания и манипу- лирования данными в памяти и для сохранения их в базе данных. В некоторых слу 1аях программисты определяли для этой структуры данных объектный класс и создавали методы, позволяющие сериализовать объекты этого класса в базу данных, омимо ООП, использовались и другие методы. Так или иначе, пробле- ма заключалась в том, что каждое новое представление требовало разработки но- вого метода, позволяющего его обрабатывать. Корпорация Microsoft приступила к разработке технологии .NET, когда стало ясно, что нео ходимо разработать обобщенный способ определения и обработки сложных представлений баз данных и подобных им структур. Можно было бы
I «ТО нужны базы t.. у саз ^ных _____________2£работка сведений о клиентах в базе данных View Ridge 625 разработать для этой цели новую патентованную технологию, но, к счастью Microsoft поступила иначе, осознав, что идеи, методы и средства, используемые для обработки обычных баз данных, применимы и для баз данных, функциони- рующих в памяти. Для вас выгода здесь состоит в том, что все изученные вами ранее идеи и методы, связанные с обработкой обычных баз данных, можно ис- пользовать для обработки наборов данных. Наборы данных имеют один недостаток, и для некоторых приложений он является весьма существенным. Поскольку набор данных отделен от исходной базы данных, при работе с ним можно использовать только оптимистическую блокировку. Информация считывается из базы данных, записывается в набор данных и далее обрабатывается там. Не делается никаких попыток распростра- нить изменения, сделанные в наборе данных, на исходную базу данных. Если после обработки приложение захочет сохранить всю информацию из набора данных в обычной базе данных, ему необходимо будет использовать оптими- стическую блокировку. Если какое-то другое приложение изменило данные, необходимо будет либо повторно обработать набор данных, либо принудительно записать его содержимое в базу данных, что приведет к проблеме потерянного обновления. Таким образом, наборы данных не могут использоваться для приложений, в которых оптимистическая блокировка является проблематичной. Для таких приложений следует пользоваться объектом Command. Если же конфликт в при- ложении маловероятен или допустима повторная обработка данных после кон- фликта, то в этом случае наборы данных предоставляют значительные преиму- щества. 00" & Обработка сведений о клиентах в базе данных View Ridge с помощью ADO.NET В оставшейся части этой главы рассматривается приложение isual Basic.NET, создающее набор данных для представления, показанного на рис. 13.7. VB.NET - это объектно-ориентированный язык программирования. Если вы еще не знако мы с объектно-ориентированным программированием, вам придется приложить усилия и понять приведенные здесь примеры, насколько вы это можете. Смысл большинства примеров можно интуитивно уяснить, даже если вам непонятен синтаксис. _ , (Обратите, однако, внимание: ранее мы упомянули, что возможности Oracle по обработке XML доступны только при использовании Java, a Java являет- ся объектно-ориентированным языком программирования. Более того, работа с ADO.NET возможна только при использовании одного из языков .NE1. кото- рые, подобно VB.NET, являются объектно-ориентированными. 1аким оОразом, если вы еще не знакомы с объектно-ориентированным проектированием и про- граммированием, но хотите работать с базами данных будущего, то вам лучше не откладывая приступить к изучению этой темы!) -
626 Глава 13. XML И ADO NET Назначение приложения Назначение этого приложения состош в гом, чгобы п|юдемоис|рировлть созда ине и обработку набора данных. Это ASP NI Т приложение < издает веб страницу и строит набор данных из няш таблиц базы данных View Ridge. Приложение считывает все сведения об одном из клиентов (здесь Си огпегЮ клисл ный 1015, жестко закодирован в приложении). После того как набор данных будет заполнен, пользователь может отобразить на веб-странице содержимое его таблиц, отобразить весь набор данных в виде XML-документа или отобразить его структуру в виде XML-схемы Кроме того, пользователь может с помощью приложения исследовать все транзакции данного клиента: если в какой-либо транзакции цена продажи мень- ше запрашиваемой цены, пользователь может установить цену продажи равной запрашиваемой цене. Наконец, измененная информация из набора данных запи- сывается обратно в базу данных. Создается журнал операций с данными, кото- рый позволит нам увидеть, как набор данных отслеживает изменения. В следующих разделах мы рассмотрим представляющие важность фрагменты кода приложения. Цель, однако, заключается не в том, чтобы вы уяснили себе работу данного конкретного приложения, а в том, чтобы вы поняли идеи, лежащие в основе наборов данных, и связь между наборами данных, базами данных и XML Установка соединения и заполнение набора данных В листинге 13.20 показан фрагмент кода, который импортирует необходимые библиотеки классов, определяет переменные, используемые во всем приложении, и начинает обработку. Этот фрагмент входит в состав VB-модуля DataSetElements. содержащего подпрограммы обработки веб-страницы. Остальные процедуры это- го модуля будут показаны в ходе дальнейшего обсуждения. Листинг 13.20. Создание набора данных, соединения и адаптера данных Imports System.Data Imports System Data.OracleClient ' используем поставщик данных OracleClient Module DataSetElements Public drdransRows As DataRowO Public drTransRow As DataRow Public dtUpdatedRows As DataTable Public intCustomerlD As Integer Public dsCustomerView As DataSet Public conViewRidge As OracleConnection Public daViewRidge As DracleDataAdapter
------------^Обработка сведений о клиентах в базе данных View Ridge 627 Public Sub ConstructDataSetO ’ создаем набор данных и устанавливаем соединение с базой данных Oracle dsCustomerView = New DataSetO = SSPi»)COnVieWR1d9e = №W 0racleConnectlon("Data Source=VRG: Integrated Security создаем экземпляр адаптера данных настраиваем команду SELECT ниже daViewRidge = New OracleDataAdapterC”. convlewRIdge) End Sub Работа приложения начинается с подпрограммы ConstructDataSet, которая вы- зывается при загрузке веб-страницы (не показана). Она создает новые экземпля- ры объектов DataSet и Connection и сохраняет их в переменных dsCustomerView и conViewRidge соответственно. Соединение устанавливается с базой данных Oracle под названием VRG, при этом используются интегрированные средства безопасности. Показанный здесь формат строки соединения может использовать- ся в тех случаях, когда Oracle работает на той же машине, что и веб-сервер с ба- зой данных. Кроме того, использование интегрированных средств безопасности означает, что идентификационные данные пользователя предоставляются опе- рационной системой (в данном случае Windows ХР Professional)1. Последний оператор подпрограммы создает экземпляр объекта OracleDataAdapter (адаптер дан- ных Oracle) в переменной daViewRidge. Обратите внимание, что адаптер данных использует соединение (объект Connection), а не набор данных (объект Dataset). Таким образом, один и тот же адаптер данных может при необходимости исполь- зоваться с разными наборами данных. В данном приложении мы будем работать только с одним набором данных — dsCustomerView. Далее веб-страница вызывает подпрограмму FillDataSet, показанную в лис- тинге 13.21. Эта программа заполняет таблицы набора данных с помощью адап- тера данных. Текст соответствующей команды SQL записывается в свойство SelectCommand объекта Dataset с помощью строковой переменной. Затем вызы- вается метод FillSchema объекта OracleDataAdapter, записывающий метаданные XML-схемы результата выполнения команды в новую таблицу под названием CustomerAlias. После этого вызывается метод Fill объекта OracleDataAdapter, кото- рый сохраняет результаты выполнения команды в наборе данных. 1 По умолчанию ASP.NET соединяется с СУБД, используя нмя пользователя ASPNET. Как вы по- мните из главы 10. Oracle требует, чтобы нмя пользователя идентифицируемого средствами опера- ционной системы, на'..а юсь с символов OPSS. Таким образом, чтобы наше приложение сч огло работать, ж об одимо, чтобы в базе данных VRG была учетная запись с именем OPSJASPNET н эта учетная миш ь холжпа иметь достаточные привилегии для того чтоб, I читать и обновлять тлОпицы View Ridge Вмесю loro чтобы использован, задаваемое ио умолчанию имя пользователя ASPNET, вы можете вас пшмп» ASfcNET передана и. Oracle идентификационные данные пользователя. Дан- ный метод, однако, выходи! ла рамки нашего обсуждения. < H1.J1г':ид П'Лй «С’Л-;
628 Глава 13 XML и ADO.NET Листинг 13.21. Использование адаптера данных для заполнения таблиц на^^за Public Sub Fill DataSetО Dim strSQLCommand As String ' Заполняем таблицу CustomerAlias набора данных ' информацией из таблицы CUSTOMER базы данных View Ridge ’ Сначала получаем инфомацию о схеме, а потом сами данные strSQLCommand = "Select * from SYSTEM.CUSTOMER where CustomerlD • " & Str(intCustomerlD) daViewRidge.SelectCommand.CommandText = strSQLCommand daVi ewRidge Fi11 Schema(dsCustomerView. SchemaType.Mapped "CustomerAlias”) daViewRidge.Fill(dsCustomerView. "CustomerAlias") ' Заполняем таблицу Intersect!onAlias набора данных ' информацией из таблицы CUSTOMER_ARTIST_INT базы данных View Ridge strSQLCommand = "Select * from SYSTEM.CUSTOMER_ARTIST_INT where CustomerlD = " & Str(intCustomerlD) daVi ewRidge.Sei ectCommand.CommandText = strSQLCommand daViewRidge.Fi11 Schema(dsCustomerView. SchemaType.Mapped, "Intersect!onAl ias”) daViewRidge.Fill (dsCustomerView, “IntersectionAlTas") ' Заполняем таблицу TransactionAlias набора данных ' информацией из таблицы TRANSACTION базы данных View Ridge strSQLCommand = "Select * from SYSTEM.TRANSACTION where CustomerlD = " & Str(intCustomerlD) daViewRidge.Sei ectCommand.CommandText = strSQLCommand daViewRidge.FillSchema(dsCustomerVi ew. SchemaType.Mapped. "TransactionAlias") daViewRidge Fill(dsCustomerView. "TransactionAlias") ' Считываем строки таблицы WORK strSQLCommand = "Select * from SYSTEM.WORK where WorkID IN " _ & "(Select WorkID from SYSTEM.TRANSACTION WHERE CustomerlD = & Str(intCustomerlD) & ”)" daViewRidge Sei ectCommand.CommandText = strSQLCommand daViewRidge.Fi11 Schema(dsCustomerView. SchemaType.Mapped, "WorkAlias") daViewRidge.Fi11(dsCustomerVi ew. "WorkAlias") Считываем строки таблицы ARTIST через таблицу пересечения strSQLCommand = "Select * from SYSTEM.ARTIST where ArtistID IN " _ 8 "(Select ArtistID from SYSTEM.CUSTOMER_ARTIST_INT WHERE CustomerlD = 8 Str(intCustomerlD) & ")" daViewRidge.Sei ectCommand.CommandText = strSQLCommand daViewRidge.Ft 11 Schema(dsCustomerView SchemaType Mapped "ArtistAlias daViewRidge Fill(dsCustomerView. "ArtistAlias") Считываем строки таблицы ARTIST, на которые нет ссылки ' в таблице пересечения strSQLCommand = "Select * from SYSTEM.ARTIST A where A.ArtistID IN " _ 8 "(Select W.ArtistID from SYSTEM WORK W Join SYSTEM.TRANSACTION T _
Обработка сведений о клиентах в базе данных V,ew Ridge 629 ? = W WOrkID Jo1n SYSTEM CUST0MER c ON T.CustomerlD = Lr > Luo LUI I It-1 1U & "AND C.CustomerlD = ” & Str(lntCustomerlD) & ") " & 'AND NOT EXISTS (Select * from SYSTEM.CUSTOMER ARTIST INT I " & ''WHERE I.ArtistID = A.ArtistID " ~ ~ & "AND I.CustomerlD = " & Str(lntCustomerlD) & ")" daViewRidge.Sei ectCommand.CommandText = strSQLCommand daViewRidge F111Schema(dsCustomerView. SchemaType Mapped. "ArtistAlias") daViewRidge.Fill(dsCustomerView. "ArtlstAllas") End Sub Для определения того, какие строки следует считывать, оператор SELECT ис- пользует значение целочисленной открытой переменной intCustomerlD. В данном приложении подпрограмма загрузки формы, вызываемая перед FillDataSet, при- сваивает этой переменной значение 1015. Таким образом, в набор данных будут считаны только сведения о клиенте с CustomerlD = 1015. Разумеется, если изме- нить значение этой переменной, можно получить данные и о других клиентах. В данном приложении имена всех таблиц базы данных Oracle должны пред- варяться ключевым словом SYSTEM - например, SELECT * FROM SYSTEM.CUSTOMER. Это необходимо потому, что таблицы были созданы под учетной записью SYSTEM, а обрабатываться они будут учетной записью OPSSASPN ЕТ, как объяснялось ранее. Кроме того, все таблицы набора данных, кроме одной, имеют те же самые имена, что и соответствующие таблицы исходной базы данных, с добавлением суффик- са Alias. Например, таблица CUSTOMER носит в наборе данных имя CustomerAlias. Исключением из этого правила является таблица пересечения CUSTOMER_ARTIST_ INT, которой в наборе данных соответствует таблица IntersectionAlias. Единственной достойной упоминания особенностью этой подпрограммы явля- ются SQL-операторы, используемые для получения данных из таблицы ARTIST. Их два: первый считывает все строки, на которые ссылается таблица пересе- чения, а второй — все строки, указанные в таблице WORK, но не фигурирующие в таблице пересечения. Теперь все данные о клиенте, CustomerlD которого равен значению пере- менной intCustomerlD, считаны в набор данных. Кроме того, в набор данных помещены все метаданные таблиц, полученные от Oracle поставщиком данных OracleClient. Добавление новых структур в набор данных Следующая серия подпрограмм добавляет в набор данных новые структуры. В листинге 13.22 приведен текст процедуры Build Relationships, которая определя- ет связи между таблицами. Для этого используется метод Add принадлежащего набору данных класса Relationship. В каждом случае методу Add передаются в ка- честве параметров имя связи, имя ключа родительской таблицы и имя внешнего
630 Глава 13. XML и ADO.NET ключа в дочерней таблице. Создаваемые здесь спя ш можно использовать для об- работки таблиц набора данных. 11апример, имея < i року в таблице WorkAlias через связь можно пай i n соответствующую строку и родительской (аблице ArtistAlias пузнать, какой художник является автором данного нрои.шедсиия Аналогичным образом, имея строку в таблице ArtistAlias, можно пайтн все связанные с ней стро- ки в дочерней таблице WorkAlias н узнать, какие произведения были созданы дан- ным художником. Листинг 13.22. Построение связей Public Sub BuildRelationships!) ' Создаем связи dsCustomerView.Relations.Add("CustomerTransactionRel“. dsCustomerView.Tables!"CustomerAl ias").Columns("CustomerlD”). dsCustomerView. Tables! "TransactionAlias") .Col umns ("CustomerlD")) dsCustomerView.Relations.AddC'WorkTransRel ”. dsCustomerView.Tables!"WorkAlias").Columns("Work ID"). dsCustomerView.Tables!"Transact!onAlias").Columns("Work ID")) dsCustomerView.Relations Add!"Art!stWorkRel". dsCustomerView.Tables("Arti stAli as").Col umns("ArtistID"). dsCustomerView.TablesC'WorkAlias") .ColumnsC'ArtistID")) dsCustomerView.Relations.Add("CustomerlntRel“. _ dsCustomerView.TablesC'CustomerAlias").Columns("CustomerlD"). dsCustomerView.Tables("IntersectionAl ias").Col umns("CustomerlD”)) dsCustomerView.Rel ations.Add("ArtistlntRel". dsCustomerView.Tables!"ArtistAlias").Columns!"ArtistID"). _ dsCustomerView.Tables!"IntersectionAlias").Columns!"ArtistID”)) End Sub Ограничения ссылочной целостности для связей устанавливаются в подпро- грамме, изображенной в листинге 13.23. В каждом случае указываются роди- тельская и дочерняя таблицы, и для каждого ограничения создается экземпляр объекта ForeignKeyConstraint. Объект ForeignKeyConstraint имеет свойства DeleteRule и UpdateRule. Задавая значения этих свойств, можно определять поведение вне- шнею ключа при удалении или обновлении ключей родителя. Эти свойства имеют четыре возможных значения: {None, Cascade, Set Null, Set Default) (нет, каскадное обновление/удаление, пустое значение, значение по умолчанию) — те же вари- анты, которые имеются в модели IDEF1X, рассматривавшейся в главе 2 Здесь мы устанавливаем значения этих свойств в соответствии с ограничениями ссы- лочной целостности базы данных Oracle.
Обработка сведений о клиентах в базе данных View Ridge ( Листинг 13.23. Создание ограничений ссылочной целостности Sub CreateRefIntegrityConstraints() ' Создаем ограничения Dim dtParent As DataTable Dim dtChild As DataTable Dim fkConstraint As ForeignKeyConstraint dtParent - dsCustomerView.TablesC'ArtistAlias") dtChild = dsCustomerView.TablesC’WorkAlias") fkConstraint = New ForeignKeyConstraint _ ("WorkFK”. dtParent. Col umns ("Arti st ID"). dtChi Id.Col wins! "Arti stID")) fkConstraint.DeleteRule = Rule.None fkConstraint.UpdateRule = Rule.None dtParent = dsCustomerView.TablesCWorkAlias”) dtChild = dsCustomerView Tables!"TransactionAlias") fkConstraint = New ForeignKeyConstraint _ ("WorkTransFK", dtParent.Columns(“WorkID"). dtChi 1 d.Columns!"WorkID")) fkConstraint.DeleteRule = Rule.None fkConstraint.UpdateRule = Rule.None dtParent = dsCustomerView.Tables("CustomerAlias") dtChild = dsCustomerView.Tables!"Transact!onAlias") fkConstraint = New ForeignKeyConstraint _ ("CustomerTransFK”. dtParent.Columns("CustomerlO"). dtChi1d.Columns("CustomerlO")) fkConstraint.DeleteRule = Rule.None fkConstraint.UpdateRule = Rule.None dtParent - dsCustomerView.Tables("CustomerAlias") dtChild = dsCustomerView.TablesCIntersectionAlias") fkConstraint = New ForeignKeyConstraint _ ("CustomerArtistFK". dtParent.Columns(“CustomerlO"). dtChild ColumnsCCustomerlD")) fkConstraint DeleteRule = Rule.Cascade fkConstraint UpdateRule “ Rule.Cascade dtParent “ dsCustomerView TablesC'ArtistAlias ) dtChild - dsCustomerView TablesCIntersectionAlias ) fkConstraint - New ForeignKeyConstraint _ ("ArtlstCustomerFK". dtParent Columns!"ArtistID"). dtChild Columns("ArtistID")) fkConstraint DeleteRule • Rule.Cascade fkConstraint UpdateRule - Rule Cascade
632 Глава 13. XML и ADO.NET Наконец, вызывается подпрограмма AddDataColumn (лишни 13 24), которая создает новый столбец в таблице CustomerAlias. Новый столбец будет (одержать сумму значений столбца SalesPrice во всех строках таблицы TransactionAlias, свя занных с данной строкой таблицы CustomerAlias. Обратите внимание на го, как используется объект-связь CustomerTransactionRel для нахождения строк таблицы TRANSACTION. Листинг 13.24. Добавление вычисляемого столбца в таблицу набора данных Sub AddDataColumnО Dim tCol As DataColumn ’ Создаем новый столбец Total Purchases и устанавливаем его ' равным сумме значений столбца SalesPrice в дочерних строках tCol = New DataColumnl"Total Purchases". GetType(Int32)) tCol.Expression = "Sum (ChildlCustomerTransactionRel).SalesPrice)" dsCustomerView.Tables("CustomerAli as”) Columns.Add(tCol) End Sub Имейте в виду, что набор данных и все созданные здесь структуры находятся в оперативной памяти. Мы создали миниатюрную базу данных, но в памяти, а не на диске. Кроме того, информация в наборе данных не синхронизируется с исход- ной базой данных. Если нужно, мы можем закрыть соединение, уничтожив объ- ект Connection, и независимо обрабатывать набор данных без всяких трудностей. Обработка набора данных В наборы данных встроены возможности, облегчающие их обработку. В листин- ге 13.25 приведен текст процедуры на VB.NET, отображающей данные в виде табли- цы на веб-странице. Все, что нужно сделать, — это установить свойство DataSource объекта Grid так, чтобы оно указывало на набор данных, а в свойство DataMember записать имя таблицы набора данных, информацию из которой необходимо ото- бразить. Заполнение веб-таблицы данными осуществляется с помощью метода DataBind Результаты выполнения подпрограммы показаны на рис. 13.10. Листинг 13.25. Заполнение таблицы на веб-странице информацией из набора данных Private Sub FillGridsC) связываем данные с ячейками таблицы на веб странице grdCustomer DataSource = dsCustomerView grdCustomer.DataMember = "CustomerAlias" grdCustomer.DataBindl) grdTransaction.DataSource = dsCustomerView grdTransaction.DataMember = "TransactionAlias" grdT ransacti on.DataBind()
------------Обработка сведений о клиентах в бяво ----------------------------------- лентах в базе данных View Ridge 633 grdWork DataSource = dsCustomerView grdWork DataMember = "WorkAlias" grdWork DataBlndl) grdArtist.DataSource = dsCustomerView grdArtist.DataMember = "ArtistAlias" grdArti st. Da taBindO grdlntersection.DataSource = dsCustomerView grdlntersection. DataMember = "IntersectionAlias" grdlntersecti on.DataBind() End Sub P-wsi CtatgeDye J ( ShowLj^ J USA 206 Tfimy T«4^t^*oue *-“«’«* WA 52114 USA 206 555-1000 CunomerlOlS^rcnawhae c«n91W0 - =>, - 1015 IxawltyWA .98114 too 20000 1015 505 50$ iLyvat. Гаог.с Cn: of the onlypnvatcly r.eld ccp.es si exeelest coodnoci 9Й13514 */•0 Ember; F. 9m the srart'r ссДссйоп НС 14 : 1015 м 1015 16 «015 0ИЕЕЯЕЖ2ПШЖИЕ1^Е1Е2 1709 1S00 Trsfii US Tobey US ChAgaU French И 16 4» to» ty, Рис. 13.10. Вид веб-страницы в браузере Веб таблицы „а этом рисунке имеют ряд интересных свойств. Во-первых, об- ратите внимание, что имена столбцов таблиц получены от Oracle. Нигде в коде приложения мы не указывали эти имена явно Имена столбцов содержались в мета- данных, полученных из базы данных методом FillSchema объекта OracleDataAdapter Все эти имена написаны заглавными буквами, потом)’ что именно в таком виде они храня 1ся и Oracle. Кроме того, заметьте, что в таблицу набора данных CustomerAlias добавлен столбец TotalPurchases (общая сумма приобретении). Его значение равно 91 000, что действительно составляет общую сумму всех покупок, сделанных этим кли- ентом Эго означает, что связь между таблицами CustomerAlias н TransacbonAlias была корректно обработка Все прочие данные для клиента с номером 1015 вы- глядят так, как и следовало ожидать.
634 Глава 13 XML, и ADu.NFT До сих пор мы р.1бо га.иц с наборами данных, исходя из табличном парадигмы, подобно тому, как чо делается в листинге 11 25. По можно обращаться к иабо- рам цшных и исходя из партии мы XML В лнспппе 13 26 приведен пример не- пользования метода GetXml объекта Dataset. В данном случае метод записывает ХМЬ-представлеине набора данных в строковую переменную, содержимое ю/го- рой затем отображается в текстовом иоле Резулыаыи показаны на рис. 1311 Листинг 13.26. Генерация XML-документа из набора данных Private Sub btnShowXML_Click _ (ByVai sender As System Object, ByVai e As System EventArgs) _ Handles btnShowXML.Click ’ создаем XML-документ и помещаем его в текстовое окно strXml = dsCustomerView.GetXml() txtXMLShow.Text = strXml pnlTables.Visible = False txtXMLShow.Visible = True End Sub | Shawfabtos | | Shaw XML | Show I jl M -xwrf иигмiW bt«f . о ✓ </MA5E> </STREET» </CITY> ©«>• 0 !&S!2SL>UU Рис. 13.11. Часть получившегося XML-документа [ Changa btita | Showtjog ] :<NesPaza5et> KCuscoMetAlias> : <CUSTGHEPIS>1O15</CUSTOHSRIE> <NAME>TiXXany Twilight <3TREET>8t: - First Avenue cClTYXLandey <STATI>WA<;S?ATK> <IIPPOSTALCODE>S6114 </IIPPOSTALCODE» «O®JTRY>trSi</CGUNTRY> ] <APJtXCCi>E>20e</AREACO£>E> tFS<CaKVHMR>5S5- 1OOC</FSCCT£HUHBER> <EMAIL>CUSto»trijD15esOtneWTiere. CO»</EMAIL> <Тогя1_х0С20_РигсЬйз«>51С00</Тога1_хР020_Ригсказез> < intersect icniiA.es> «ARTISTIt»3</ARTISTIC» <CV3TOHERX5>1015c/CVSTOKERl»> </IntersectlonAli&s» <IntereeocichALims> <A»TISTID> 14 </ ARTISTID.-» <CU3T O8ERIL>1015</CUSTOnEPlb> </Intecsect 1опАИаз> <Intersectlobilias> <iRTISTIO>16</XRTI3TXD> <Cn$TO!!£RI&> 1015</CU£TOK!:RIP> <i Xnteraectionklieo '(Transact ioniiiae> er«W«ACTIOWXP>i3S</TRA>;siCTICWXI» с»ЛТКАССЛ1МС.>2О02-0Т-ПТ00:00 :OO.COODOO9-07 :CC</»ATt ACQUIRE!» <ACQUI«IT1<»RFICE>47COO<ZACQUISITI<«PSICE> cvt/xioxzaiiocu.uixn.^.-ra'A Реклама разработок Microsoft никоим образом ие входит в намерения автора, однако здесь мы имеем поистине удивительную возможность, которая доступ на при столь малых усилиях с нашей стороны. Мы можем создать набор данных
Обработка сведений о клиентах в базе данных View Ridge 635 ‘ создаем XML-схему и помещаем ее в текстовое окно strXml = dsCustomerView.GetXmlSchemaO txtXMLShow.Text = strXml pnlTables.Visible = False txtXMLShow.Visible = True End Sub и с его помощью построить представление базы данных любого уровня сложности. После этого мы вольны обрабатывать это представление либо в форме таблиц, либо в форме XML. Более того, если мы внесем изменения в XML-документ, эти изменения будут отражены в наборе данных и, следовательно, в таблицах. Сходным образом, если мы изменим содержимое таблиц набора данных, эти из- менения будут автоматически отражены в создаваемом XML-документе. Таким образом, мы можем обрабатывать одни и те же данные с разных точек обзора. Можно также автоматически сгенерировать XML-схему для набора данных. Для этого мы вызываем метод GetXmlSchema объекта Dataset и отображаем воз- вращаемую им строку в текстовом поле (листинг 13.27, рис. 13.12). Результатом будет схема XML-документа, показанного на рис. 13.11. Листинг 13.27. Генерация XML-схемы из набора данных Private Sub btnShowXMLSchema_C11ck _ (ByVai sender As System. Object. ByVai e As System. Event Args) _ Handles btnShowXMLSchema.Click 3V‘cHor<ni Intranet 1 •
вЗб Глава 13 XML и ADO Nt 1 Если мы сохраним полученную схему й файле, то н<ьж>' с №«м<лам> файла мы сможем воссоздан. набор данных Все таблицы, < ллбцм и • им «и и ра данных будут корректно носсглнонлсны. исходя из его схемы Имниг в яйлу однако, что есть ряд характеристик набора данных, которы* н<- мо . • быть. йены в ХМ1 -схеме. Например, сияли пока цапаются ц XML-схгме, а огрниичеиад ссылочной целостности - нет. Ограничения ссылочной целостности и- • / ->лим/. заново устанавливать для набора данных после того, как он будет воссюахт по XML-схеме. Обновление информации в наборе данных и исходной базе данных Содержимое набора данных может обновляться точно так же, как и содержииое обычной базы данных. Различие состоит в том, что изменения, сделанные в набо- ре данных, не обязательно распространяются на исходную базу данных Чтобы продемонстрировать, как производится обновление набора данных мы внесем некоторые изменения в набор данных, исследуем состояние его строк, сохраним сделанные нами изменения в исходной базе данных, а затем снова исследуем со- стояние строк набора данных. Все действия будут записаны в текстовый журнах В листинге 13.28 показан код, выполняющий указанные действия. Читая этот код, обращайтесь к листингу 13.20, где были объявлены важные объектные пере- менные. В частности, переменная drcTransRow (префикс dre обозначает объект DataRowCollection, представляющий коллекцию строк набора данных) определена как массив объектов DataRow (строка набора данных), а переменная drTransRow объявлена как отдельный объект DataRow. Переменная dtUpdatedRows представ- ляет собой объект DataTable (таблица набора данных), содержащий обновленные строки. Наконец, переменная dtTrans определена как одиночный объект DataTable. По причинам, которые здесь для нас не существенны, этот объект объявлен в дру- гом месте кода, но определен как объект класса DataTable Листинг 13.28. Процедура обновления Private Sub btnChangeData_Click(ByVal sender As System.Object. ByVai e As System.EventArgs) _ Handles btnChangeData.Click txtBoxMessage.Visible = True ' делаем журнал видимым txtBoxMessage.Text = "**** start column change in TransactionAlias Table. **** " ’ start log dtTrans указывает на таблицу TransactionAlias dtTrans = dsCustomerView.TablesC’TransactionAlias”) находим подходящие строки drcTransRows = dtTrans.SelectCfSalesPrice < AskingPrice) ") ’ для каждой найденной строки
Обработка сведений о клиентах в базе данных View Ridge 637 For Each drTransRow In drcTransRows ' устанавливаем salesprlce равным askingprice drTransRow!'Sa esPrice") = drTransRow!"AskingPrice") Next ' записываем состояние в журнал DisplayRowStateO создаем таблицу обновленных строк dtUpdatedRows = dsCustomerView. TablesCTransactionAlias") dtUpdatedRows = dsCustomerVl ew. Tabl es ("Transacti onAl las"). GetChanoes (Da ta RowSta te.Modified) Задаем свойство UpdateCommand для адаптера данных Oracle But 1 dOracleUpdateCommand () daViewRidge.Update(dtUpdatedRows) ' Update database txtBoxMessage.Text = txtBoxMessage.Text & _ “**** Oracle Updated Trom Data Set **** " записываем состояние в журнал DisplayRowStateO фиксируем изменения в наборе данных dsCustomerView.AcceptChanges!) txtBoxMessage.Text = txtBoxMessage.Text & _ ''**** Data Set Accept Changes Issued **** " последний раз записываем состояние в журнал DisplayRowStateO выводим на веб-страницу последние данные FillGridsO End Sub При внесении изменений в наборе данных хранятся три версии каждого столбца каждой таблицы исходное значение, текущее значение и предлагаемое значение. Исходное значение — это значение, которое столбец имел при первом считыва- нии из базы данных или после того, как в наборе данных были зафиксированы изменения с помощью метода AcceptChanges. Текущее значение — это значение столбца после того, как изменения были сделаны, но до того, как они были зафик- сированы в наборе данных. Если значение столбца не менялось, текущее значение столбца совпадает с исходным. Наконец, предлагаемое значение — это значение, существующее во время модификации. Мы будем перехватывать это значение в процедуре, являющейся в ADO.NET эквивалентом триггера. ; у. \Дщ 8 Г
638 Глава 13. XML и ADO.NET Обновление набора данных Когда пользователь щелкает па кнопке Change Data (Изменил, данные;, запуска ется процедура па листинга 13.28. Первым делом процедура выводит сообщение о начале процедуры изменения в текстовое окно txtBoxMessage, Затем пе|х.‘меиная dtTrans устанавливается на таблицу TransactionAlias Далее в коллекцию drcTransRowj записываются все строки таблицы TransAlias, в которых столбец SalesPrice меньше, чем AskingPrice. После этого для всех строк в коллекции drcTransRows столбец SalesPrice устанавливается равным AskingPrice. В нашем случае (см. рис. 1311) имеется только одна такая строка, которая и будет обновлена. Посте того как изменение произведено, генерируется событие ColumnChanging (изменение столбца) объекта dtTrans и выполняется код, приведенный в листин- ге 13.29. В этом примере предлагаемое значение просто записывается в текстовое окно, выполняющее у нас роль журнала. Разумеется, если необходимо, в этом месте может выполняться логика предваряющего триггера. Обратите также вни- мание, что в этом месте предлагаемое значение можно изменить до того, как оно будет записано в набор данных. Листинг 13.29. Обработка события (аналог триггера) Private Sub dtTrans_ColuninChanging(ByVai sender As Object. ByVai e As System.Data DataColumnChangeEventArgs) Handles dtTrans.ColumnChanging это аналог предваряющего триггера для набора данных здесь, например, могло бы изменяться e.ProposedValue txtBoxMessage.Text = txtBoxMessage.Text & _ "**** Column is changing. Proposed value is: " & _ e.ProposedValue & " ****•• End Sub После обновления столбца SalesPrice вызывается подпрограмма DisplayRowState. Как видно из листинга 13.30, эта подпрограмма выводит в текстовое окно сооб- щение, содержащее текущее и исходное значения столбца SalesPrice для всех строк таблицы TransactionAlias. Листинг 13.30. Вывод в журнал текущего и исходного состояния столбца SalesPrice Sub DisplayRowStateO For Each drTransRow In dtTrans Rows показываем текущее значение SalesPrice в этой строке txtBoxMessage.Text = txtBoxMessage.Text & ” Transaction with TransactionlD'’ & Str(drTransRow("TransactionID")) _ & ' Current Value Is ” & drTransRowCSalesPnce". DataRowVersion.Current показываем исходное значение SalesPrice в этой строке txtBoxMessage.Text т txtBoxMessage.Text & _
Обработка сведений о клиентах в базе данных View Ridge 639 " Transaction with TransactionlD" & Str(drTransRow( & “ Original Value Is " & drTransRow("SalesPrice". DataRowVersion.Original) & " " “TransactionlD" )) Next End Sub Рис. 13.13. Журнал с результатами обновления набора данных Как следует из записей в журнале (рис. 13.13), изменение было перехвачено событием Columnchanging, после чего в журнал было записано предлагаемое значе- ние 20000. Далее подпрограмма DisplayRowState вывела текущие и исходные значе- ния для всех строк в dtTrans (таких строк, согласно рис. 13.10, имеется две). Заметь- те, что текущее и исходное значения для первой строки совпадают, а для второй строки различаются, поскольку столбец SalesPrice этой строки был изменен. Обновление базы данных Oracle Итак, содержимое набора данных было изменено, но в исходной базе данных ни- каких модификаций нс делалось. Следующие операторы из листинга 13.27 запи- сывают изменения, сделанные в наборе данных, в базу данных Oracle. Для этого в наборе данных создается таблица dtUpdatedRows, которая далее заполняется с по- мощью метода GetChanges. Метод GetChanges помещает все строки, в которых теку- щее значение отличается от исходного, в таблицу dtUpdatedRows. Следующий оператор вызывает подпрограмму, которая строит команду об- новления для Oracle. Текст этой подпрограммы представлен в листинге 13.31.
640 Глава 13, XML и ADO NET Назначение этой подпрограммы и том, чтобы присвоить знач> ни Снбй<тву UpdateCommand адаптера данных Oracle. Каждый адаптер данных имеет четы- ре таких свойства: SelectCommand, InsertCommand, UpdateCommand и DeleteCommand Эти команды используются для выполнения указанных действии Если, на пример, необходимо обновить строку в базе данных, адаптер данных вызы вает UpdateCommand. Если требуется удалить строку, адаптер данных вызывает DeleteCommand. Для заполнения набора данных в листинге 13.20 мы использова- ли свойство SelectCommand, Листинг 13.31. Создание команды обновления Sub Bui 1dOracleUpdateCommandО Dim cmdUpdate As OracleCommand ' Создаем команду обновления cmdUpdate = New OracleCommandl"UPDATE SYSTEM.Transaction SET SalesPrice = pSalesPrice " & _ "WHERE TransactionlD = :pTransactionID". conViewRidge) cmdUpdate.Parameters.AddC'pSalesPrice". OracleType.Number. 8. "SalesPrice") cmdUpdate.Parameters.AddCpTransactionlD". OracleType.Int32. 0. "TransactionlD") daViewRidge.UpdateCommand = cmdUpdate End Sub Эти свойства могут содержать любую допустимую команду SQL. Кроме того, они могут вызывать хранимые процедуры, выполняющие необходимые измене- ния в данных. Можно автоматически сгенерировать эти команды с помощью VisualStudio.NET, но эта возможность выходит за рамки нашего обсуждения. Вместо этого мы создадим свою собственную команду обновления. Прежде чем мы продолжим, обратите внимание, что способность настраивать процедуры вставки, обновления и удаления, выполняемые адаптером данных, дает разработчику необычайную гибкость. Работая с ADO, разработчик был огра- ничен рамками конкретной реализации этих действий в ADO. Позволяя разработ- чику задавать свои собственные команды, ADO.NET обеспечивает гораздо ооль- шую гибкость при встраивании желаемой логики и функциональности в процесс сохранения измененного содержимого набора данных в базе данных. Необходимо сделать одно небольшое замечание по поводу листинга 13.31. Как вам известно из главы 10, имена переменных в хранимых процедурах на PL/ЗУ. предваряются двоеточием. Это означает, что перед параметрами, передаваемыми команде обновления, также должны ставиться двоеточия, как и сделано в лвс тинге 13.31. В документации поставщика данных Microsoft OracleClient отсутст вует четкое указание на эту особенность. После того как задано свойство UpdateCommand, можно выполнять обновле ния. В листинге 13.28 это делается путем вызова метода Update адаптера данных,
Обработка сведений о клиентах в базе данных View Ridge 641 которому в качестве параметра передается таблица набора данных с обнов- ленными строками. В результате изменения записываются в базу данных Oracle. Однако, как показывает журнал (рис. 13.13), произведенные нами изменения еще не зафиксированы в наборе данных. На это указывает тот факт, что после обновления базы данных Oracle исходное и текущее значения столбца SalesPrice во второй строке dtTrans различаются. Фиксация изменения в наборе данных осуществляется путем вызова метода AcceptChanges набора данных. После этого исходное и текущее значения всех столбцов во всех строках таблиц набора данных будут одинаковыми. Это демон- стрируют последние четыре строки журнала на рис. 13.13. Окончательный вид всех таблиц набора данных показан на рис. 13.14. За- метьте, что значение вычисляемого столбца TotalPurchases также было корректно обновлено. Ц = Ранг W15 T- S$- Saf™ L^eyWA 33-14 Aveoie 7H7Z2002 120000 AM 2?27*i974 R7S0 12 00 0C AM JlACOUH-T! Jl UiNUICJiKgMAfl. 206 555 WOO .Кроме того. 50» измене c nifsioab^ WO %5 530 5 14 К ICWOK ISWWAM ?2SW 3f:»:974 •2.00.00 AM. 72500 U15 20000 20000 i₽i: 505 Муле F*hnr Ок? of onhrpwM*!;; rntrfw, SiowE^beri From the artiste ccJlscnc-b :o>5 1015 iOIf | Ci Ьш I Г Showij^j j 530 <800 1700 14 И US ГоЬеу US Frerxh Рис. 13.14. Вид таблиц набора данных после обновления В этом разделе мы продемонстрировали лишь немногие из возможностей и функций ADO.NET. Хотя это не дает вам достаточной подготовки для того, чтобы писать собственные приложения ADO.NET, у вас должно было сложиться общее представление о наборах данных и способах их обработки Также вы Должны были понять, как идея набора данных объединила в себе мир реляцион- ных баз данных и мир обработки документов Эта технология будет играть важ ную роль в течение многих лег, и изучение ее будет великолепным вложением нашего времени.
642 Глава 13. XML и APO Nl Г Обзор стандартов XML Как вы знаете. ХМ1. был |>a;tpa(»oraii как серия < iандаркш. Мы упомянули ре из них: XML, \SL, XSLT п XML St lieina. Сущее myci ряд других «андонов, С которыми ВЫ можете сюЛКПуТЪСЯ. Лскоюрыс из ЦЦХ ПС|М-*1И< лены в габл, 132 Стандарты, документацию по ним н учебные мщерналы можно найти на сайтах www.w3.org н www.xml.org. Таблица 13.2. Важные стандарты XML Стандарт Описание XML Расширяемый язык разметки Язык разметки документов, который положил начало развитию следующего' XSL Таблица стилей XSLT. Документ, содержащий пары вида {шаблон, действие} и другие данные, используемые для преобразования XML-документа в другие форматы XSLT Программа (или процесс), которая применяет таблицы стилей XSLT к ХМL-документу, в результате чего на выходе получается преобразованный XML-документ XML Schema Удовлетворяющий стандарту XML язык, который позволяет задавать требования к структуре XML-документа. Расширяет и заменяет DTD. Находится в процессе развития и обещает быть исключительно важным для обработки баз данных Xpath Подъязык XSLT, используемый для идентификации частей XML-документа, подлежащих преобразованию. Может также использоваться для вычислений и строковых манипуляций XPointer Стандарт для связывания документов между собой. XPointer содержит многие элементы XPath SAX Простой интерфейс прикладных программ для XML. Событийный синтаксический анализатор, который уведомляет программу об обнаружении элементов XML в ходе анализа документа DOM Объектная модель документов. Интерфейс прикладных программ, представляющий XML-документ в виде дерева. Каждый узел дерева представляет фрагмент XML-документа. Программы могут напрямую обращаться к узлу DOM-представления и выполнять с ним различные действия XQuery Стандарт для представления запросов к базе данных в виде XML-документов. В структуре запроса используются элементы XPath, а результат представляется в XML-формате. Данный стандарт находится в процессе развития и обещает стать важным в будущем XML Namespaces Пространства имен XML — стандарт именования определяемых пользователем коллекций элементов. Обозначение X:Name интерпретируется как «элемент Name, определенный в пространстве имен X». Y:Name интерпретируется как «элемент Name, определенный в пространстве имен Y». Полезен для предотвращения конфликтов и ь Стандарт XPath — эго стандарт адресации элементов в документах. В листин- ге 13.5 в выражениях вроде <xsl:value-of-select-,,name/lastname,'> для указания на конкретный элемент документа используется стандарт XPath. XPath включает в себя концепции из другого стандарта, XPointer, назначение которого состояло
_ ______Обработка сведений о клиентах в базе данных View Ridge 643 в том, чтобы обеспечить возможность одному документу ссылаться на элементы других документов. SAX и DOM представляют собой различные методы синтаксического анали- за XML-документов. Процесс синтаксического анализа (parsing) включает в себя чтение документа, разбиение его па компоненты и выполнение определенных действий, исходя из результатов разбиения - например, сохранение компонен- тов в базе данных. Синтаксические анализаторы XML могут также проверять до- пустимость документов по типу и схеме. В случае использования интерфейса SAX программа-обработчик XSLT (пли другая программа, занимающаяся обработкой XML-документов) вызывает удов- летворяющий стандарту SAX синтаксический анализатор и передает ему имя документа, который предстоит анализировать. SAX-анализатор обрабатывает до- кумент и вызывает объекты XSLT-процессора при обнаружении определенных структур. Например, при обнаружении нового элемента синтаксический анали- затор SAX вызывает программу-обработчик XSLT, передавая ей имя элемента, его содержимое и другие необходимые данные. Интерфейс DOM основан на другой парадигме. Синтаксический анализатор, удовлетворяющий стандарту DOM, обрабатывает весь XML-документ и соз- дает его древообразное представление. Программа-обработчик XSLT может затем вызвать DOM-анализатор для получения определенных элементов с помощью XPath или аналогичной схемы адресации. DOM требует, чтобы весь документ был обработан за один прием, поэтому для очень больших документов может по- требоваться чрезмерно большое количество памяти. В такой ситуации более подходящим выбором является SAX. С другой стороны, если необходимо, чтобы все содержимое документа было доступно одновременно, то единственным вари- антом является DOM XQuery — это находящийся в стадии разработки стандарт для представления обобщенных запросов в виде XML-документов. Его можно представить себе как аналог SQL для XML-документов. Этот стандарт может стать важным в буду- щем для мира баз данных и XML. Посетите сайт www.w3.org и осведомитесь о те- кущем состоянии этого стандарта: не исключено, что, когда вы будете читать эту книгу, его разработка будет уже завершена. Последний стандарт, XML Namespaces, имеет большое значение, поскольку позволяет объединять несколько различных словарей элементов в одной < 1 схеме. Сею помощью можно определять и поддерживать домены, а также пред- отвращать конфликт имен. Необходимость в последнем возникает. когда доку- мент содержит синонимы. Пусть элемент под названием Instrument используется В документе в двух различных смыслах; в одном случае имеется в виде м\зы калытый инструмент с нодэлемеигамп {Manufacturer, Model, Material} (производи- тель, модель, материал) скажем, {1 lorner, бас-кларнет, Дерево}, а во втором Электроинструмент с подэлсментамп {Manufacturer, Model о age} (h|xii. тель, модель, напряжение) - например, {Bosch. Электродрель. 220 В}. Автор XML схемы для такою документа может определить для каждою из этих эле ментов свое пространство имен. Тогда перед именем сложного типа Instrumemt *» каждом случае можно будет указать метку нрострящ тпа нмтп, как i
644 Глава 13 XML и ADO NET в рассмотренных ранее схемах, нс пользуя метку sxd.. МI Nann-spai s ю г/шшр пая тема, и вы наверняка узнаете о пей много больше и процессе работы с XML Комитет по стандартам ХМ1 продолжает спою паяную работу, и но мере шп нпкновення потребностей будут разрабатываться ио$ыс стандарты Например, в настоящий момент (2003 год) идет подготовка к разработке стандартов безо пасностп. Более подробную информацию вы получите на сайте www.w3.org Резюме Слияние технологий обработки баз данных и обработки документов является од- ним из наиболее важных прорывов в информационной технологии нынешнего дня. Обработка баз данных и обработка документов тесно связаны друг с другом. При работе с базами данных для создания и материализации представлений нуж- ны технологии обработки документов, а при работе с документами для постоян- ного хранения информации нужны технологии обработки баз данных. Язык SGML представляет такую же важность для обработки документов, как реляционная модель — для мира баз данных. Язык XML представляет собой серию стандартов, совместно разработанных сообществами профессионалов в области обработки документов и обработки баз данных. XML предоставляет стандарти- зированный, но вместе с тем гибкий способ описания содержимого документов. XML-документы могут автоматически генерироваться на основе информации из базы данных, и наоборот — информация может автоматически извлекаться из XML-документов и записываться в базу данных. Хотя XML может использоваться для материализации веб-страниц, это одно из самых его незначительных применений. Намного более важным является его использование для описания, создания и материализации представлений баз дан- ных. XML находится на переднем крае технологий обработки баз данных; послед- нюю информацию о развитии этого стандарта вы найдете на сайтах www.w3.org и www.xml.org. XML является более удачным языком разметки, чем HTML, главным обра- зом потому, что он обеспечивает четкое разделение между структурой, содержи- мым и материализацией документа. В XML символы не могут использоваться неоднозначным образом. Для описания содержимого XML-документов используется два способа: опре- деление типа документа (DTD) и XML-схема. XML-документ, соответствующий своему определению типа, называется допустимым по типу. Документ может быть формально правильным, но недопустимым по типу — либо потому, что он не соответствует структуре DTD, либо потому, что у него вообще нет DTD. XML-документы могут преобразовываться в другие форматы с помощью про- граммы-обработчика XSL, которая применяет к документу таблицу стилей XSLT Распространенным видом преобразования является преобразование XML-доку- мента в формат HTML. В будущем более важную роль будут играть другие виды преобразований. Например, имея несколько таблиц стилей XSLT, можно преоб- разовывать один и тот же XML-документ, представляющий заказ, в различные форматы, требуемые отделом продаж, бухгалтерией и операционным отделом.
Резюме 645 Обработка с помощью таблиц стилей XSLT является контекстно-ориентирован нои: когда обнаруживается определенный элемент в определенном контексте предпринимается заданное действие. Сегодня большинство браузеров имеют встроенные программы-обработчики XSLT. XML Schema - это стандарт для описания содержимого XML-документа. С помощью XML Schema можно определять собственные словари элементов Документы, соответствующие своей XML-схеме, называются допустимыми по схе- ме. В отличие от DTD, XML-схемы сами являются XML-документами, которые можно проверять на допустимость по отношению к их схеме. Схема, являющаяся прародительницей всех остальных схем, находится на сайте консорциума W3C. Схемы состоят из элементов и атрибутов. Есть два типа элементов: простые и сложные. Простые элементы имеют одно значение. Сложные элементы могут иметь множество вложенных в них элементов. Сложные элементы могут также иметь атрибуты. Элементы, составляющие сложный элемент, могут быть как простыми, так и сложными. В составе сложных элементов могут определяться последовательности элементов. Есть хорошее практическое правило: элементы представляют данные, а атрибуты — метаданные. Это правило, однако, не явля- ется частью какого-либо стандарта XML. XML-схемы (и документы) могут иметь более сложную структуру, чем столб- цы таблицы. Можно определять группы, состоящие из нескольких элементов, — например, Phone (телефон) или Address (адрес). Схема, все элементы которой рас- полагаются на одном уровне, называется плоской. Структурированной схемой называется схема, в которой определены подгруппы, такие как Phone или Address. Чтобы избежать дублирования определений, можно определять элементы как глобальные. Дублирование нежелательно, поскольку существует риск, что опреде- ления станут несогласованными, когда одно из них будет изменено, а другое — нет. Как в Oracle, так и в SQL Server имеются возможности для создания XML- документов из содержимого базы данных. В Oracle для этого необходимо ис- пользовать Java (более подробную информацию вы найдете на www.oracle.com). SQL Server поддерживает специальную форму оператора SELECT — выражение FOR XML. С помощью FOR XML можно создавать XML-документы, в которых все данные представлены в виде атрибутов либо в виде элементов. Кроме того, этот оператор может вместе с ХМ L-документом генерировать его XML-схему. Псполь зуя форму FOR XML EXPLICIT, разработчик может указать, какие столбцы таблиц следует преобразовать в элементы, а какие — в атрибуты. При интерпретации запросов к нескольким таблицам программа определяет иерархический порядок расположения элементов в документ но порядку следо ваиия таблиц в запросе. С помощью оператора FOR XML можно создавать доку- менты, содержащие максимум один многозначный маршрут. Докумен Шие более одного такого маршрута, должны каким-го образом объедит самим приложением. „ Важность ХМ L состоит в том, что он упрощает обмен и совмссгт ое«спольз вание документов (а следовательно, тт ннформащш тт.т баз организациями Договорившись о единой XML-схеме, орта п . „ ‘ ‘ ‘ тировать, что все исходящие н входящие документы являют. 11!?‘ь ™ схеме. Кроме того, орт т тизании могут разрабатывать таблицы стилен XSL1 для
646 Глава 13. XML и ADO.NET преобразования любых допустимых по схеме XMI документов полученных ад нового источника, в другие стандартные форматы. Din преимущества становят ся еще более явными, когда стандартизация ХМ I.-схем происходит на у|ювне<гг раслевых групп. XML также упрощает электронную коммерцию (В2В) ADO.NET — это новая, улучшенная и зпа.елыю расширенная ш-jx ия ADO разработанная Microsoft в рамках ннициатнпы .NET. ADO.NET включает в себя всю функциональность ADO. но добавляет к ней мною новых возможностей В частности. ADO.NET упрощает преобразование ХМL-документов в содержи- мое базы данных и наоборот. Что важнее всего, ADO.NET вводит понятие набо- ров данных — полнофункциональных, независимых баз данных, целиком распо- лагающихся в оперативной памяти. Поставщик данных .NET — это библиотека классов, предоставляющая услуги ADO.NET. Корпорацией Microsoft разработаны три поставщика данных. Постав- щик данных OLE DB можно использовать для обработки любого OLE DB-co- вместимого источника данных. Поставщик данных SQLClient предназначен для работы с SQL Server, а поставщик данных OracleClient — для работы с Oracle. В ближайшем будущем весьма вероятно появление поставщиков данных от дру- гих производителей. Считыватель данных обеспечивает быстрый последовательный доступ к дан- ным только для чтения. Для выполнения SQL-операторов и вызова хранимых процедур, подобно тому, как это делается в ADO (но в более удобной форме), можно использовать объект Command. Главной новой идеей в ADO.NET является набор данных. Набор данных представляет собой базу данных в оперативной памяти, кото- рая отключена от обычных баз данных, но обладает всеми их существенными ха- рактеристиками. Наборы данных могут иметь множество таблиц, связей, ограни- чений и процедур обеспечения ссылочной целостности, представлений, а также процедур, эквивалентных триггерам. Таблицы набора данных могут иметь столб- цы суррогатного ключа (называемые столбцами автоприращения) и первичные ключи. Столбцы таблиц набора данных могут объявляться уникальными. Набор данных не синхронизируется с базой данных, из содержимого которой он был построен. Набор данных может создаваться из нескольких баз данных, в том числе управляемых различными СУБД. После того как набор данных создан, его содержимое легко может быть пред- ставлено в виде XML-документа, а его структура — в виде XML-схемы. Более того, этот процесс работает и в обратном направлении. По XML-схеме можно создать структуру набора данных, а из XML-документа взять данные для его заполнения. Наборы данных предоставляют стандартизированный, свободно доступный метод обработки представлений базы данных. Они особенно важны для обработ- ки представлений, содержащих несколько многозначных маршрутов. Потенциальный недостаток наборов данных заключается в том, что они не присоединены к исходной базе данных, и любые обновления в исходной базе, ос- нованные на изменениях в наборе данных, должны производиться с использова- нием оптимистической блокировки В случае возникновения конфликта необхо- димо либо повторно обработать набор данных, либо принудительно сохранить изменения в базе данных, что вызовет проблему потерянного обновления.
Вопросы группы I 647 Идеи, лежащие в основе наборов данных, иллюстрируются ASP.NET-приложе- нием, написанным на VB.NET. В данном примере обрабатывается представление базы данных галереи View Ridge, содержащее все сведения об одном из клиен- тов. Для этого устанавливается соединение с базой данных Oracle и определяет- ся адаптер данных, который считывает в набор данных содержимое всех пяти таблиц. После этого определяются связи и ограничения ссылочной целостности, а также создается новый столбец, использующий одну из связей. Далее происходит обработка набора данных; отображается содержимое всех его таблиц, создаются эквивалентный XML-докумепт и XML-схема для этого набора данных. Наконец, одна из строк набора данных обновляется и записыва- ется обратно в базу данных Oracle, для чего соответствующим образом устанав- ливается свойство UpdateCommand адаптера данных. В заключение кратко описываются несколько стандартов XML: XPath, SAX, L)OM, XQuery и XML Namespaces. Вопросы группы I 1. В чем состоит тесная связь обработки баз данных и обработки документов? 2. Как связаны между собой HTML, SGML и XML? 3. Поясните значение фразы «стандартизированный, по вместе с тем гибкий». 4. Что такое SOAP? Что эта аббревиатура обозначала первоначально? Что она обозначает сегодня? 5. Какие проблемы связаны с интерпретацией тегов, подобных <h2>, в JJTML? 6. Что такое DTD? Каково его назначение? 7. В чем разница между формально правильным XML-документом и допус тимым по типу XML-документом? 8. Почему определение «XML - это следующая версия HTML» является слишком узким? 9. Как связаны между собой XML, XSL и XSLT? 10. Объясните, как используются инструкции вида {шаблон, действие} при обработке XSL-докумсита. И. Каково назначение стандарта XML Schema? 12 Чем XML-схема отличается or DTD7 13 Что такое документ, допустимый ио схеме? 14 . Объясните проблему курицы и яйца, связанную с проверкой допустимо- сти документов XML Schema. 15 В чем разница между простыми и сложными элементами? 16 В чем разница между элементами и атрибутами? 17 Каково практическое правило, используемое щш представлении информа- ции из базы данных в виде элементов и атриоуюв? 18 Приведите пример плоской XML схемы, отличный от схемы, данной в тексте.
648 Глава 13. XML и ADO.NET 19. Приведите пример структурированной XML-схемы, отличный от схемы данной в тексте. 20. Зачем нужны глобальные элементы? 21. Каково необходимое требование для обработки XML-докуменюв в Oracle? 22. Поясните разницу между выражениями FOR XML RAW и FOR XML AUTO, ELEMENTS. 23. В каком случае вы использовали бы выражение FOR XML EXPLICIT"? 24. Почему в SQL-операторе, использующем выражение FOR XML, важен поря- док следования имен таблиц? 25. Почему неверна схема на рис. 13.6, а? Что привело к получению такой схемы? 26. Почему использование внешнего соединения решило бы проблему, изобра- женную на рис. 13.6, а? В каком случае это не помогло бы? 27. Объясните своими словами, почему SQL-оператор с предложением FOR XML не может быть использован для построения XML-документа, содержащего два многозначных маршрута. 28. Почему ограничение, описанное в вопросе 27, является важным? 29. Объясните своими словами, каково значение XML для обработки баз данных. 30. Почему стандарт XML Schema важен для межорганизационного обмена документами? 31. Что такое ADO.NET? 32. Что есть поставщик данных? 33. Какие поставщики данных упоминались в тексте? 34. Что такое считыватель данных? 35. Как можно использовать ADO.NET для обработки базы данных без помо- щи считывателей данных или наборов данных? 36, Что такое набор данных"? 37. Чем наборы данных концептуально отличаются от баз данных? 38. Перечислите основные структуры набора данных, как они описаны в этой главе. 39. Каким образом наборы данных решают проблему представлений с несколь- кими многозначными маршрутами? 40. Каков основной недостаток наборов данных? В каком случае он может яв- ляться помехой? 41. Почему для обработки баз данных важно знать объектно-ориентированное программирование? 42. Что представляет собой соединение ADO.NET? 43. Какая учетная запись должна существовать по умолчанию в Oracle, чтобы можно было использовать интегрированные средства безопасности в при- ложении ASP.NET? 44. Что такое адаптер данных?
_______________________________________________Вопросы группы II 649 45 Каково назначение свойства SelectCommand адаптера данных? 46. В чем разница между методами Fill и FiUSchema адаптера данных? 47. Как строятся связи между таблицами набора данных в ADO.NET"? 48. Как определяются ограничения ссылочной целостности в ADO.NET? Какие возможны процедуры обеспечения ссылочной целостности? 49. Объясните, откуда берется значение столбца TotalPurchases в таблице набора данных CustomerAlias. 50. Напишите фрагмент кода, создающий XML-документ из набора данных. 51. Напишите фрагмент кода, создающий XML-схему из набора данных. 52. Чем различаются исходное, текущее и предлагаемое значения? 53. Как реализуется функциональность триггеров в наборе данных? 54. Каково назначение свойства UpdateCommand адаптера данных? 55. Опишите, как создаются параметры для команды обновления в листинге 13.31. 56. Каково назначение свойств InsertCommand и DeleteCommand адаптера данных? 57. Объясните, какого рода гибкость обеспечивают свойства InsertCommand, UpdateCommand и DeleteCommand. 58. Что такое XPath? 59. Чем DOM отличается от SAX? 60. В чем назначение стандарта XQuery? 61. В чем назначение стандарта XML Namespaces? Вопросы группы II 62 Создайте XML-документ с DTD, подобный приведенному на рис. 13.1, ко- торый представлял 1эы первую строку таблицы ARTIST (см. табл. 7.1). 63. Взяв за образец лизинг 13.5, создайте XSL-документ для материализации XML-документа, созданного вами в ответе на вопрос 62. Материализуйте ваш документ в браузере. 64. Создайте XML-схему, описывающую строку таблицы TRANSACTION Пусть столбец TransactionlD играет роль атрибута. Сгруппируйте данные о приоб- ретении произведений галереей в один сложный тип, а данные о покупках клиентов - в другой сложный тин. В качестве образца используйте лис- 65. Создайте XML-схему, описывающую художников и клиентов, имеющих к ним интерес. В качестве образца используйте листинг 13. 66 Создайте XML-схему, содержащую данные о художниках, произведениях, транзакциях и клиентах. В качестве образца пснользупте листинг 13.1b. 67 Создайте ХМL схему, содержащую нее данные о художниках В качес не образца используйте листинг 13 19
650 Глава 13. XML и ADO.NET Вопросы к проекту FiredUp Если вы еще этого не сделали, создай ге базу данных FiredUp с помощью Or или SQL Server. Следуйте инструкциям и конце главы К) или И егюгвегстиеиио 1. Взяв за образец лпеппп 13.1, создайте XML документ с DTD описип- щпй строку таблицы КЛИЕНТ. 2. Взяв за образец листинг 13.5, создайте XSL документ для материализации ХМ L-документа, созданного вамп в ответе па вопрос 1. Материализуйте ваш документ в браузере. 3. Создайте XML-схему, описывающую соединение таблиц КЛИЕНТ и РЕМОНТ ГОРЕЛКИ Пусть документ содержит данные об одном клиенте и произвола ном (в том числе нулевом) количестве ремонтов, выполненных для данно- го клиента. В качестве образца используйте листинг 13.9. 4. Напишите SQL оператор с предложением FOR XML, генерирующий XML- докумепт, созданный вами в ответе на вопрос 3. 5. Создайте XML-схему, содержащую все сведения о заданном клиенте. Сколько многозначных маршрутов имеется в этой схеме? 6. Объясните, какие преимущества могла бы получить фирма FiredUp от ис- пользования XML-схемы, созданной в ответе на предыдущий вопрос 7. Объясните, как с помощью набора данных можно генерировать докумен- ты, подобные тому, который вы создали в ответе на вопрос 5 5®* SenerPages MvSQL са'ЛС! Вопросы к проекту Twigs Tree Если вы еще этого не сделали, создайте базу данных Twigs Tree с помощью Oracle или SQL Server. Следуйте инструкциям в конце главы 10 iuyi 11 соответственно. 1. Взяв за образец листинг 13.1, создайте XML документ с DTD, описываю- щий строку таблицы ВЛАДЕЛЕЦ. 2. Взяв за образец листинг 13.5, создайте XSL-документ для материализации XML-документа, созданного вамп п ответе на вопрос 1. Материализуйте ваш документ в браузере. 3. Создайте XML-схему, описывающую соединение таблиц ВЛАДЕЛЕЦ и ДО- СТАВ КА_СТРУЖКИ. Пусть документ содержит данные об одном владельце участка и произвольном (в том числе нулевом) количестве доставок, вы- полненных для него. В качестве образца используйте листинг 13.9. 4. Напишите SQL-оператор с предложением FOR XML, генерирующий XML докумен г, созданный вами в ответе на вопрос 3. 5. Создайте XML схему, содержащую все сведения о заданном владельце участка. Сколько многозначных маршрутов имеется в этой схеме. 6. Объясните, какие преимущества могла бы получить фирма FiredUp от и пользования XML-схемы, созданной в ответе на предыдущий вопрос. 7. Объясните, как с помощью набора данных можно генерировать докуме ты, подобные тому, который вы создали в ответе на вопрос 5. не - АмЗОООя^уп работ foauor-r S'""*™ Л'
Глава 14 JDBC, Java Server Pages и MySQL В этол i лаве обсуждаются алыерпативы таким технолог ням и продуктам Microsoft, как OLE DB, ADO и .NET. В частности, мы будем рассматривать JDBC, Java Server Pages QSP) с использованием Apachc/Tomcat, а также СУБД под названи- ем MySQL. Большую роль в разработке этих технологий сыграло движение за свободное программное обеспечение, и все они имеют открытые исходные тек- сты. Фактически для разработки всех примеров этой главы использовались только свободно распространяемые программы. Однако JDBC не требует использовать исключительно свободное программ- ное обеспечение: эту технологию можно применять также в Windows ХР, Win- dows 2000 и других операционных системах для работы с SQL Server, Oracle и дру- гими распространенными СУБД. JSP-страпицы и веб-сервер Apachc/Tomcat тоже могут работать под управлением Windows ХР и 2000. Однако все примеры этой главы были разработаны и проверены с использованием Linux. Как вы можете догадаться, единственное требование при использовании JDBC состоит в том, что программы должны быть написаны на Java. Данная книга не предполагает знакомства читателя с программированием па Java, н пет необ- ходимости понимать каждую строчку кода: целью должно быть понимание сути и возможностей представленных здесь технологий. Если вы уже программируете па Java, приведенные примеры должны побу- дить вас к созданию примеров более сложных и реалистичных. В любом случае по прочтении этой главы вы будете способны гранишь возможности ODBC, ADO и ASP с JDBC и JSP. JDBC Для начала заме г им, что, нс смог ря па у i нержде пня mhoi их источников, 11)В( ш Означает Java Datalwise Connectivity. По утверждению компании Sun. изобретателя Java, JDB( но вообще нс аббревиатура, а прост JDBC Ос тается только догады- ваться, какие правовые пли личное тные коллизии ciom за ним \ икржденисм. /драйверы JDBC сущсчгвук)! почти для всех мыслимых СУ ЬД Корпорация Sun поддержи вас г каталей них драйверов на своем сайге по адресу http: /java.sun.coni,
652 Глава 14, JDBC, Java Server Pages и MySQI products jdbc. Некоторые драйверы являются бесила!пымн, и шлни у всех есть ознакомительные версии, которые можно бесплатно использовать в течение ограниченного периода времени. Драйверы JDBC , взятые при нодюювке главы, — это драйверы MySQL с открытыми исходными текстами, рдзрабо тайные Марком Мэтьюсом (Mark Mathews). Их можно загрузить по адресу http://mmmysql.sourceforge.net. Чтобы вы нс прибрели вредной привычки, прежде чем продолжить, исправим одну потенциальную ошибку. На шаппе СУБД MySQL произносится «май эс- кыо-эл», а не «май сиквел». Вряд ли это важно, но, если вы хотите произвести впечатление, всегда говорите «май эс-кыо-эл». Типы драйверов Sun определяет четыре типа драйверов. Драйверы первого типа представляют со- бой мост от JDBC к ODBC. Они обеспечивают интерфейс между Java и обычны- ми драйверами ODBC. Большинство драйверов ODBC написано на С или C++. По причинам, которые не важны для нас здесь, между Java и C/C++ существует определенная несовместимость. Драйверы JDBC-ODBC устраняют эту несовмес- тимость и позволяют обращаться к источникам данных ODBC из Java. Посколь- ку использование ODBC было описано нами в предыдущей главе, первый тип драйверов мы далее рассматривать не будем. Драйверы типов 2-4 написаны полностью на Java и различаются только спосо- бом соединения с СУБД. Драйверы типа 2 соединяются с СУБД через «родные» интерфейсы — например, обращаются к Oracle с использованием стандартного (не ODBC) программного интерфейса Oracle. Драйверы типов 3 и 4 предназна- чены для использования в сетях связи. Драйвер типа 3 транслирует вызовы JDBC в независимый от СУБД сетевой протокол. Этот протокол затем преобра- зуется в сетевой протокол конкретной СУБД. Драйвер типа 4 транслирует вызо- вы JDBC в сетевой протокол конкретной СУБД. Чтобы понять различия между драйверами типов 2-4, нужно сначала понять различия между сервлетом (servlet) и апплетом (applet). Как вы, возможно, знаете, язык Java разрабатывался как переносимый. Чтобы удовлетворять треоо- ванию переносимости, Java-программы компилируются не в конкретный машин- ный язык, а в машинно-независимый байт-код. Sun, Microsoft и другие компа- нии разработали интерпретаторы бант-кода для каждой платформы (Intel 386, Alpha и т. д.). Эти интерпретаторы называются виртуальными машинами Java (Java virtual machines). Для выполнения скомпилированной Java-программы машинно-незав! симый байт-код интерпретируется виртуальной машиной. Оборотная сторона заключается в том, что интерпретация байт-кода добавляет промежуточный шаг, и, следова- тельно, такие программы не могут выполняться так же быстро, как программы, компилируемые непосредственно в машинный код. В зависимости от нагрузк приложения это может вызывать неудобства или нет. Апплет — это программа в байт-коде Java, выполняемая на компыо ере зователя приложения. Байт-код апплета посылается пользователю по HTTP и в* зывается с пользовательской машины также с помощью HTTP. Интерпре
JDBC 653 байт-кода производится виртуальной машиной, которая обычно является частью браузера. Один и тот же байт-код благодаря своей переносимости может быть отправлен на компьютер под управлением Windows, UNIX или MacOS Сервлет - это Java-программа, вызываемая по HTTP на веб-сепвепе Она отвечает на запросы от браузеров пользователей. Сервлеты интерпретируются и выполняются виртуальной машиной Java, работающей на веб-сервере Поскольку драйверы типов 3 и 4 работают с сетевыми протоколами, их мож- но использовать в коде апплетов и сервлетов. Драйверы типа 2 могут использо- ваться только в ситуации, когда Java-программа и СУБД находятся на одной и той же машине или когда в СУБД имеется специальная программа, занимаю- щаяся связью между компьютером, на котором работает Java-программа, и компь- ютером, на котором располагается СУБД. Таким образом, если ваша программа должна соединяться с базой данных из апплета (двухуровневая архитектура), можно использовать только драйверы ти- пов 3 и 4. При этом, если ваша СУБД имеет драйвер типа 4, используйте его, по- скольку он будет работать быстрее, чем драйвер типа 3. В трехуровневой или многоуровневой архитектуре, если веб-сервер и СУБД работают на одной и той же машине, можно использовать драйвер любого из трех типов. Если же они находятся на разных машинах, то безо всяких трудно- стей могут быть использованы драйверы типов 3 и 4. Подойдет также и драйвер типа 2, если в СУБД имеются средства, обеспечивающие связь между веб-серве- ром и СУБД. Характеристики типов драйверов JDBC приведены в табл. 14.1. Таблица 14.1. Типы драйверов JDBC Тип драйвера Характеристики_____________________________________________________ Мост ODBC/JDBC. Предоставляет Java-интерфейс к драйверу ODBC Позволяет работать с источниками данных ODBC на Java 2 Java-интерфейс к собственной библиотеке функций СУБД. Java-программа и СУБД должны находиться на одной машине, в противном случае СУБД должна сама заботиться о связи между двумя компьютерами 3 Java-интерфейс к независимому от СУБД сетевому протоколу. Может использоваться для сервлетов и апплетов 4 Java-интерфейс к сетевому протоколу конкретной СУБД. Может использоваться для сервлетов и апплетов Использование JDBC В отличие от ODBC, в JDBC ист отдельной программы, специально предназначен- ной для создания источника данных. Создание соединения происходит в _ Java-программе через драйвер JDBC. Алгоритм использования драйвера JDBC так . 1. Загрузить драйвер. 2. Установить соединение с базой данных. 3. Создать оператор. 4 Выполнить некоторые действия с созданным оператором Как вы увидите, имена СУБД и базы данных указываются на шаге
654 Глава 14, JDBC, Java Server Pages и MySQL Загрузка драйвера Чтобы загрузить драйвер, пеобхЬдпмо си ria.ua достать библиотеку драйвера и уста пови ть ее в каталог. Этот каталог обязательно должен быть указан в определении переменной окружения CLASSPATH компилятора н виртуальной машины Java Есть несколько способов загрузи ть драйвер в программу; наиболее падежным ян ляетоя следующий; Class. forName(string) .newInstanceO: Значение строкового параметра зависит от используемого драйвера. Для драй- веров ММ MySQL строка загрузки выглядит так: Cl ass.forName("org. gjt. mm.mysql.Dri ver").newlnstance(); Этот метод будет генерировать исключение, поэтому следует поместить его вызов в блок tryxatch. (Если вы не являетесь Java-программистом, не отчаивай- тесь — просто поймите, что эти операторы делают классы JDBC доступными для программы.) Установление соединения с базой данных Следующим этапом после загрузки драйвера является создание объекта, пред- ставляющего соединение с вашей базой данных. Формат таков: Connection conn = DriverManager.getConnection(string): Класс DriverManager входит в библиотеку JDBC, которую вы загрузили на первом шаге. Он играет ту же роль, что и диспетчер драйвера ODBC. Драйве- ры JDBC регистрируются в этом классе. На одной машине может быть зареги- стрировано несколько драйверов. При вызове метода DriverManager.getConnection, диенегчер просматривает свой список драйверов и выбирает из него первый подходящий драйвер. Таким образом, если ваше соединение способно обраба- тывать несколько драйверов, вы можете получить ие тот драйвер, который ожидаете. Строковый параметр, передаваемый методу getConnection, состоит из трех частей, разделенных двоеточиями. Первой частью всегда является строка jdbc, вторая часть — это ключевое слово, идентифицирующее используемую СУБД, а третья — URL базы данных, которую предстоит обрабатывать, с необязатель ними параметрами наподобие имени пользователя и пароля. Следующий оператор установит соединение с базой данных MySQL под на званием vrl от имени пользователя dkl с паролем sesame: Connection conn = DriverManager.getConnection("jdbc:mysql:// localhost/vrl?user=dkl&password=sesame") Содержимое второй и третьей частей этой строки зависит от драйвера JOB На самом деле некоторые драйверы требуют задавать имя пользователя и г как отдельные параметры. Чтобы определиться в этом вопросе, обратитесь кументации драйвера.
JDBC 655 Между прочим, большая часть атой технолог,,» „мое, корня „ „,,рс UNIX UNIX чуостоителыга к регистру букв,„ почт,, „о „сем. что вы .„юд„ге здесь гнстр также имеет значение. Например, jdbc и ODBC - это „е одно „ „, же Иабп- ранте все в том же регистре, в каком показано здесь. Из этого правила есть не- сколько исключении, но они не стоят упоминания, а тем более запоминания П|юсто набирайте все так, как показано здесь Метод getConnection также будет генерировать исключение, поэтому его вы- зов тоже следует поместить внутрь блока tryxatch. Создание оператора Следующий шаг — эго создание объекта Statement, представляющего оператор Процедура напоминает то, что мы делали в предыдущей главе для создания объ- екта Command. Синтаксис таков: Statement stmt = conn createStatementO. Никаких параметров этому методу не передается. Сейчас вы увидите, как можно обрабатывать созданный оператор. Обработка операторов Методы объекта Statement стандартизированы в спецификации JDBC Драйвер сможет выполнить любой из приведенных операторов (и еще много других). За подробной информацией обращайтесь к документации драйвера. В наших приме- рах мы будем использовать методы executeQuery и executeUpdate: ResultSet rs = stmt.executeQuery(querystring): int result = stmt.executeUpdate(updatestring); Первый оператор возвращает набор результатов, который можно использо- вать точно так же, как мы использовали курсоры в предыдущих главах. Второй оператор возвращает целое число которое показывает количество обновленных строк. В качестве конкретных примеров можно привести следующие: ResultSet rs = stmt.executeQuery!"SELECT * FROM CUSTOMER''): и int result = stmt.executeUpdate("UPDATE ARTIST SET Nationality WHERE Name= oste ). Обратите внимание на то, что внутри двойных кавычек во избежание недора- зумений используются одиночные. Для получения запрошенных строк можно перебрать набор результатов, воз вращенпых методом executeQuery Количество и имена столбцов можно получить с помощью метода getMetaData. Его синтаксис следующий ResultSetMetaDate rsMeta - rs.getMetaData!); Теперь, как вы увидите из следующих примеров, можно вызывать методы getColumnCount и getColumnName объекта rsMeta, которые возвращают количество и имена сюлбцов соответственно.
656 Глава 14. JDBC, Java Servai Рацее и MySQL Готовые и вызываемые операторы Скомпилированные запросы н хранимые процедуры можно выбывать с номоед^ готовил оператора (prepared statements) и вызываемых операторов (<*a||a^(g statements). Они используются подобно объекту Command, о ко юром шла речь в главе 12. Поскольку пн скомпилированные запросы, ин хранимые процедуры не поддерживаются MySQL, в примерах этой главы иснользовагь их мы ис будем Продемонстрируем тем не менее использование вызываемых операторов Допустим, мы работаем с базой данных View Ridge в версии для Oracle, созданной в главе 10, и нам нужно вызвать хранимую процедуру Customerinsert. Будем пред, полагать, что объект conn содержит установленное соединение с базой данных View Ridge для Oracle: CallableStatement cs = conn.prepareCall("{call Customer Inserts. ?. ?. ?)}“)- cs setStri ng(1. "Ma ry Johnson“): cs.setString(2. "212"): cs setStnng(3. "555-1234"): cs.setString(4. "US"): cs.execute!); Эта последовательность, вызывающая хранимую процедуру Customerinsert с приведенными данными, очень похожа на ту, которая использовалась для ODBC в главе 12. Можно также получать значения, возвращаемые процедурами, но этот вопрос выходит за рамки нашего обсуждения. Дальнейшую информацию вы найдете по адресу http://java.sun.eom/products/jdk/l.l/docs/guide/jdbc. На рис. 14.1 изображены все компоненты JDBC. Приложение создает объек- ты Connection, Statement, ResultSet и ResultSetMetaData. Вызовы методов этих объ- ектов перенаправляются через диспетчер драйвера (объект DriverManager) соот- ветствующему драйверу, а тот выполняет предписанные действия со своей базой данных. Обратите внимание, что база данных Oracle на этом рисунке может обраба- тываться либо через мост JDBC-ODBC, либо с помощью чистого JDBC-драйвера. Примеры использования JDBC В листингах 14.1 и 14.2 показаны два примера использования драйверов JDBC mm.mysql с СУБД MySQL. Обратите внимание, что обе эти программы импорти- руют java.sql.*. Также обратите внимание на то, что драйверы JDBC не импорти- руются, а загружаются. Если вы попытаетесь их импортировать, результатом неразбериха. Во всех этих примерах используется база данных View Ridge, изображенная на рис. 7.3, 6. Она содержит следующие таблицы: CUSTOMER (CustomerlD. Name, AreaCode, PhoneNumber. Street, City, State, Zip) ARTIST (ArtistID, Name, Nationality, BirthDate, DeceasedDate) CUSTOMER_ARTIST_INT (CustomerlD, ArtistID) WORK (WorkID. Description, Title, Copy, ArtistID); имл-ГО! TRANSACTION (Transact!,onlD, DateAcquired PurchasePnce, SalesPrice, CustomerlD, World ) Связи и ограничения ссылочной целостности описаны в главе 7.
JDBC 657 База данных База данных SQL Server Oracle Рис. 14.1. Компоненты JDBC Класс GeneralTable В листинге 14.1 показан Java-класс GeneralTable. Он принимает один параметр — имя таблицы из базы данных MySQL под названием vrl. MySQL чувствительна к регистру, и имена всех таблиц в базе данных пишутся заглавными буквами. Следовательно, программа должна преобразовать введенное имя таблицы к верх- нему регистру. Листинг 14.1. Класс GeneralTable import java л о,*. import java.sql *; public class GeneralTable { /** Программа на Java, выводящая содержимое любой таблицы. * При вызове передается один параметр - имя таблицы. * которое автоматически преобразуется к верхнему регистру */ public static void main (String [] args) { if (args length <1) { System out printin ("Предоставленных данных недостаточно return; прпдыжение&
658 Глава 14. JDBC. Java Server Pages и MySQL Листинг 14.1 (продолжение) String varTableName - args[0], varTableName - varTableName.toUpperCase 0: System, out. printin ('Выводится таблица" + varTableName) : try { // Загрузка классов MySQL JDBC от Марка Мэтьюса Ц mm.niysql. jdbc-1.2c Class. forName ("org.gjt.mm.niysql .Driver"). newlnstance 0 . // Строка соединения указывает на локальную базу данных MySQL. // пользователь dkl String connString = "jdbc:mysql: //localhost/vrl?user=dki"; System.out.printin ("Попытка установления соединения с " + connString) Connection conn = DriverManager .getConnection(connString) ; // Получаем набор результатов Statement stmt = conn.createStatement () : String varSQL = "SELECT * FROM " + varTableName: ResultSet rs = stmt.executeQuery(varSQL) : // Получаем метаданные, описывающие только что открытый набор результатов ResultSetMetaData rsMeta = rs.getMetaData О: // Выводим имена столбцов в виде строк String varColNames = int varColCount = rsMeta.getColumnCount (): for (int col = 1; col <= varColCount; col++) { varColNames = varColNames + rsMeta.getColumnName(col) +" System.out.pri nt1n(va rColNames): // Выводим значения столбцов while (rs.nextO) { for (int col = 1; col <= varColCount: col++) { j System.out.print{rs.getString(col) + " System.out.printin (); // Очистка rs.close 0: stmt, closed; conn, closed: catch (Exception e) { e.printStackTraced
JDBC 659 Данный пример является прямым приложением только что описанных нами идей. Класс GeneralTable имеет общедоступный метод, не возвращающий значе- ний (в этом и состоит значение слов public и void). Программа проверяет наличие хотя бы одного параметра, записывает переданное ей имя таблицы в переменную varTableName и приводит это имя к верхнему регистру. Затем она обрабатывает базу данных в блоке try с помощью драйверов JDBC. Блок try используется пото- му, что многие методы генерируют исключения. Эти исключения будут перехва- чены в блоке catch. В этих примерах оставлена стандартная обработка исключений. Если вы про- граммируете на Java, то, скорее всего, знаете много способов улучшить обработ- ку исключений по сравнению с тем, что показано здесь. Однако сейчас нас инте- ресуют базы данных. Если вы не знакомы с программированием на Java, просто представьте, что все операторы, помещенные внутрь блока try, который обозначается <try{...}», — это то, что происходит при нормальной работе. Все операторы, помещенные внутрь блока catch, который обозначается «catch{...}», — это то, что происходит, когда возникает ошибка. Кроме того, по аналогии с SQL, в Java многострочные комментарии начинаются с «/*» и заканчиваются на «*/ ». Однострочный ком- ментарий начинается с «//». Драйверы inm.mysql загружаются, как описано ранее, а затем создаются соеди- нение (объект conn) и оператор (объект stmt). Имя базы данных — vrl, имя пользо- вателя — dkl. Пароль отсутствует. (Чтобы это работало, в MySQL нужно опреде- лить пользователя с именем dkl и наделить его полномочиями обращаться к базе данных vrl без пароля. Эти действия мы обсудим в последнем разделе главы.) Для набора результатов rs создается объект rsMeta, содержащий метаданные. Из него считываются имена столбцов и затем выводятся в виде одной длинной строки (varColumnNames). После этого набор результатов перебирается, п каждая его строка выводится на экран. Результат выглядит не слишком красиво, но. по крайней мере, принцип ясен и все работает. Типичный результат работы программы выглядит следующим образом. Showing Table ARTIST Trying connection with jdbc:mysql://localhost/vrl?user”dkl Maae nationality Birthdate DeceasedOate ArtistID Miro Spanish null null 1 Tobey US null null 2 Van Vronken US null null 3 Hatisse french null null 4 Как и говорилось, выгляди! >то ие очень красиво. Класс Cuetomerlnsert В листинге 14.2 приведена вюрая Java-программа, которая о6‘,овл«с;^’ им* vrl Эта программа рсализуе! логику процедуры Customerlnseit, oinicainnK »главах 7, 10, II и 12 (Вы еще не устали от этой процедуры? 1то ж, но всяктм случат. логика вам знакома!)
660 Глааа 14. JDBC, Java Server Pages и MySQL Листинг 14.2. Класс Customerinsert import java.io.*: import java.sql.*: public class Customerinsert { /** Реализация на Java процедуры CustomerInsert для галереи View Ridge * Процедура принимает в качестве параметров имя клиента (CustomerName). * его код региона (AreaCode). номер телефона (Local Number) и национальность * художников, которые его интересуют (Nationality). Добавляет нового клиента. * если его еще нет в базе данных, и затем ассоциирует данного клиента со всеми * художниками указанной национальности, добавляя соответствующие строки * в таблицу пересечений. */ public static void main (String [] args) { if (args.length < 4) { System.out.printin ("Предоставленных данных недостаточно"): return: } String varName = args[O]; String varAreaCode = args[l]; String varLocalNumber = args [2]; String varNationality = args[3]: InsertData (varName. varAreaCode. varLocalNumber. varNationality) : } public static void insertData (String varName. String varAreaCode. String varLocalNumber. String varNationality) { System.out.printin ("Добавляется строка для" + varName): try { // Загрузка класса драйвера JDBC от Марка Мэтьюса // mm.mysql.jdbc-l.2c Class. forNameCorg.gjt. mm. mysql. Driver") -newInstanceO : // соединяемся с базой данных vrl как пользователь dkl. без пароля String connString = "jdbc:mysql:/Vlocalhost/" + "vrl" + "?user=dkl": System.out.printin ("Попытка установления соединения с ” + connString): Connection conn = DriverManager.getConnection(connString): // Соединение установлено. Далее идет проверка на дублирование данных. Statement stmt = conn.createStatement О ;
JDBC 661 String varSQL = "SELECT Name "; String varWhere = "FROM CUSTOMER WHERE Name= varWhere = varWhere + varName + AND AreaCode = varWhere = varWhere + varAreaCode + "' AND PhoneNumber - varWhere = varWhere + varLocal Number + ...; varSQL = varSQL + varWhere; ResultSet rs = stmt .executeQuery (varSQL) ; while (rs .next 0 ) { // Имеются дублирующиеся данные System, out printin ("Указанный пользователь уже имеется в базе. Изменений не произведено.”); rs. close () ; stmt, close О : conn, close О : return; } // Можно добавлять новые данные varSQL = "INSERT INTO CUSTOMER (Name. AreaCode. PhoneNumber)"; varSQL = varSQL + " VALUES ('" + varName + varSQL = varSOL + varAreaCode + varSQL = varSQL + varLocal Number + •••)"/• int result = stmt executeUpdate (varSOL). if (result == 0) { System.out.printin ("Ошибка при вставке"): rs.close () : stmt.close 0 : conn.close () ; return; } 7 Обновление прошло успешно: теперь нужно добавить строки в таблицу // пересечений. Для этого получаем идентификатор нового клиента varSOL = "SELECT CustomerlD" + varWhere; rs = stmt.executeQuery(varSOL) ; String varCid While (rs.next 0) { varCid = rs getString(l) ; if (varCid == "0" ) { System.out.printing"He удается найти идентификатор нового клиента ) . rs.closeO : stmt.closed ; conn.closedO : return. // Теперь добавляем строки в таблицу пересечений varSQL - "SELECT ArtistID FROM ARTIST WHERE Nationality = + varNati onal 1 ty + продолжение^
662 Глава 14. JDBC, Java Server Papes и MySQI Листинг 14.2 (продолжение) String varlnsertStart - "INSERT INTO CUSTOMER ARTISTJNT (CustomerlO. ArtistID) VALUES (" *+ varCid +". : String varlnsertEnd - rs = stmt.executeQuery (varSQL) : System.out.println("Добавляются записи в таблицу пересечений для клиента" "+ varCid) : while (rs.next О ) { result = stmt.executeupdate (varlnsertStart + rs getStringd ) + varlnsertEnd) : } // Очистка rs. closed ; stmt, closed : conn, closed ; } catch (Exception e) { e.prtntStackTraced : Как вы помните, эта процедура имеет четыре параметра: имя нового клиента, код региона, местный номер телефона и национальность всех художников, рабо- тами которых интересуется данный клиент. Эти параметры принимаются про- цедурой main и передаются методу InsertData. В принципе метод InsertData здесь не нужен: мы могли бы вместить все в один метод, как в предыдущем примере. Отдельный метод создается потому, что в следующем разделе мы будем преобра- зовывать его в класс Java bean. Это преобразование будет легче выполнить, если данный метод будет выделен. Сначала метод InsertData загружает драйверы и создает строку соединения с базой данных vrl для пользователя dkl. Затем он производит проверку на пред- мет присутствия записи о данном клиенте в базе данных, запрашивая из vrl стро- ки с заданным именем, кодом региона и номером телефона. Если такая строка находится, выводится сообщение, и набор строк, оператор и соединение закры ваются. В противном случае в таблицу CUSTOMER вставляется новая строка. Столбец CustomerlD, являющийся суррогатным ключом таблицы CUSTOM определен в базе данных ключевым словом AUTO_INCREMENT. Таким образом, зна- чение этого столбца задавать не требуется: СУБД MySQL задаст его сама. Если вставка оказалась успешной, переменная result не должна равняться н}лкх если это не так, значит, во время обновления произошла ошибка. В этом случа^ выводится предупреждающее сообщение, и все объекты очищаются. Если оши о не произошло, значение CustomerlD считывается из базы данных, а затем в та л» цу CUSTOMER_ARTIST_INT вставляются строки. Логика здесь весьма напо11н^г логику хранимой процедуры Customerinsert в версии для Oracle и SQL На этом этапе переменная result не проверяется на нулевое значение: в совершенной версии этой программы такая проверка производилась бы. вы программируете на Java, то знаете, что все выводы сообщений об ош
Java Server Pages 663 И очистку объектов нужно выполнять с помощью исключений. Здесь мы опустим обсуждение этих вопросов и сосредоточимся на том, что непосредственно связа- но с базами данных. Теперь, после краткого введения в JDBC, мы обсудим использование этой технологии в Java Server Pages. Java Server Pages Java Server Pages (JSP) - это продукт, предоставляющий возможность создания динамических веб-страниц с помощью HTML, XML и языка программирования Java. Java Server Pages внешне очень походит на Active Server Pages, по это сходство обманчиво, поскольку в основе этого продукта лежит совсем другая технология. JSP и ASP схожи в том, что в обоих случаях HTML смешивается с программным кодом. Но в ASP программирование ограничено сценарными языками, подобными VBScript или JScript, а в JSP программирование осуществляется па Java и только на Java. Таким образом, разработчик веб-страниц получает в свое распоряжение всю мощь полноценного объектно-ориентированного языка программирования. Поскольку Java является машинно-независимым языком, JSP-страницы также машинно-независимы. Используя JSP, вы не ограничены рамками Windows 2000 и IIS. Одну и ту же J SP-страницу можно запустить на сервере под управлением Linux, Windows и других операционных систем. Официальную спецификацию JSP можно найти по адресу http://java.sun.com/ products/jsp. JSP-страницы и сервлеты JSP-страницы преобразуются в стандартный язык Java и затем компилируются, как обычные Java-программы. В частности, они преобразуются в сервлеты Java, то есть в подклассы класса HttpServlet. Таким образом, код JSP-страницы имеет доступ к объектам, представляющим HTTP-запросы и их результаты, к их мето- дам и другим функциям HTTP. Поскольку JSP-страницы преобразуются в подклассы сервлетов, в них не требу- ется создавать полноценные Java-классы или методы. Вы можете просто вставлять фрагменты Java-кода там, где пожелаете, а при синтаксическом анализе страни- цы они будут корректно помещены в подкласс сервлета. Так, например, следую щий фрагмент будет отлично работать в JSP-страиице без всякого дополнитель- ного Java-кода: String раНуНате="карнавал"; partyName - partyName.toUpperCaseO: Out printin ("Приходите на наш " + partyName): %> В результате обработки этой части JSP-страницы в окне браузера появится Иддиисъ «Приходите на наш КАРНАВАЛ» Кстати, обратите внимание, что Java-кпд Помещается между <% и *», как п код па VBScript или JScript в ASP страницах
664 Глава 14. JDBC, Java Server Рацеа и MySQL Чтобы использовать J$P страницы, иеб-хирисp должен подл» ржииахь снеццфи кацни Java servlet 2.1+ и Java Server Pages 1.0’. Список серверов, под/херживающия эти спецификации, вы можете наши ио адресу http://java.sun.com/products/servtet/ industry.html. Есть по крайней мере пя гь-шссть подходящих вариантов. В остав- шейся части главы мы будем использовать для .л их целей сервер Apache Tomcat, Apache Tomcat Веб-сервер Apache не поддерживает сервлеты. Однако фонд Apache и корпора- ция Sun выступили совместными спонсорами проекта Jakarta, в рамках которого был создан обработчик сервлетов под названием Apache Tomcat. Исходные тек- сты и двоичный вариант Tomcat можно найти на сайте проекта Jakarta по адресу http://jakarta.apache.org. Tomcat представляет собой обработчик сервлетов, который может работать в связке с Apache или как автономный веб-сервер. Возможности Tomcat как веб- сервера ограничены, поэтому в автономном режиме он обычно используется только для тестирования сервлетов и JSP-страниц. В коммерческих приложени- ях Tomcat следует использовать совместно с Apache. Если Tomcat и Apache работают отдельно на одном веб-сервере, они должны использовать разные порты. По умолчанию для веб-сервера предназначен порт 80, и обычно Apache использует именно этот порт. При использовании Tomcat в авто- номном режиме для него обычно выделяется порт 8080, хотя номер порта, разу- меется, можно изменить. В приведенных ниже примерах Tomcat использует порт 8080 Эти примеры запускались в закрытой интрасети, где машине, на которой работал Tomcat, был присвоен IP-адрес 10.0.0.3. Таким образом, чтобы вызвать страницу somepage.jsp, в поле адреса браузера нужно ввести строку http://10.0.0.3:8080/somepage.jsp. Настройка Tomcat для обработки JSP При установке Tomcat для него будет создана структура каталогов, куда необхо- димо будет поместить библиотеки классов и веб-страницы. Для Tomcat версии 3.1 библиотеки классов следует помещать в каталог <install-dir>/lib, а JSP-страницы — в каталог <nstall-dir>/webapps/ROOT/WEB-INF/classes, где <install-dir> - это каталог, в который устанавливается Tomcat. В Linux менеджер пакетов RPM по умолчанию устанавливает Tomcat в каталог /usr/local/jakarta-tomcat. Соответственно, библиоте- ки классов в этом случае нужно поместить в каталог /usr/local/jakarta-tomcat lib. а JSP-страницы — в каталог /usr/local/jakarta-tomcat/webapps/ROOT/WEB-INF/classes. Если вы устанавливаете Tomcat в другой операционной системе или вообще уста навливаете другой обработчик сервлетов, стоит обратиться к документации. Устанавливая файлы классов в подкаталог lib, нужно иметь в виду маленькш нюанс: Tomcat создает свою переменную CLASSPATH при запуске. Поэтому, посте того как вы установите новый файл класса в каталог lib, вы должны останов! ь и перезапустить Tomcat, чтобы он смог увидеть этот файл. Если же вы прос скопируете новый файл в подкаталог lib без перезапуска Tomcat, вы получи исключение Class not found (класс не найден). (Поверьте мне. я знаю это-)
Java Server Pages 665 Все приведенные ниже JSP-страницы используют драйверы MySQL mm.mysql. Чтобы работа с этими драйверами стала возможной, необходимо поместить в под- каталог lib библиотеку класса соответствующего драйвера. Для примеров этой главы использовалась библиотека mm_unconip.jar. На рис. 14.2 изображена схема процесса компиляции JSP-страниц. Получив запрос на обработку JSP-страницы, Tomcat (или другой обработчик сервлетов) находит скомпилированную версию этой страницы и проверяет, является ли данная версия текущей. Для этого он ищет некомпилированную версию страни- цы с более поздней датой и временем, чем скомпилированная страница. Если страница не является текущей (нашлась более поздняя некомпилированная страница), производится синтаксический анализ новой страницы, после чего она преобразуется в исходный Java-файл, который затем компилируется. Получен- ный сервлет загружается и выполняется. Если же скомпилированная JSP-стра- ница оказывается текущей, то она загружается в память и выполняется. Если JSP-страница уже находится в памяти, обработчик просто выполняет ее. Запрос JSP-страницы Отклик JSP-страницы Рис. 14.2. Процесс компиляции JSP-страницы
666 Глани 14. JDBC, Java Server Радев и MyS<X (Междх прочим, у riiKoit ан и>м<п оческой компиляции е* п, один ,, если вы сделаете синтаксические ошибки и забудете протес гирощнгь свои СТря пицы, то первый пользователь, обратившийся К этим страницам, Получит <хюб- щспие об ошибках компиляции.) В отличие от CGl-фанлов и некоторых других неб серверных upoiрамм, в случае одновременно в памяти находится пс болы одной JSP-ripaiiMUM Более loro, страницы выполняются одним из потоков Тonical, а не независимым пронес сом. Это означает, что для выполнения JSP-страницы требуется гораздо меньше памяти и процессорного времени, чем для выполнения сравнимого но функцио- нального I СG 1-cnenapi 1я. * 2 4 Примеры JSP-страниц В этом разделе описываются две простые JSP-страницы. Первая страница пред- ставляет собой JSP-версию класса GeneralTable из листинга 14.1. Вторая реализует логику работы метода insertData (см. листинг 14.2) в классе Java bean, который за- тем вызывается из другой JSP-страницы. GeneraiTable.jsp В листинге 14.3 приведен текст JSP-страницы, выводящей содержимое любой таблицы из базы данных MySQL под названием vrl. Эта страница по своему форма- ту и логике работы очень напоминает страницу GeneralTable.asp (см.листинг 12.4). Предполагается, что пользователь передает странице имя таблицы в качестве па- раметра Листинг 14.3. GeneraiTable.jsp <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!- Example of Database Access from a JSP Page -> <W page import="java.sql .*" <HTML> <HEAD> <TITLE>Table Display Using JDBC and MySQL</TITLE> <META NAME="author" CONTENT="David Kroenke"> <META NAME=”keywords" CONTENT="JSP. JDBC, Database Access"> <META NAME=”description" CONTENTS An example of displaying a table using JSP."> <LIHK REL-STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H2>Database Access Example</H2> <%. String varTableName= request.getparameter ("Table') : varTableName = varTableName.toUpperCaseO • £> <H3>Showing Data from MySQL Database vrl</H3> ’ <« try { // Загрузка драйверов JDBC Марка Мэтьюса Class.forName C'prg.gjt.mm.mysql .Driver").newlnstanceO ; Ъ A A А Л
Java Server Pages 667 Устанавливаем соединение с базой данных vrl как пользователь dkl String connString = "jdbc:mysql://localhost/" + "vrl” + "?user=dkl"; Connection conn = DriverManager.getConnection(connString) ; // Получаем rs и rsMeta для оператора SELECT Statement stmt = conn.createStatement 0 : String varSQL = "SELECT * FROM " + varTableName; ResultSet rs = stmt.executeQuery (varSQL) ; Result SetMetaData rsMeta = rs.getMetaData () : «> <TABLE BORDER-1 BGCOLOR=#ffffff CELLSPACING=5xF0HT FACE="Arial" COLOR=#OOOOOD > <CAPTION><B><X=va rTa bl eName %></В></CAPT10N></ FONT> <THEAD><^ String varColNames int varColCount = rsMeta.getColumnCount () ; for (int col =1; col <= varColCountO: col++) { X><TH BGCOLOR=#cOcOcO BORDERCOLOR=#QOOOOO ><FONT SIZE=2 FACE ="Ar1al” COLOR=#DOOOOO ><^=rsMeta.getColumnName(col)%></FONT>&nbsp: </TH> <3 }X> </TR> </THEAD> <TB0DY><X while [rs.next ()) { 2><TR VALIGN=TOP><^ for (int col = 1: col <= varColCount: col++) { $><TD BDRDERCOLOR=#COCOCO ><FONT SIZE=2 FACE="Arial" COLOR=#OOOOOD ><fc=rs.getString(col)^><BR></FONT></TD> } } // // Очистка rs. closed : Stmt, closed ; conn, closed ; } catch (ClassMotFoundException e) { out println("Driver Exception " + e) . </TR> </TBOCY> <TFOOT</TFOOT> </TABLE> </B0OT> «/HTML- На рис 14 3 показаны |кзультагы вызова это» страницы из браузера Internet ExpUnu «„«„ЫОТ..1Х. 1ЮД упрдвлепием w„,do»s 2000. Сш. СТР»НЩВ о6|мба-
668 Глава 14. JDBC, Java Server Pages и MySQL тывалась Tomcat на компьютере под управлением Linux. Обратите внимание обращение к порту 8080, в реальной системе Tomcat рабопщ бы вместе с Аг ь* на заданном по умолчанию порте 80, и указывать номер порта не требопа яосьб * 40^ Ct a rat В a ЙИЦ 9 ‘3 п гезультат выз°ва страницы GeneralTable java.sqL Затем с помошмп^ш ВЫЗЬ1Вает каталог страниц, загружая библиотеку параметр, содержащий имя табТ 9etParameter нтТР-объекта request считывается верхнего регистра. Дэпрр Q . ИЦЫ' 1 Ртученная строка преобразуется в строку тинге 14.1, и создается со а1ружаются классы JDBC, как это делалось в лис- Остальной код тот же 11ТГ,еДИНеНИе с ^аз°й данных vrl для пользователя dkl. ров HTML, используемых ’ 1 ~ °” п₽осто разбросан среди операто- Опять-таки эта страница ОДЙ результатов- GeneralTable.asp, приведенную™*^* обманчиво похожей на свою ASP-версию, что вместо ADO и ODBC ГЛаве Разница заключается не только в том, будет сколи ирована в I ПОЛЬЗУется JDBC. Более важно то, что эта страница и будет работать 6bK^eJ P°rpaMMy’ а «дельно, станет переносимой
669 Java Server Pages CustomerlnsertUsingBean.jsp Поскольку в JSP страницах используется Java, разработчик имеет в своем распо- ряжении все возможности объектно-ориентированного языка программирования. Это означает, чго J. -страницы могут вызывать предварительно скомпилиро- ванные объекты. Это важно и полезно по множеству причин. Во-первых, это от- деляет друг от друга задачи написания программной логики и генерации HTML- кода. Таким образом, в организации работа над этими двумя существенно раз- личными задачами может быть поручена двум разным группам. Во-вторых, это позволяет реализовывать логику в независимых модулях с возможностью их по- вторного использования, а также обеспечивает многие другие преимущества, свя- занные с инкапсуляцией. Наконец, это уменьшает сложность поддержания сайта. (Если вы не являетесь Java-программистом, можете пропустить следующий абзац. Что касается классов Java bean — просто вообразите себе Java-класс с при- мерным поведением, который не стыдно показать мамочке.) Говоря простым языком, класс Java bean — это класс, обладающий тремя свой- ствами. Во-первых, у него нет открытых (public) переменных. Во-вторых, обра- щение ко всем постоянно хранимым значениям происходит с помощью методов с названиями вида get<xxx> и set<xxx>. Например, значение myValue считывается с помощью метода getmyValue() и задается с помощью метода setmyValue(). В-треть- их, класс Java bean должен либо не иметь конструктора вообще, либо иметь один явно определенный конструктор без аргументов. В листинге 14.4 показан класс Java bean под названием CustomerlnsertUsingBean. Этот класс имеет метод, реализующий логику работы процедуры Customerinsert базы данных галереи View Ridge (да, это опять она! Но в последний раз). Этот класс имеет четыре постоянно хранимых значения. newName, newAreaCode, newLocalNumbe и newNationality. Для каждого из этих значений определены два метода доступа — getXXX и setXXX. У класса нет ни открытых постоянно хранимых значений, ни конструктора. Следовательно, класс CustomerlnsertUsingBean удовлетворяет опре- делению класса Java bean. Листинг 14.4. Класс Customer!nsertBean Import Java.Ю.*; import java sql *: public class CustomerlnsertBean { /** Класс Java bean для процедуры Customer Insert базы данных View Ridge. * Доступ к постоянным значениям осуществляется с помощью * методов getxxx и setxxx. ★ ★ ★ * flmupfivoa добавляет нового клиента, если его еще нет^в базе данных, аАатемАссоциирует его со всеми художниками выбранной национальности, вставляя соответствующие строки в таблицу пересечении private String newName - "unknown": private String newAreaCode -
670 Глава 14. JDBC, Java Server Pages и MySQL Листинг 14.4 (продолжение) private String newLocalNumber ~ ""; private String newNationality - : public String getnewNameO { return (newName) : } public void setnewName (String newName) { if (newName != null) { this.newName = newName: } el se { this.newName = "unknown": } public String getnewAreaCode () { return (newAreaCode) ; s } public void setnewAreaCode (String newAreaCode) if (newAreaCode !=null) { this.newAreaCode = newAreaCode; } else { this.newName = "” ; public String getnewLocalNumber () { return (newLocalNumber) ; public void setnewLocalNumber (String newLocalNumber) if (newLocalNumber != null) { this.newLocaI Number = newLocalNumber: } else { this.newName = public String getnewNationality () { return (newNationality) ; public void setnewNationality (String newNationality) if (newNationality != null) { this.newNationality = newNationality } else { this.newName =
Java Server Pages 671 public String InsertDataO { try { // Загрузка драйверов JDBC Марка Мэтьюса // mm.mysql.jdbc-1.2c Class.forName ("org.gjt.mm.mysql.Driver") newlnstance () ; / Устанавливаем соединение с базой данных vrl как пользователь dkl. без пароля String connString = "jdbcrmysql://localhost/” + "vrl" + “?user=dkl"; Connection conn = DriverManager.getConnection(connString) ; // Соединение установлено. Далее идет проверка на дублирование данных. Statement stmt = conn.createStatement ( ) ; String varSQL = "SELECT Name String varWhere = "FROM CUSTOMER WHERE Name= : varWhere = varWhere + newName + AND AreaCode = : varWhere = varWhere + newAreaCode + "' AND PhoneNumber = varWhere = varWhere + newLocalNumber + ...: varSQL = varSQL + varWhere: ResultSet rs = stmt.executeQuery (varSQL) ; while (rs.next ()) { // Имеются дублирующиеся данные. rs.closed ; stmt.closed : conn.closed ; return ("Данные дублируются - никаких действий не предпринято “): } И Все в порядке, теперь можно добавлять новые данные varSQL = "INSERT INTO CUSTOMER (Name. AreaCode. PhoneNumber} varSQL = varSQL + ’ VALUES C" + newName + "’. varSQL = varSQL + newAreaCode + "'. varSOL - varSQL + newLocalNumber + ’”)" : int result - stmt executeUpdate (varSQL): if (result “ 0) { // Ошибка при вставке rs closed ; stmt closed : conn closed : return ("Ошибка при вставке"): } // г, T„non. нужно добавить строки в таблицу пересечений // Обновление прошло успешно, теперь нужно дои Для этого получаем идентификатор нового клиента varSQL • "SELECT CustomerID " * varWhere, n • stmt executeQuery (varSQL) , npofatwrHue#
672 Глава 14. JDBC. Java Server Pages и MySQL Листинг 14.4 (продолжение) String varCid while (rs.next 0 ) { varCid - rs.getString(l) : if (varCid ~ "0" ) { // He удалось получить идентификатор нового клиента rs.closed : stmt.closed : conn.closed : return ("He удается найти нового клиента после вставки"): } } // Теперь добавляем строки в таблицу пересечений varSQL = "SELECT ArtistID FROM ARTIST WHERE Nationality = + newNationality +...: String varlnsertStart = "INSERT INTO CUSTOMER_ARTIST_INT (CustomerlD. ArtistID} VALUES *(” + varCid +". String varlnsertEnd = rs = stmt.executeQuery (varSQL): while (rs.nextd) { result = stmt.executeUpdate (varlnsertStart + rs.getString(l) + varlnsertEnd): // Очистка rs.closed ; stmt.closed : conn.closed ; return ("Success") ; catch (Exception e) { return ("Exception: " + e ): } Процедура обновления реализована в методе под названием InsertData. Этот ё /г метод идентичен методу InsertData из листинга 14.2. На рис. 14.4, показана форма, в которую вводятся данные нового клиента. HTML-страница для этой формы изображена в листинге 14.5. Обратите внимание, что тег FORM ACTION имеет значение CustomerlnsertUsingBean.jsp. Также обратите внимание, что текстовым полям даны имена newName, newAreCode, newLocalNumber и newNationality. Это имеет значение, потому что при нажатии кнопки Add Customer (Добавить клиента) странице CustomerlnsertUsingBean.jsp передаются параметры, содержащие эти имена. Как вы увидите, JSP может осуществлять привязку вход ных параметров к одноименным свойствам объекта, если это потребовать.
Java Server Pages 673 •'4»» • .' аУЛуЛ'Х-.» „V..'. .< .•«''"У'- лмммюпум».v.w,.<a <w<-y«v<- - Sg]t»ie.,: ;-,V ® Мем!®' йгй Рис. 14.4. Вид формы для ввода данных о новом клиенте в окне браузера Листинг 14.5. НТМЦ-код формы для ввода данных о новом клиенте <HTML> <HEAD> <МЕТА HTTP-EQUIV="Content-Type" CONTENT="text/html“> <TITLE>Table Display Form</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> i A 1 <BODY> ft J <FOBM METHOD-"post" ACTION="CustomerInsertUsingBean.jsp"> <₽><STRONG><FONT color=purple face="" size=5>&nbsp: Snbsp: View Ridge Gal 1 ery</Ff JNT></STRONG> <Mnbsp &nbsp- &nbsp <strong><font color=”purple" face size="4"> New, Customer Form</tont></strong><P><font style="background color: #FDF5EC color*"forestgreen" face>&nbsp. Snbsp: Rnbsp: Name &nbsp,ftnbsp: «/fontxFONT style-"BACKGROUND-COLOR: #FDF5EC -,&nbsp. Шр fcnbsp ftnbsp &nbsp;&nbsp &nbsp &nbsp &nbsp 8-nbsp: Knbsp; &nbs p. fenbsp. &nbsp. Snbsp, Snbsp. Knbsp: &nbsp; &n£sp; &nbsp: ^nbsp: Anbsp: &nbsp: </FQHT><INPur 1d«newName name»newNarne></P>
674 Глава 14. JDBC, Java Server Paces и MySQI, Листинг 14.5 (продолжение) <P>8nbsp:<font style-"background color: #FDF5EC” col or-’’forestgreen’ face>&nbsp; ftnbsp: &nbsp :AreaCode<font style-"background color #FDF5E6“>: 8nbsp. Rnbsp. 8nbsp:</font>8nbsp. ftnbsp: &nbsp. &nbsp, &nbsp, 8nb?o Snbsp: &n bsp: &nbsp: Rnbsp; &nbsp: &nbsp; &nbsp; &nbsp, ftnbsp, Anbsp. jnbjp </fontxINPUT id=newAreaCode name-newAreaCode size-"6"x/p> <P><font style="background-color: #FDF5EC” col or-"forestgreen" face>8nbsp: Rnbsp: 8nbsp: Phone: &nbsp: Snbsp: &nbsp: &nbsp: &nbsp: Rnbsp: &nbsp, 8nbsp: &nbsp; &nbsp. Snbsp; Rnbsp; Snbsp: finbsp; Snbsp: Snbsp; Snbsp :&nbsp; &nbsp &nbsp. ftnbsp Snbsp: &nbsp; &nbsp: &nbsp. Snbsp; </font><INPUT 1d=newLocalNumber name=newLocal Number Size="20”>8nbsp; &nbsp &nbsp:8nbsp;8nbsp; ftnbsp: Rnbsp: &nbsp:</P> <P>8nbsp: &nbsp: &nbsp: <font style="background-color : #FDF5EC" color"forestgreen" face>Nationality Of Artists: &nbsp; &nbsp; </font>8nbsp; 8nbsp; <INPUT id=newNatTonality name=newNationality size="17"></P> <P>8nbsp;<F0NT style-"BACKGROUND-COLOR: #FDF5EC"> &nbsp &nbsp. Snbsp. </FONT>finbsp: Rnbsp: 8nbsp: Rnbsp <FONT style="BACKGROUND- COLOR: #FDF5EC“> <INPUT 1d="subm1tl name=subm1tl type=subra1t value="Add Customer” >8nbsp; &nbsp: &nbsp: <INPUT id=resetl name=resetl type=reset value="Reset Values”></FONTx/p> </FORM> </BODY> </HTML> JSP-страница CustomerlnsertUsingBean.jsp приведена в листинге 14.6. Важную роль в этой странице играют два оператора: <jsp:useBean id="insert” class’"CustomerInsertBean"/> и <Jsp:setProperty name=”insert" property»”*’7> РУ JSP и связать1T01*ДаеТ команду загРУзить класс CustomerlnsertBean компилято- ^staU-dir>Zb^ ЧТ°бЫ ЭТ° 13аб0таЛ° ° ™ 31’ ° установлен Tomrat /WEB-IfiF/classes, где <instalt-dir> - это каталог, в котором bean под названием’ cTtXlnsertBeln d СК°“ПИЛированная?еРсия ^асса Java шью vTunuTi, rdkt г HsertBean.class. При стандартной установке с помо- INF/dasses ЭГ° УДСТ каталог /usr/Jocal/jakarta-tomcat/webapps/ROOT/WEB-
Jaya Server Pages 675 Листинг 14.6. CustomerlnsertUsingBean.jsp < DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN”> <!— Example of Database Access from a JSP Page page import=“java.sql.*" %> <HTML> <HEAD> <TITLE>Updating Using a Java Bean</TITLE> <META NAME=”author" CONTENT="David Kroenke"> <META NAME-'keywords" CONTENT="JSP. JDSC. Database Access"> <META NAME= "description" CONTENT="An example of invoking a bean and displaying results."> «LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <B0DY> <H2>Database Update Using JDBC from a Java Bean</H2> <H3>Processing the View Ridge Customer Insert for MySQL Database vrl</H3> cjsp useBean id="insert" class="CustomerInsertBean" /> <jsp;setProperty name=“insert” property""*" /> <? // Свойства класса были установлены предыдущим оператором. // теперь вызываем класс, чтобы выполнить вставку String result=insert.InsertDataО : if (result != "Success") { // Выводим сообщение об ошибке и завершаем процедуру out. print!п( "Ошибка" + result}; return; } // Данные успешно добавлены в базу. Выводим таблицу пересечений try { И Загрузка драйверов JDBC Марка Мэтьюса И Class forNameCorg gjt.mm mysql Driver") . newlnatance 0 : String connString = "jdbcmysql ://localhost/" + "vrl" + "?user=dkl". Connection conn - DriverManager.getConnection (connString) ; /7 Соединяем таблицы CUSTOMER и ARTIST через таблицу пересечений // Обратите внимание на использование синонимов для CUSTOMER.Name и ARTIST.Name Statement stmt - conn.createStatamentO String varSOL - "SELECT CUSTOMER Name Customer. ARTIST.Name Artist. Nationality ", VarSOL - varSOl + "FROM CUSTOMER. CUSTOMER_AR1 ISTJNI. ARI 1ST varSOL - varSQL + 'WHERE CUSTOMER CustomerlO - CUSTOMER_ARTIST_1NT CustomerlO продолжение^
676 Глава 14, JDBQ, Java Server Pages и MySQL Листинг 14.6 (продолжение) varSQL = varSQL + "ARTIST.ArtistID - CUSTOMER ARTIST INT.ArtistID", ResultSet rs = stmt.executeQuery(varSQL) : ResultSetMetaData rsMeta « rs.getMetaData() : X> <TABLE BORDER-1 BGCOLOR=#ffffff CELLSPACING=5><F00T FACE="Arial" COLOR #000000> <CAPTION><B>Customers and Interests</B></CAPTION></FONT> <THEAD> <TR><« String varColNames ="": int varColCount = rsMeta getColunnCountO for (int col =1; col <= varColCount: col++) { «xTH BGCOLOR=#cOcOcO BORDERCOLOR=#OOOOOQ ><FONT SIZE-2 FACE -"Arial" COLOR=#OOOOOQ >fc=rsMeta.getColumnName(col)%></FONT>&nbsp:</TH> <* }%> </TR> </THEAD> <TBDDY><X while (rs.next 0) { fcxTR VALIGN-TOPxt for (int col = 1: col <- varColCount: col++) { %> <TD BORDERCOLOR-#C0C0C0 ><FONT SIZE-2 FACE="Arial'' COLOR=#OOGOOO ><%—rs .getSt ring (col) XxBRx/FONT></TDx^ -rs,getString(col )&xBRx/FONTx/TD><X } } // Очистка rs. closed. stmt, closed: } catch (ClassNotFoundException e) { out.printIn ("Drinver Exception " + e)- }*> </TR> </TBODY> <TF0DTx/TF00T> </TABLE> </BODY> </HTML> Второй оператор предписывает синтаксическому анализатору JSP устанавли- вать свойства класса с использованием входных параметров формы. Символ * chiнализирует о том, что все свойства должны быть привязаны к одноименным параметрам. Этот короткий оператор заменяет собой следующую последователь- ность операторов: <jsp:setProperty name="insert" property-“newValue" value='<£= request getParameter( 'newName")X>7>
Java Server Pages 677 <jsp;setProperty name=" insert" property“"newAreaCode“ val ue« '<%= request. getParameter! "newAreaCode" )%>'/> <jsp:setProperty name="insert" property=”newt oca 1Numbe r" val ue='<%= request.getParameter("newLocalNumber" )£>'/> <jsp:setProperty name="insert" property="newNationality” value=' <^= request. getParameter ("newNati onal 1ty")£>' /> Разумеется, можно использовать обе версии. Па самом деле длинную версию использовать необходимо, если имена параметров формы отличаются от имен свойств объекта. В листинге 14.6 метод, InsertData вызывается при помощи следующей строки: String resultsnsert.InsertDataO: Еслц.метод возвращает значение, отличное от Success, выводится сообщение об ошибке. В противном случае па экран выводится соединение таблиц CUSTOMER, CUSTOMER_ARTIST_INT и ARTIST аналогично тому, как это делается в листинге 14.L Результат представлен на рис. 14.5. Рис 14 0. Результат вызова страницы CustomeilnsertUsinoBean jsp
678 Глава 14. JDBC, Java Server Pnpos и MySQL Эго было очень краткое введение в раграбитку JSI’-i границ. Многие вопрос остались за рамками нашего изложения. Подробнее о сервлетах и Java Server Pages можно прочитать в специальной литературе. MySQL MvSQL — это свободно распространяемая СУБД с открытыми исходными тек- стами, работающая под управлением UNIX, Linux и Windows. Исходные тесты и бинарные файлы MySQL можно загрузить с сайта MySQL по адресу http:// www.mysql.com. Примеры этой главы запускались в MySQL для Linux, ио они будут работать и в других операционных системах. Плата за лицензию на установку MySQL не предусматривается, кроме случа- ев встраивания ее в коммерческое приложение. Более подробная информация содержится в лицензионном соглашении, которое можно найти на сайте MySQL В MySQL отсутствуют многие возможности, которые можно найти в коммер- ческих СУБД, подобных Oracle и SQL Server, и, если у вас есть доступ к одному из этих продуктов, стоит использовать их. Если же вы работаете с малым бюджетом или хотите принять участие в движении за свободное программное обеспечение, MySQL может быть хорошим выбором. В среде Linux/UNIX MySQL не только дешевле, чем Oracle и другие коммерческие продукты, но и легче в установке. В настоящее время есть несколько хороших книг, способных послужить руковод- ством по MySQL. Это может показаться забавным, но по причине своих ограниченных возмож- ностей в сфере управления транзакциями и протоколирования MySQL показы- вает очень высокое быстродействие в приложениях, целиком ориентированных на запрос. Есть Интернет-компании, которые для поддержки своих баз данных используют Oracle, но для публикации на веб-серверах загружают их в MySQL Ограничения MySQL MySQL версий 3.x не поддерживает представления, хранимые процедуры и триг- геры. Все это, однако, включено в список задач на будущее, поэтому стоит про- смотреть последнюю документацию на предмет того, не появились ли какие-то из этих функций в более новых версиях продукта. Второй момент касается ограничений внешнего ключа (ссылочной целостно- сти). Хотя эти ограничения воспринимаются MySQL при синтаксическом анализе как допустимые конструкции, никаких действий в связи с ними не предприни- мается. Это означает, например, что выражение ON CASCADE DELETE в ограничении внешнего ключа не будет воспринято как ошибка, однако каскадные удаления, вопреки ожиданиям, производиться не будут. Если обратиться к примеру с гале реей View Ridge, то синтаксический анализатор MySQL легко пропустит еле дующее ограничение: ALTER TABLE CL)STOMER_ARTIST_INT ADD CONSTRAINT CustomerlntFK FOREIGN KEY(CustomerJD) REFERENCES CUSTOMER ON DELETE CASCADE:
............- .....---------------------------------------MySQL 679 Но после удаления строки из таблицы CUSTOMER каскадного удаления не бу- дет, и придется выполнить его вручную. Работа с MySQL Чтобы запустить MySQL из командной строки, введите MySQL -и <имя_пользователя> -р У кажите дейст вующее имя пользователя. После этого вам будет предложено ввести пароль. Если вы используете учетную запись, которая не имеет пароля вы можете набрать MySQL -и <имя_пользователя> Чтобы увидеть, какие имеются базы данных, введите Show databases: Обратите внимание, что команды MySQL завершаются точкой с запятой. Кроме того, команды MySQL нечувствительны к регистру, но в именах пользо- вательских конструкций (таблиц, столбцов и т. д.) регистр имеет значение. Работа с существующей базой данных Для работы с одной из уже существующих баз данных введите Use <иня_базы_данных>: Например, для работы с базой данных vrl следует набрать Use vrl; Чтобы узнать, какие таблицы имеются в базе данных, введите Show tables: Метаданные таблиц выводятся с помощью команды describe, например Oeser be CUSTOMER: Теперь можно вводить любые стандартные операторы SQL. Операторы SELECT, UPDATE, INSERT и DELETE будут работать так, как и следует ожидать. Создание новой базы данных Чтобы создать новую багу данных, в< идите в MySQL с топ учетной записи, кото- рую вы хотите сдслагь владельцем повой базы. Затем введите Create Database <иня_ьновой_базы_данных>: Например, чтобы создагь базу данных с именем vr2, следует ввегтп Create database vr2: Совдав пу< тую базу да.ах, можно <|юрмнровагь ее структуру с помощью SQL- зтераторов CREATE, как мы дс ниш ранее В листинге 14.7 приведена последователь*
680 Глава 14. JDBC JavaSgrygrPagesи MySQl ность операторов, создающая структуру базы данных View Ridge. Всем суррОГат ным ключам дано свойство AUTO_INCREMENT. Этот тип данных ирсдставляе/ собг - поддерживаемую MySQL последовательность, которая начинается с едини п увеличивается с шагом один. Обратите внимание, что MySQL иоддерживде тип данных Year. Этот тип данных, являющийся четырехзначным целым числом используется для столбцов BirthDate и DeceasedDate таблицы ARTIST. Обратит внимание и на то, что ограничения внешнего ключа отсутствуют. Как уже гов рилось ранее, MySQL воспримет их как допустимые конструкции, но ничего будет с ними делать. Листинг 14.7. SQL-операторы, создающие базу данных View Ridge в СУБД MySQL CREATE TABLE CUSTOMER ( CustomerlD Int AUTOJNCREMENT PRIMARY КЕУ. Name varchar(25) NULL, Street varchar (30) NULL. City varchar(35) NULL. State varchar(2) NULL. Zip varchar(9) NULL. AreaCode varchar(3) NULL. PhoneNumber varchar (8) NULL) ; CREATE INDEX CUSTOMERJIameJDX ON CUSTOMER (Name) ; CREATE TABLE ARTIST ( ArtistID int AUTOJNCREMENT PRIMARY KEY. Name varchar(25) NOT NULL. Nationality varchar(30) NULL. Bi rthdate year NULL. DeceasedDate year NULL): CREATE UNIQUE INDEX ARTIST_Name_IDX ON ARTIST(Name): CREATE TABLE WORK! WorkID int AUTOJNCREMENT PRIMARY KEY. Desc ri pt1on text NULL. Title varchar(25) NOT NULL. Copy varchar(B) NOT NULL. ArtistID int NOT NULL): CREATE UNIQUE INDEX WORKJDJDX ON WORK (Title. Copy. ArtistID); CREATE TABLE CUSTOMER_ARTIST_INT ( ArtistID int NOT NULL. CustomerlD int NOT NULL): ALTER TABLE CUSTOMER ARTISTJNT ADD CONSTRAINT CUST ARTIST PK PRIMARY KEY ( ArtistID. CustomerlD ):
MySQL 681 CREATE TABLE TRANSACTION ( TransactionlD int AUTOJNCREMENT PRIMARY KEY DateAcquired date NOT NULL. AcquisitionPrice decimals.2) NULL. PurchaseDate SalesPrice CustomerlD WorkID В этой date null. decimal(7.2) NULL. int NULL. 1nt NOT NULL). cxi Me создается уникальный индекс по столбцам (Title, Copy ArtistID) таблицы WORK. Этот индекс предотвращает вставку в базу да... повторяющихся записей о произведениях. Это означает, что действия, выполняемые приведен пыми ранее Java-нрограммамп для предупрежден ня таких ситуаций, оказываю! ся ненужными. Они не приносят никакого вреда, разве чю чуть чуть снижаю! производительность. Тем не менее, как сказано в главе 7, всегда лучин1 но воз можности обеспечивать выполнение ограничений целоетио< ш в баю данных Показанные здесь операторы можно вводи и* в MySQL вручную По, если ли операторы записаны у вас в файле, их можно импортирован* н MySQL. Предно ложим, последовательность операторов, изображенная н лиегшпе 14.7, содер ЖИТСЯ в файле НОД именем VRSQL.txt. Чтобы ее выполнить, ниедтие в командной строке оболочки (не MySQL!) следующую команду: mysql -user-dkl -password=sesame < VRSQL.txt В результате запустится MySQL для пользин.псля dkl с паролем sesame и бу*- дуг выполнены содержащиеся в файле операторы. Настройка разрешений на доступ для JDBC Если вы понимаете ограничения MySQL, работа с этой СУБД не иредставляе! трудностей. Операторы SQL выполняются в точности так, как и следует ожидать. Есть, однако, одна маленькая особенность, о которой следует знать Соединения с JDBC обрабатываются по так, как все остальные пользовательские соединения. Чтобы понять, что в связи с этим следует делать, рассмотрим сначала словарь Данных MySQL. MySQL хранит метаданные в базе данных mysql. Особый интерес прсдставля ют в ней две таблицы: user и db. Ч тобы увидеть содержащиеся в них мшаданные, •и крой те базу данных mysql н введите команду describee именами них щблиц. Для просмотра списка пользователей и пх компьютеров введите на приглашение mysql следующее: Use mysql. SELECT Host. User TROM user. Для просмотра списка пользователей, пх компьютеров и баз данных, доступ- ных для них, введите SELECT Host, User, Db IRON db;
682 Глава 14, JDBC. Java Sarver Pagns и MySQL B качестве имени компьютера обычно фигурирует строка localhost имя коми», югера, на котором работает MySQl, пли имена других компьютеров Значение % означает, что данный нользонагель может устанавливать соединение с любой» компьютера. Исходя из этого, логично предположить, что программы JDBC, работающие на топ же машине, что и MySQL, в качестве имени компыогера будут иметь localhost Однако это не так. Дело в том, что для MySQL localhost обозначает соединение через сокет, тогда как в JDBC соединение устанавливается ио протоколу TCP/IP. Таким образом, если вы хотите установить соединение с помощью JDB( простей- шим (но наименее безопасным) методом будет предоставил» требуемой учетной записи доступ к базе данных с любой машины. Это делает оператор GRANT- GRANT ALL ON vrl.* TO dkl@"F IDENTIFIED BY "sesame": Этот оператор предоставляет полномочия доступа ко всем таблицам базы данных vrl пользователю учетной записи dkl с паролем sesame. Символ процента (%) означает, что dkl может устанавливать соединение с любого компьютера. Для большей безопасности его следует заменить конкретным IP-адресом. Выполнив этот оператор, запросите из таблицы db столбцы User, Host и Db, что- бы удостовериться, что ваш пользователь в качестве имени компьютера имеет %. Если это так, то вы можете соединяться с этой базой данных с помощью JDBC. Управление параллельной обработкой данных MySQL имеет ограниченную поддержку управления параллельной обработ- кой данных. В версии 3.0 отсутствует поддержка транзакций — соответственно, уровень изоляции транзакции тоже установить невозможно. Отсутствует также возможность отката транзакций. Приложения должны выполнять откат само- стоятельно при необходимости. MySQL использует блокировку чтения и записи на уровне таблицы. При вы- полнении оператора SELECT MySQL налагает блокировку чтения на все таблицы, указанные в операторе. Такая блокировка не даст другим сеансам произвести за- пись в эти таблицы, но чтению препятствовать не будет. При выполнении опера- торов INSERT, UPDATE и DELETE MySQL налагает блокировку записи на все затро- нутые ими таблицы. Такая блокировка не позволит другим сеансам ни читать, ни записывать данные. Результатом этой блокировочной стратегии является согла- сованность данных, считываемых и обновляемых отдельно взятым оператором, аким образом, все операции чтения и записи данных происходят правильно. Компенсировать отсутствие транзакций можно, отмечая предполагаемые рам- ки транзакций командами LOCK TABLES/UNLOCK TABLES Так, юследовательность операторов LOCK TABLES Tl. Т2. ТЗ WRITE; UPDATE TABLE Tl SET Coll=”xzy" WHERE Coll="abc UPDATE TABLE T2 UPDATE TABLE T3 ... прочие действия UNLOCK TABLES: зтой транзакции с таблицами Tl. T2. T3
_______________________________________________________MySQL 683 не позволит другим пользователям выполнить запись или чтение данных из таб- лиц Tl, Т2 и ТЗ, пока идет обработка транзакции. Все обновления между операто- рами LOCK п UNLOCK являются атомарными, поскольку выполняются до снятия какой-либо блокировки. К сожалению, при таком использовании блокировок для других пользовате- лей заблокированных таблиц работа остановится. Пока выполняется транзакция, ни один пользователь не сможет читать или записывать данные в таблицы Tl, Т2 и ТЗ. На период блокировки MySQL превратится в однопользовательскую систе- му по отношению к этим трем таблицам. Это, скорее всего, будет серьезной про- блемой, если транзакции являются длительными и если приложение производит много обновлений. В любом сеансе все таблицы должны блокироваться одновременно. Если тре- буется блокировка с более широким охватом, сеанс должен снять имеющиеся блокировки и заново наложить блокировки на большее число таблиц. Таким об- разом, ии у одного сеанса не может быть более одного активного оператора LOCK TABLES одновременно. Как вы помните из главы 9, эта стратегия исключает веро- ятность возникновения взаимной блокировки. «Грязное» чтение может быть возможно или нет, в зависимости от того, как написано приложение. В MySQL не предусмотрен откат, поэтому, если приложение не выполняет откат самостоятельно, «грязное» чтение возможно. Если же приложе- ние способно выполнять откат и если действия, откат которых требуется произ- вести, расположены между операторами LOCK TABLES и UNLOCK TABLES, «грязное» чтение невозможно. Однако, как уже говорилось, такая стратегия может привести к неприемлемо низкой пропускной способности. Наконец, если приложение делает откат, но не использует операторы LOCK и UNLOCK, то «грязное» чтение возможно. Резервное копирование и восстановление Возможности MySQL в сфере резервного копирования и восстановления ограни- чены. В MySQL есть утилита для сохранения базы данных и отдельных таблиц из нее. В некоторых случаях, однако, более быстрым и столь же простым методом является сохранение файлов базы данных на резервных носителях с помощью команд копирования операционной системы. MySQL ведет журнал выполняемых действии. Но этот журнал состоит из ко- манд и выполняемой работы, а не из исходных и конечных образов. Для вос- становления базы данных копируется более ранняя версия базы, и к ней при- меняются команды, записанные в журнале. Массовые изменения записываются в виде команд — в журнале указывается только имя файла, явившегося источни- ком изменений. Отдельные изменения не регистрируются. Кстати, если вы восстанавливаете базу данных после ввода ошибочного опе- ратора, например DROP TABLE CUSTOMER. не забудьте перед повторной обработкой журнала удалить из него этот оператор DROP В прогонном случае он будет выполнен диспетчером журнала, и вы верне- тесь туда, откуда пришли, — к отсутствующей таблице CUSTOMER.
684 Глава 14. JDBC, Java Server Раце и MySQI Заключительное слово о MySQL Насколько можно судить из этого раздела, сне гема MySQT лишена мши их воз можностеп п функции, имеющихся в современных СУБД Можег возникнуть но прос, зачем же она вообще нужна. Дело в том, что, как сказано ранее, гга СУБД распространяется свободно н имеет огкрьные исходны .• гекегы I ели вы хоти принять участие в проекте open source в области СУБД, MySQL будет хорошим выбором' Кроме того, MySQL проста и даже приятна в использовании. Имею- щиеся в ней возможности и функции реализованы хорошо. Создается впечатле- ние что сообщество разработчиков MySQL предпочитает делать немного, ио ка- чественно. Работать с таким продуктом - одно удовольствие. Резюме JDBC - это альтернатива ODBC и ADO, обеспечивающая доступ к базам данных для программ, написанных на Java. Драйверы JDBC существуют почти для каж- дой мыслимой СУБД. Корпорация Sun определила четыре типа драйверов. Драй- веры типа 1 обеспечивают мост между Java и ODBC. Драйверы типов 2-4 напи- саны целиком на Java. Драйверы типа 2 в связи между компьютерами полагаются на возможности СУБД, если таковые имеются. Драйверы типа 3 транслируют вызовы JDBC в независимый от СУБД сетевой протокол. Драйверы типа 4 пре- образуют вызовы JDBC в сетевой протокол конкретной СУБД. Апплет — это скомпилированная в байт-код программа на Java, которая пере- дается браузеру по HTTP и вызывается с помощью этого же протокола. Серв- лет — это Java-программа, работающая па сервере и отвечающая па НТТР-запросы. Драйверы типов 3 и 4 могут использоваться как для апплетов, так и для сервле- тов. Драйверы типа 2 могут использоваться только в сервлетах, и только если СУБД и веб-сервер находятся на одной машине или если СУБД самостоятельно обеспечивает связь между веб-сервером и сервером базы данных. Алгоритм использования JDBC состоит из четырех шагов: (1) загрузить драйвер; (2) установить соединение с базой данных; (3) создать оператор; (4) вы- полнить оператор. Библиотеки классов драйвера должны быть в CLASSPATH компилятора и виртуальной машины Java. Они загружаются в Java-програм- му с помощью метода forName. Соединение устанавливается с помощью метода getConnection объекта DriverManager. Строка соединения состоит из символов jdbc:, за которыми следует имя драйвера и URL базы данных. Операюры создаются с помощью метода createStatement объекта Connection Выполнение операторов производится методами executeQuery и executeUpdate объек- та Statement. Объекты ResultSetMetaData создаются при помощи метода getMetaData о ъекга ResuLtSet. JDBC позволяет выполня ть скомпилированные запросы и храни- мые процедуры с использованием объектов PreparedStatement и CalLableStatement. Технология Java Server Pages (JSP) позволяет создавать динамические веб- страницы с использованием HTML, XML и Java. JSP-страницы предоставляют в распоряжение разработчика всю мощь полноценного объекгно-ориептнровап- ного языка программирования. Ни VBScript, ин JavaScript в JSP использоваться не могут. JSP страницы компилируются в машинно-независимый бант-код.
Резюме 685 JSP-страницы компилируются в виде подклассов класса HttpServlet Следова- тельно, в JSP-страницу можно помещать как законченные Java-программы, так и фрагменты Java-кода. Чтобы работ с JSP-страницами была возможна, веб-сервер должен реализовывать спецификации Java Servlet 2.1+ и Java Server Pages 1.0+. Apache Tomcat — свободно распространяемый продукт с открытыми исходными текстами из проекта Jakarta — поддерживает эти спецификации. Tomcat может работать в связке с Apache или как автономный тестовый веб-сервер. При использовании Tomcat (или любого другого обработчика JSP) драйверы JDBC и JSP страницы должны помещаться в специальные каталоги То же са- мое относится и к классам Java bean, используемым JSP-страницами Получив запрос на обработку JSP-страницы, Tomcat сначала убеждается, что использует- ся самая новая версия страницы. Если обнаруживается более поздняя некомпи- лированная версия страницы, Tomcat автоматически производит ее синтаксиче- ский анализ и компиляцию. В его памяти одновременно находится не более одной копии JSP-страницы, и запросы на обработку JSP-страниц выполняются отдель- ным потоком обработчика сервлетов, а не отдельным процессом. Если требуется, Java-код в JSP-странице может вызывать скомпилированный класс Java bean. MySQL — это свободно распространяемая СУБД с открытыми текстами, ра- ботающая под управлением UNIX, Linux и Windows. Платить за лицензию на ее установку не требуется. MySQL может обеспечить весьма быструю обработку за- просов, но она не поддерживает представления, хранимые процедуры и триггеры. Ограничения ссылочной целостности могут быть определены, по они не будут реализовываться MySQL. MySQL поддерживает словарь данных в базе данных с именем mysql Для определения полномочий пользователей можно запросить таблицы user и db из этой базы данных. Для обращения к MySQL через JDBC учетной записи пользователя должен быть предоставлен доступ к базе данных либо с какого-нибудь компьютера, либо с IP-адреса, представляющего локаль- ный компьютер. MySQL предоставляет ограниченные возможности для управления параллель- ной обработкой. Транзакции не поддерживаются, поэтому нет операторов COMMIT и ROLLBACK и невозможно установить уровень изоляции. MySQL налагает блоки- ровки на уровне таблицы. Коллективная блокировка чтения налагается при вы- полнении операторов SELECT, а при записи налагается монопольная блокировка. Блокировка на уровне таблиц может привести к снижению пропускной способ- ности. Операторы, которые должны выполняться в рамках транзакции, можно окружать командами LOCK TABLES и UNLOCK TABLES. Взаимная блокировка предотвра- щается за счет того, что одновременно может быть активен только один оператор LOCK TABLES. «Грязное» чтение возможно, если некоторые приложения произво- дят 01 кат выполняемых действии, но не блокируют таблицы на время выполне- ния этих действий. Возможности MySQL в сфере резервного копирования н восстановления так- же ограничены. В MySQL имеется утилита, которая дополняет программы копи- рования операционной системы MySQL, ведет журнал выполненных команд. Этот жургыл не содержи! исходных н конечных образоц, н в него не записываются резулыагы массовых обновлений или удалений. Хотя MySQL имеет множество ограничений, она проста в тио ii>.iob,uhih, а те возможности и функции которые в ней реализованы, реализованы качественно.
686 Глава 14 JDBC. Java Server Pa и M I Вопросы группы I 1. Что необходимо для использования JDBC? 1. Как расшифровывается JDBC? 2. Какие четыре типа драйверов есть в JDBC? 3. Объясните назначение драйверов JDBC типа 1 4. Объясните назначение драйверов JDBC типов 2 4. 5. Данте определения терминов апплет и сервлет. 6. Объясните, как в Java достигается переносимость. 7. Перечислите четыре шага, из которых состоит работа с драйвером JDBC 8. Напишите оператор Java, загружающий драйверы mm.mysql, использован- ные в этой главе. 9. Напишите Java-оператор, устанавливающий соединение с базой данных с помощью драйверов mm.mysql. Пусть база данных называется CustData, имя пользователя — Lew, пароль — Secret. 10. Напишите оператор Java, создающий объект Statement (набор результатов). И. Напишите оператор Java, создающий объект ResultSet, который содержит столбцы Name и Nationality таблицы ARTIST, используя созданный ранее объект Statement с именем s. ДСяя 12. 13. 14. 15. 16. 17. 18. 19. 20 21. 22. Напишите Java-оператор, перебирающий набор результатов s, созданный в ответе на вопрос 12. Напишите Java-оператор, выполняющий обновление, при котором нацио- нальность художника по фамилии Jones меняется на French. Используйте созданный ранее набор результатов s. Как в вопросе 14 можно определить, успешным ли было обновление? Напишите Java-оператор, который создает объект, содержащий метадан- ные набора результатов, созданного в ответе на вопрос 12. Напишите последовательность Java-операторов, необходимую для вызова хранимой процедуры Customer_Delete. Будем предполагать, что процедура имеет три текстовых параметра: имя клиента, код региона и номер телефона. Пусть параметры процедуры имеют значения Mary Orange, 206 и 555-1234. Каково назначение Java Server Pages? Опишите различия между ASP- и JSP-страницами. Об ясните, как достигается переносимость JSP-страниц. По 1сму в JSP-страницы можно включать маленькие фрагменты Java-ко- да. очему для этого не требуется писать законченные Java-программы? Для чего предназначен Tomcat? Какие действия следует предпринять при стандартной установке Tomcat прежде чем использовать JSP-страницы, которые загружают классы JD) *5* 4Z <5
Вопросы группы 1 687 23. Что нужно сделать при подключении к Tomcat новых библиотек классов, чтобы эти библиотеки появились в CLASSPATH? 24. Опишите процесс компиляции и выполнения JSP-страниц. Можно ли ис- пользовать устаревшую страницу? Обоснуйте свой ответ. 25. Почему JSP-страницы предпочтительнее CGI-сценарпев? 26. Каким требованиям должен удовлетворять Java-класс, чтобы быть клас- сом Java bean? 27. Напишите директиву JSP, загружающую с именем CustomerDeleteBean класс Java bean. Дайте загруженному классу идентификатор custdel. 28. Напишите директиву JSP, присваивающую свойству Propl класса Java bean значение параметра формы Paraml. 29. Почему лучше давать свойствам объекта и параметрам формы одинако- вые имена? Напишите директиву JSP, связывающую свойства и параметры в этом случае. 30. В чем разница между вызовом класса Java bean из Java-программы и из Java-кода JSP-страницы? 31. При каких условиях вы стали бы использовать MySQL? 32. С каким типом работы отлично справляется MySQL? 33. Перечислите основные ограничения MySQL. 34. Как MySQL обрабатывает ограничения ссылочной целостности? 35. Какой SQL-оператор используется в MySQL для создания повой таблицы? 36. Что нужно иметь в виду, устанавливая соединение с MySQL с помощью JDBC? 37. Напишите команду MySQL, дающую пользователю с именем Lew пол ю- мочия на доступ к любой таблице базы данных CustData. Пусть паролем бу- дет Secret. 38. Опишите имеющиеся в MySQL возможности управления транзакциями. 39. Как MySQL использует блокировки чтения? 40. Как MySQL использует блокировки записи? 41. На каком уровне MySQL налагает блокировки? Каковы преимущества и недостатки такого подхода? 42. Покажите, как приложение может обеспечить атомарность транзакции с использованием операторов LOCK TABLES и UNLOCK TABLES. 43. В чем заключается недостаток стратегии, описанной вамп в ответе на во- прос 43? 44. Почему взаимная блокировка в MySQL невозможна? 45. При каких условиях в MySQL возможно «грязное» чтение? 46 Опишите имеющиеся в MySQL возможное ги для резервною копирования. 47 Каковы ограничения протоколирования в MySQL? 48 ( огласпо доводам автора, почему стоит использовать MySQL?
688 Глава 14 JDBC. Java Sei v«i Pa os и MySQL Вопросы группы II 49 Сравните между собой ASP и JSP. У кажи к < ильные; и слабые crop. «гы ждон технологии. При каких условиях вы отдали Гия предпо'гт. лие одной технологии перед другой? Насколько важна перенос имопьдля веб серев ров? Насколько большим недостаг ком является санис имси i с, от Мц rosofty Некоторые говорят, что выбор в пользу юй пли другой 1ехиолосии явля ется скорее вопросом личных предпочтений и ценноср-й, нежели чего-то другого. Согласны ли вы с .мим? $ 50. Перепишите класс Java bean, показан mail в листинге 14.4, чсобы он исполь- зовал исключения, а не возвращал значение result. Модифицируйте JSP- странпцу, чтобы она корректно обрабатывала лот класс. Чем получив- шийся класс лучше исходного? Проекты 1. Напишите Java-программу, использующую MySQL и драйверы mm.niysql, которыми мы пользовались в этой главе. Ваша программа должна реали- - -2 зовать логику работы хранимой процедуры CustomerlnsertWithTransaction, описанной в варианте для Oracle в главе 10 и в варианте для SQL Server 2. 3 4. 5. 6. в главе 11. Сделайте так, чтобы программа выводила те же результаты, что показаны в представлении CustomerPurchasesView. Запустите вашу програм- му в автономном режиме. Преобразуйте программу, написанную вами для проекта 1, в класс Java bean. Цацщците JSP-страницу, вызывающую этот класс. Найдите драйвер ODBC для Oracle и напишите Java-программу, устанав- ливающую соединение с версией базы данных View Ridge для Oracle и вы- водящую содержимое любой таблццы этой базы данных. Напишите Java- программу, вызывающую хранимую процедуру Customerinsert. Для вызова используйте JDBC-объект CallableStatement. ‘ Преобразуйте программу, написанную вами для проекта 3, в класс Java bean. Напишите JSP-страницу, вызывающую этот рласс. Найдите драйвер ODBC для SQL Server и нацишите Java-программу, уста- навливающую соединение с версией базы данных View Ridge для SQL Server и выводящую содержимое любой таблицы этой базы данных. Напишите Java-программу, вызывающую хранимую процедуру Customerinsert. Для вызова используйте JDBC-обьскт CallableStatement. Преобразуйте программу, написанную вами для проекта 5, в класс Java еап. Напишите JSP-страипцу, вызывающую этот класс.
Вопросы к проекту Twigs Tree 689 Вопросы к проекту FiredUp Создайте базу данных FiredUp в MySQL или Oracle. В MySQL вы не сможете за- давать ограничения ссылочной целостности; в остальном следуйте указаниям, приведенным в конце главы 10. 1. Напишите JSP-страницу, выводящую таблицу ГОРЕЛ KjA. 2. Напишите JSP-страницу, выводящую содержимое любой таблицы базы даннмЦуге^ир. За образец возьмите листинг 14.1. 3. Напишите JSP-страницу, позволяющую клиентам регистрировать своп го- релки. 4. Создайте класс Java bean, реализующий процедуру ввода данных о ремон- те горелки. 5. Напишите JSP-страницу, вызывающую класс Java bean, созданный в во- просе 4. За образец возьмите листинг 14.5. Вопросы к проекту Twigs Tree Создайте базу данных FiredUp в MySQL или Oracle. В MySQL вы не сможете за- давать ограничения ссылочной целостности; в остальном следуйте указаниям, приведенным в конце главы 10. 1. Напишите JSP-страницу, выводящую таблицу ВЛАДЕЛЕЦ. 2. Напишите JSP-страницу, выводящую содержимое любой таблицы базы данных Twigs Tree. За образец возьмите листинг 14.1. 3. Напишите JSP-страницу, позволяющую клиентам назначать выполнение работ на определенную дату. Следует вводить только дату и описание рабо- ты. Считайте, что сведения о владельце участка уже имеются в базе данных. 4. Создайте класс Java bean, позволяющий ввести данные о новом владельце участка. 5. Напишите JSP-страницу, вызывающую класс Java bean, созданный в во- просе 4. За образец возьмите листинг 14.5.
Глава 15 Совместное использование данных предприятия В предыдущих главах этой книги описывалась работа с базами данных в контек- сте персональных компьютеров и Интерпет-техпологий с использованием веб- сервера и сервера базы данных. Но на предприятиях используются также другие, более старые типы систем. Поскольку вам, возможно, придется с ними столк- нуться, в первой части этой главы мы кратко рассмотрим характеристики трех типов таких систем. Четвертый тип систем, который постепенно начинает исполь- зоваться в коммерческих приложениях, — это системы распределенной обработ- ки баз данных, которые мы также будем обсуждать здесь. И Oracle, и SQL Server поддерживают распределенную обработку баз данных. Данные являются важным активом организации — активом, который можно использовать не только для упрощения работы, по и для управления, планирова- ния, прогнозирования, стратегического анализа и т. п. К сожалению, во многих организациях, наряду с несомненным положительным эффектом от использо- вания баз данных, имеется сознание того, что в сфере анализа, планирования и других составляющих управления предприятием базы данных используются неэффективно В этой главе обсуждаются вопросы, представляющие важность для увеличения отдачи от средств, инвестированных в данные какого-либо пред- приятия, — загрузка централизованных данных, оперативная аналитическая об- работка данных (OLAP), хранилища данных и администрирование данных. Архитектуры корпоративных систем обработки данных Д ш обработки данных в масштабе предприятия используются несколько различ- ных архитектур. В прошлом наиболее распространены были системы удален- ной о >работки данных. Но по мере того как микрокомпьютеры стали появляться । и >исах и выросла их мощь в качестве серверов данных, возникли новые ар\и- • ектуры многопользовательских систем обработки данных. В этом разделе мы об- судим системы удаленной обработки данных, клиент-серверные системы, системы совмсснюго использования файлов и распределенные варианты этих систем
Архитектуры корпоративных систем обработки данных 691 Системы удаленной обработки Классическим методом поддержки многопользовательской базы данных явля- ется удаленная обработка (teleprocessing), при которой используются один компь- ютер с одним процессором. Вся обработка производится этим едина венным компьютером. На рис. 15.1 показана типичная система удаленной обработки (teleprocessing system). Пользователи работают с пеинтеллектуалы1ыми терминалами (или с мик- рокомпьютерами, эмулирующими такие терминалы), которые передают- сообще- ния о транзакциях и данные центральному компьютеру. Часть операционной системы, отвечающая за управление связью, принимает сообщения и данные и передает их соответствующим прикладным программам. Программы обраща- ются к СУБД, а СУБД выполняет операции с базой данных, используя ту часть операционной системы, которая отвечает за обработку данных. Когда транзак- ция завершается, подсистема управления связью возвращает результаты пользо- вателям, сидящим у терминалов. На рис. 15.1 показаны п пользователей, транзакции которых обрабатывают три различные прикладные программы. Поскольку па стороне пользователя интел- лектуальные устройства присутствуют в ограниченной степени (имеются в виду, естественно, терминалы), все команды форматирования вывода должны геперпро ваться процессором центрального компьютера и передаваться по линии связи. Это означает, что пользовательский интерфейс имеет текстовую ориентацию и прими- тивен по своей сути. Системы, подобные этой, называются системами удаленной Communications Lines' ОСУК= часть операционной системы, отвечающая за управление коммуникацией ПП = прикладная программа ОСуд = часть операционной системы отвечающая за управление данными Рис. 15.1. Связи между программами в системе удаленной обработки данных Ис горичс-с ки спсп-мы удаленной обработки были нои алыерп.и ивоп миогоиользовасельским системам баз данных Но м<}
692 Глава 15, Совместное использование дан| ух прндирия»и» улучшения соотношения цены н щхтп.пюдпгелыкхти для компьютрон и р част носгп, с появлением персональных комн moi еров, они были ныкчиены дружми системами, состоящими более чем на одного комнькнера. Клиент-серверные системы На рис 15.2 изображена схема одной из таких систем, которая носит название клиент-серверной системы (client-server system). В отличие oi системы уда- ленной обработки, в которой имеется только один компьютер, клиент серверная система состоит из множества компьютеров, объединенных в сеть. Одни компью- теры, называемые клиентами (clients), занимаются обработкой прикладных про- грамм. Другие компьютеры, называемые серверами (servers), занимаются обра- боткой базы данных. Пользователь, Пользователь 2 Пользователь г Клиентский компьютер л ОССЕТЬ - часть операционной системы, отвечающая за сетевую коммуникацию OCyB - часть операционной системы, отвечающая за управление данными Рис. 15.2. Клиент-серверная архитектура свой клиент»•^д;11°Ка3а11 пР”меР> 13 котором каждый из п пользователей имеет обрабатывает п- ^°МПЬ101еР’ обрабатывающий приложения, — пользователь Userl обрабатывает ‘ омпьгогсРе CLientl приложения API и АР2, пользователь L)ser2 оираиатывает приложение АР9 батывает приложения АР2 и АРЗ н “'°Тере Cl*.nt2’ а пользователь UserN обра- сервер базы данных. 3 К0МпьютсРе ClientN. Второй компьютер - это ент1ких“пьютеро^ разным Теорегически в роли клн yi выщупать большие ЭВМ или микрокомпьютеры.
Архитектуры корпоративных систем обработки данных 693 Однако из соображений стоимости функции клиентов почти всегда выполняют микрокомпьютеры. Точно так же в роли сервера может выступать компьютер любого типа, по по экономическим причинам функции сервера чаще всего вы- полняет микрокомпьютер. Клиенты и серверы соединяются в локальную (LAN ) или глобальную (WAN) сеть. Хотя редко случается, чтобы в качестве клиентских машин использовалось что-либо иное, кроме микрокомпьютеров, роль сервера иногда выполняется большой ЭВМ, особенно когда сервер должен иметь большую вычислительную мощность или когда из соображении безопасности и для большего контроля за базой данных размещение ее на микрокомпьютере представляется неуместным. Система на рис. 15.2 имеет один сервер, хотя это не всегда так. Различные серверы могут обрабатывать различные базы данных или предоставлять клиен- там другие услуги. Например, в фирме, занимающейся инженерными разработ- ками, один сервер может обрабатывать базу данных, а па другом могут работать системы автоматического проектирования. Если обработкой базы данных занимаются несколько серверов, то, чтобы та- кая система могла считаться клиент-серверной, каждый из серверов должен об- рабатывать свою базу данных. Если же два сервера обрабатывают одну базу дан- ных, такая система уже не может претендовать на название клиент-серверной, а назвать ее следует системой распределенной обработки базы данных. Системы совместного использования файлов Вторая многопользовательская архитектура представлена на рис. 15.3. В этой ар- хитектуре, которая носит название архитектуры с совместным использованием файлов (file-sharing), на пользовательских компьютерах находятся не только при- кладные программы, но и СУБД. В этом случае сервер является файловым серве- ром, а не сервером базы данных. Почти во всех системах с совместным использо- ванием файлов применяются локальные сети из микрокомпьютеров Архитектура с совместным использован нем файлов была разработана до клп ент-серверной архитектуры и во многих отношениях является более примитив нои При совместном использовании файлов СУБД каждого пользовательского компьютера посылает запросы па обработку файлов подсистеме обработки дан- ных операционной системы файлового сервера. Это означает, что при такой ар хитектуре трафик в локальной сети гораздо больше, чем при клиент-сервернои архитектуре. Рассмотрим, например, запрос, возвращающий столбцы Name и Address всех строк таблицы CUSTOMER, где столбец Zip имеет значение 98033. В клиент-сервер- ной системе прикладная программа послала бы следующую SQL комап I) SELECT NAME, ADDRESS FROM CUSTOMER ИО1 ZIP-98033 Сервер потратил бы столбцы Name и Address всех строк, удовлетворяющих критерию отбора.
694 Глава 15. Совместное использование /данных предприятия Клиентский компьютер п ОССЕТЬ = часть операционной системы, отвечающая за сетевую коммуникацию ОСуд = часть операционной системы, отвечающая за управление данными Рис. 15.3. Архитектура с совместным использованием файлов В системе с совместным использованием файлов СУБД находится на локаль- ном компьютере, поэтому программы на файловом сервере не способны обрабо- тай SQL-запрос. Вся такая обработка должна происходить на пользовательском компьютере, поэтому СУБД вынуждена запрашивать у файлового сервера всю та )лицу CUSTOMER целиком. Если эта таблица имеет индексы или другие связан- ные с ней избы 1 очные данные, они также должны быть переданы клиенту. Ясно, 1го при совместном использовании файлов по локальной сети передаются гораз- до большие объемы данных. Э111х пР()блсм системы с совместным использованием файлов редко ипп Спп'ОТСЯ ДЛЯ °бРс’ботки больших объемов данных с ориентацией на траизак- нения iraw™.М11ого дап,,Ь1х необходимо блокировать и передавать для выпол- ся сли1111<-лм°и т')а”заДЦ|1и’ и производительность такой архитектуры оказывает- запрос лаппыхЗК°Н днако для этой архитектуры все же есть одно применение: телям требуется достуиТ Г “3 ЕСЛ" °ДНОМу или нескольким пользова- отчетов или ответов на __^°ЛЬШИМ Фрагментам базы данных для составления загружающий ‘ “ ‘Росы, то, возможно, имеет смысл поставить сервер, "=и г'ых-при этои «rf- данных мы будем ра<хма11,„ют“ьХТ^й "3“'"’“ °бра6оТКП связанные^ б^ами^ашп ”С1^,ьзованнем файлов имеют также приложения, не требуется хранить большие файлы?™* "Р‘™ера МОЖ,,° пРивестп системы, где 4>аилы (звук, графику и анимацию) на высокоскоро-
Архитектуры корпоративных систем обработки данных 695 стных дисках большого объема. С помощью таких систем организуется также со- вместное использование дорогих принтеров, плоттеров и другого периферийно го оборудования. Системы обработки распределенных баз данных Четвертая альтернатива (рис. 15.4) - это системы обработки распределенных бал данных, в которых база данных распределена ио множеству компьютеров. На рис. 15.4 база данных (пли часть се) хранится на всех N компьютерах. Как показа- но на рисунке, компьютеры 1, 2 и N обрабатывают и приложения, и базу данных, а компьютер 3 обрабатывает только базу данных. Пользователь 1 Пользователь г Пользователь 3 Компьютер л ОС СЕТЬ = часть операционной системы, отвечающая за сетевую коммуникацию = часть операционной системы, отвечающая за управление данными ОСуд СУРБД = система управления распределенными базами данных Рио. 15.4. Архитектура распределенной базы данных
996 Глава IS. Совместнее использование даннм* пре«пр.«нгив Пунктирная линия, которой обведены <|шплы, означает, что база данных »клю чает в себя все сегменты, хранящиеся на всех N компьютерах. Зги комньютерм могут физически размещаться и идиом пом.-щенпн, а могут н разных юшим планеты. Распределенная обработка и обработка распределенных баз данных Обратимся снова к рис. 15 1. 15.2. 15 3 и 15.4. Система с совместным использова- нием файлов, клиент-серверная система и система обработки распределейных баз данных имеют одно важное отличие от системы удаленной обработки данных в них для обработки приложений или СУБД используется более одного компь- ютера. Соответственно, большинство сказало бы, что все эти три архитектуры являются примерами распределенных: систем (distributed systems), поскольку об- работка приложения распределена по нескольким компьютерам. Обратите внимание, однако, что сама база данных является распределенной только в архитектуре, изображенной на рис. 15.4. В клиент-серверной архитекту- ре и в архитектуре с совместным использованием файлов база данных распо- лагается на одном компьютере. Поэтому большинство не причислило бы кли- ент-серверную архитектуру и архитектуру с совместным использованием файлов к системам распределенных баз данных (distributed database systems). Типы распределенных баз данных Есть несколько типов распределенных баз данных. Взгляните сначала на рис. 15.5, а, на котором изображена нераспределенная база данных, состоящая из четырех частей — W, X, Y и Z. Все эти четыре сегмента расположены в одном и том же месте, и дублирование данных отсутствует. Теперь рассмотрим распределенные базы данных, изображенные на рис. 15.5, б-г. На рис. 15.5, б, изображен первый тип распределенной базы данных, где база дан- ных расположена на двух компьютерах: сегменты W и X хранятся на компьютере 1, а сегменты У и Z — на компьютере 2. На рис. 15.5, в, вся база данных продублиро- вана (реплицирована) на двух компьютерах. Наконец, па рис. 15.5, г, база данных разделена, а ее сегмент Y продублирован. По отношению к разделению баз данных иногда употребляются два термина. Вертикальным разделом (vertical partition), или вертикальным фрагментам (vertical agment), называется таблица, разделенная на две или более совокупности столб- цов апример, таблица R (Cl, С2, СЗ, С4) может быть разделена на два вертикальных фрагмента. Pl (Cl, С2) и Р2 (СЗ, С4). В зависимости от приложения и от причины, по которой производится разделение, ключ отношения R, скорее всего, будет по- мещен в отношение Р2, которое примет вид Р2 (С1, СЗ. С4). Горизонтальный раз- Д£!Л ^ <>r'ZOnta' Partition), или горизонтальный фрагмент (horizontal fragment), — это фрагмент таблицы, представляющий собой совокупность строк. Например, если первые 1000 строк отношения R помещаются в отношение R1 (Cl. С2, СЗ. С4), а оставшиеся строки помещаются в отношение R2 (Cl, С2, СЗ, С4), то отношения
Архитектуры корпоративных систем обработки данных 697 R1 и R2 образуют два горизонтальных фрагмента. Иногда база данных разбивает- ся и на горизонтальные, и на вертикальные разделы, и результат такого разделе- ния называется смешанным разделом (mixed partition) Автономный компьютер Линия связи БД (копия 2) Компьютер 2 Линия связи БД б Линия связи Компьютер 2 г Рис. 15.5. Типы распределенных баз данных: a — неразделенная, нереплицированная; б - разделенная, нереплицированная; в — неразделенная реплицированная; г — разделенная, реплицированная в Сравнение различных типов распределеных баз данных равнение баз данных с различной степенью распределения приведено на рис. 15.6. Четыре типа баз данных расположены на рисунке слона направо по возрастанию ствинии разделения Нераспределенная база данных находится в крайней левой Точке отрезка оси (равнения, а распределенная н реплицированная база данных В крайней Правой Разделы хранятся на двух или более компьютерах, а неразде- ленная база данных целиком дублируется на двух пли более компьютерах.
698 Глава 15. Совместное использование данных предприятия Единая база данных Континуум Распределенные базы данных Единые неразделенные нереплицированные Разделенные нереплицироввнные Неразделенные реплицированные Разделенные реплицированные Возрастание параллелизма Возрастание независимости Повышение гибкости Повышение доступности + ----------------------------------------► . Увеличение стоимости/сложности _ .—....................-................... Возрастание трудности в управлении _ * —.......................................► + Повышение риска для безопасности системы - -.............-.......—....—....... .... > Рис. 15.6. Характеристика баз данных по степени распределения Характеристики этих альтернатив тоже указаны на рис. 15.6. Слева направо возрастают параллелизм, независимость, гибкость и доступность, однако при этом повышаются стоимость, сложность, трудность в управлении и риск несанк- ционированного доступа. Одно из этих преимуществ имеет особенное значение для бизнеса. Варианты, расположенные справа на рис. 15.6, обладают большей гибкостью и, следовательно, могут быть лучше приспособлены для конкретной организационной структуры и бизнес-процессов. Например, компанию-производителя с высокой степенью децентрализации, в которой менеджерам-технологам предоставлена большая свооода в планировании, не сможет удовлетворить информационная система, изображенная на рис. 15.5, о, поскольку структура этой системы войдет в кон- фликт со структурой компании. Таким образом, альтернативы, расположенные в правой части рисунка, в большей степени подходят этой организации, чем те, которые находятся слева. Наибольшим недостатком распределения является сложность управления по условленная этим потенциальная опасность потери целостности данных, ассмотрим архитектуру базы данных на рис. 15.5, г. Пользователь, сидящий за компьютером 1, может читать и обновлять элемент данных раздела Y, располо- женный на компьютере 1, одновременно с тем, как этот же элемент раздела V расположенный на компьютере 2, будет читаться и обновляться пользователем, сидящим за компьютером 2. isn XIE Еа Методы распределенной обработки В разных СУБД применяются различные способы распределенной обработки. Гссеи Леггет поддержка распределенной обработки осуществляется ходным о тразом, по одни и те же вещи называются по-разному, и наоборот —
Архитектуры корпоративных систем обработки данных 699 разные вещи имеют одинаковые названия. У других производителей также име- ется своя терминология. Здесь мы сосредоточимся на основных идеях Простейшим способом обработки распред™»,", базы данных „плясГсЯ „. грузка данных только для чтения. В этом случае обновлением всех данных в базе занимается только один компьютер, но копии данных только для чтения могут посылаться на множество (возможно, тысячи) компьютеров. В Oracle гаки копии предназначенные только для чтения, называются материализованными пред- ставлениями (materialized views). В SQL Server эти конин называются момен- тальными снимками (snapshots). Этот тип распределенной обработки мы будем рассматривать в следующем разделе. J При более сложном способе распределенной обработки запросы па обновле- ние данных могут приходить со множества компьютеров, но на обработку они передаются одному специализированному компьютеру. Например, компьютер А может быть определен как единственный компьютер, который может обновлять таблицу СОТРУДНИК (и основанные на ней представления), а компьютер Б может быть определен как единственный компьютер, которому разрешено обновлять таблицу КЛИЕНТ (и ее представления). Время от времени обновления должны пе- редаваться обратно на все компьютеры в распределенной сети, и базы данных должны синхронизироваться. Наиболее сложный способ заключается в том, чтобы разрешить множествен- ное обновление одних и тех же данных в различных местах. В этом случае могут возникнуть три вида конфликтов распределенных обновлений (distributed update conflicts). Во-первых, может быть нарушена уникальность. В базе данных галереи View Ridge два разных компьютера могут создать в таблице WORK строку с одина- ковыми значениями столбцов Copy, Title и ArtistID. Другая возможность напоми- нает проблему потерянного обновления: на двух компьютерах может обновлять- ся одна и та же строка. Третий конфликт возникает в ситуации, когда на одном компьютере обновляется строка, удаленная на другом компьютере. Для разрешения конфликтов обновлений выделяется специальный компью- тер. Он следит за всеми обновлениями, и возникающие конфликты разрешаются либо собственными средствами СУБД, либо приложениями, подобно тому как это делается в триггерах. В самых крайних случаях делается запись о конфликте в журнале, и он разрешается вручную. Последний способ не рекомендуется, по- скольку до устранения конфликта множество строк в работающих базах данных может зависнуть в неопределенном положении, что приведет к неприемлемому снижению пропускной способности информационной системы предприятия. Ни один из этих способов не решает проблемы обеспечения атомарности транзакций в распределенной базе данных. Эта проблема становится особенно важно , если имеется вероятность конфликтов обновлений. В какой момент ра- боту с базой данных можно считать выполненной? Если во время разрешения конфликта распределенных обновлений должен произойти откат обновлении, то потенциально возможно, что распределенная транзакция не будет выполнена в Течение нескольких часов или даже суток. Ясно, что такая задержка псприек лема Е сли оставить в стороне конфликты распределенных обновлении, осгаегся сне один сложный вопрос - координация распределенных гранзакцип. Нооы транзакция была атомарной, пи одно обновление в распределеииоп транзакции не Должно бьпь сохранено, пока нс будут сохранены все ц'иствия транзакции.
700 Глава 15. Совместное использование данных предприятия Эго означает, что каждый компьютер должен .аппсать спои обновления условно п ожидать от диспетчера распределенных гран (акций уведомления о том, что действия всех остальных компьютеров также записаны. Для этой цели иснолыу ется алгоритм, называемый двухфазной фиксацией (two-phase commit) У компа нин Microsoft имеется служба OLE под названием Distributed transaction Serous (служба распределенных транзакций), или DIS, реализующая двухфазную фик- сацию. В мире Java для этого используется технология Enterprise Java Beans Рассмотрение этих продуктов п технологий выходит за рамки нашего изложт ния, но об их существовании знать следует. Дополнительную информацию по этой теме можно получить, выполнив поиск по ключевому слову replication (ре- пликация) в документации по Oracle п SQL Server. Загрузка данных С появлением мощных персональных компьютеров стала возможной загрузка больших объемов данных предприятия на компьютеры пользователей и отделов для локальной обработки. Пользователи могут запрашивать эти данные с по- мощью локальных СУБД, а также импортировать их в электронные таблицы программы финансового анализа, графические и другие программы. Вообще говоря, загруженные данные могут использоваться только для запро- сов и составления отчетов. Их нельзя обновить, так как после их извлечения из действующей базы данных контроль параллельной обработки этих данных не ве- дется. Чтобы лучше понять трудности, связанные с обработкой загруженных данных, рассмотрим типичный пример. Компания Universal Equipment Компания Universal Equipment производит и продает тяжелые машины для строи- тельной промышленности. Продукция компании включает бульдозеры, грейдеры, погрузчики и буровые установки. Каждый вид продукции находится в ведении одного из менеджеров по продукции в отделе маркетинга, который отвечает за планирова- ние, рекламу, маркетинговую поддержку, разработку' рекламных материалов и т. д. Каждому менеджеру выделен набор из двух или трех родственных продуктов. Реклама является самой крупной статьей расходов менеджеров по продукции, поэтому им необходимо измерять эффективность размещаемой рекламы. В каждом рекламном объявлении компании Universal Equipment имеется почтовая карточка для запроса информации. На каждой карточке напечатан номер, уникальный для каждого вида объявления, по которому можно установить, благодаря какому из объявлений произошла данная покупка. Чтобы упростить отслеживание покупок, стимулированных рекламой, отдел маркетинга разработал микрокомпьютерное приложение базы данных, которую могут использовать менеджеры по продукции На рис. 15.7, а, изображены семантические объекты, фигурирующие в этом приложении. Объект ОБЪЯВЛЕНИЕ соответствует рекламному объявлению. < 1 екг ВИД_ОБЪЯВЛЕНИЯ представляет вид конкретного объявления в конкретно публикации; обьект ПРОДУКТ - конкретный продукт, например бульдозер.
Загрузка данных 701 ект ПРОДУКТ содержит две повторяющиеся группы - Квота и Продажи. Эти группы являются многозначными, поскольку доля продаж определяется ежеквартально, а продажи — еженедельно. Это представление объекта ПРОДУКТ является весьма простым. Реальный объ- ект такого рода имеет больше атрибутов. Но поскольку остальные данные в дан- ном приложении не требуются, мы не стали их показывать. Структура базы дан- дых, состоящей из этих объектов, изображена па рис. 15.7, б. ОБЪЯВЛЕНИЕ 1Q Название Агентство ДатаСоздания ГвИД_ОБЪЯВЛЕНИЯI 1------———------1 0.N I ПРОДУКТ I I-----s------1 ! N ВИД_ОБЪЯВЛЕНИЯ !В НомерОбъявления Издание ~I Дата J 11 [объявление j 1—.......... 1 11______ |СТИМУЛИРОВАННАЯ ПОКУПКА; ПРОДУКТ !Е Квота Название — Дата Квоты ОбъемКвоты _ Продажи ДатаПериодаПродаж ОбъемПродаж JoN Г ОБЪЯВЛЕНИЕ | 1............ ; 0.1_______ ГСТИМУЛЙРОВАННАЯ_ПОКУПКА | I---------------------------1 o.N СТИМУЛИРОВАН НАЯПОКУПКА НомерСтПокупки “ ТелефонКлиента Дата J , л ИмяКлиента I v ПрОДУК!j Ъ»---------Jbu-J 1Л |ВИД ОБЪЯВЛЕНИЯ} | ОБЪЯВЛЕНИЕ] | ПРОДУКТ [ | ВИД ОБЪЯВЛЕНИЯ~] I КВОТА п [продажи! |ст^^в^Е^гюкупда Рис 16 7. Объекты и отношения эти объекты с «порыми работают менеджеры; б - реляционные струю ут
702 Глава 15. Совместное использование данных предприятия Процесс загрузки Менеджерам по продукции выделены персональные компьютеры, соединенные с другими компьютерами через локальную сеть отдела маркетинга компании Universal Equipment. Для получения данных о продажах и стимулированных рек- ламой покупках компьютеры обращаются к файловому серверу, который выпол- няет роль шлюза на пути к большой ЭВМ компании Universal Equipment (компь- ютеру, занимающемуся обработкой транзакций). Архитектура системы подобна изображенной на рис. 15.8. Рис. 15.8. Совместное использование загруженных данных с шлюзом в роли файлового сервера Каждый понедельник ответственный пользователь отдела программу, разработанную отделом информационных систем маркетинга запускает управления Univeml
Загрузка данных 703 ЕЯ™. £ о6"о“”ет таблицы ПРОДАЖИ, КВОТА и СТИМУЛИРОВАННАЯ ПОКУПКА базы да,.и,.,, файлового ссркра с по„ощью и,1фо^TnZ4i „з главной базы даппых компа,,,,,,. Эта программа добавляет да„„ь,е“ ,Хд „ююпеделю п делает необходимые „оправления. При этом импортируют „и- ные о про ахах всех родстве,„,ых продуктов, чтобы менеджеры „о могли провеет,, сравнительный анализ. После загрузки данных „а файле, ,"й сервер любой менеджер по продукции может получип, е этого сервера „„тёк сующие его данные. Благодаря мерам бсзопасноста менеджеры по продукции „е могут получить данные, доступ к которым им не разрешен. Потенциальные проблемы при обработке загруженных баз данных Загрузка данных приближает данные к пользователю и увеличивает пользу от них. Однако, к сожалению, она сопряжена с трудностью обеспечения координации, согла- сованности и контроля доступа, а также с опасностью компьютерных преступлений. Координация Рассмотрим проблему координации на примере таблиц СТИМУЛИРОВАННАЯ_ПОКУПКА и ВИД_ОБЪЯВЛЕНИЯ. Таблица СТИМУЛИРОВАННАЯ_ПОКУПКА обновляется данными с большой ЭВМ (информация о стимулированных рекламой покупках вводится продавцами и записывается в главный компьютер). Но таблица ВИД_ОБЪЯВЛЕНИЯ обновляется «локально» ответственным пользователем отдела маркетинга, кото- рый получает данные из отчетов, подготовленных менеджером по рекламе и рек- ламным агентством. Данная ситуация может вызвать проблемы, когда объявление размещается в первый раз в новом выпуске или публикации. Например, благодаря объявлению могут произойти покупки, информация о которых будет записана в базу данных главного компьютера прежде, чем данные о виде объявления будут сохранены на файловом сервере. Позже при загрузке информации с главного компьютера про- грамма импорта отклонит данные об этих покупках, так как они нарушат ограни- чение, согласно которому каждая строка таблицы СТИМУЛИРОВАННАЯ_ПОКУПКА Должна иметь родителя в таблице ВИД_ОБЪЯВЛЕНИЯ. Таким образом, .тотальное обновление и загрузка должны тщательно координироватьс : ответственный поль- зователь должен добавлять данные в таблицу ВИД_ОБЪЯВЛЕНИЯ перед импортом Данных с главного компьютера. Аналогичные проблемы с координацией могут возникнуть при обновлении данных в таблицах КВОТА п ПРОДАЖИ. Согласованность Вторая проблема, связанная с загрузкой данных, относится к согласованности. Предполагается, что менеджер.о продукции не будут изменять полученные Данные о долях и продажах. 11о ч го пронзопдеi, если менеджер изменит данные. Ьятом случае вероятна ситуация, когда данные в его базе не будут согласованы Сданными в база : Предприятия, файлового сервера и, возможно, других менед- жеров но продукции О гче । Ы. тавле легпм менеджером, буду i расхо,цп ься
704 Глава 15. Совместное использование данных предприятия с другими отчетами А если несколько менеджеров изменят свои данные о? но появление большого количества несогласованных данных. Эта ситуация наводит на мысль о необходимости строгого контроля База данных должна быть спроектирована таким образом, чтобы данные в ней нельзя было изменить. Если эго невозможно (например, СУБД для персонального компь- ютера не позволяет наложить такое ограничение, а стоимость написания соот ветствующей прикладной программы непозволительно высока), то решение этой проблемы — в обучении. Менеджеры по продукции должны знать о проблемах, которые возникнут в случае изменения ими данных, и им необходимо указать, что так делать не следует. Контроль доступа Третья проблема заключается в контроле доступа. Когда данные передаются на несколько компьютерных систем, контролировать доступ становится сложнее Например, в компании Universal Equipment данные о квотах и продажах могут быть конфиденциальными. Вице-президент отдела продаж не хотел бы, чтобы продавцы узнавали о квотах продаж на предстоящий период до ежегодного соб- рания отдела продаж. Но, если эти данные есть в базах 15 менеджеров по продук- ции, трудно гарантировать, что они будут сохранены в тайне до нужного момента Более того, файловый сервер получает все данные о квотах и продажах, которые предполагается загружать таким способом, чтобы менеджер по продукции получат только данные по продуктам, находящимся в его ведении. Однако у менеджеров по продажам силен дух соперничества, и они, возможно, захотят получить данные о продуктах друг друга Если сделать эти данные доступными на файловом сервере отдела маркетинга, это может привести к проблемам управленческого характера Компьютерные преступления Четвертая проблема — больший риск компьютерных преступлений — тесно свя- зана с контролем доступа. Контроль доступа направлен на предотвращение неже- лательной, но законной деятельности, тогда как к компьютерным преступлениям относятся незаконные деяния. Данные на главном компьютере предприятия мо- гут представлять большую ценность. Например, данные о квотах и продажах компании Universal Equipment очень интересуют конкурирующие компании. Когда происходит массовая загрузка данных на файловый сервер и затем на один или несколько персональных компьютеров, предотвращение нелегального копирования становится трудной задачей. Спрятать дискету или компакт-диск очень легко, к тому же иногда сотрудники имеют возможность обращаться к ра бочим компьютерам по удаленному соединению. В этих ситуациях обнаружить или предотвратить копирование данных практически невозможно. Один то ьк риск компьютерных преступлений может на практике заставить отказаться мысли о разработке подобной системы, даже если в остальных отношениях это было бы великолепным решением. Потенциальные проблемы загруженных аз данных перечислены в следующем списке. Координация: ♦ загруженные данные должны удовлетворять ограничениям базы данных. ♦ локальные обновления должны быть координированы с загрузкой
Загрузка данных 705 Согласованность: ♦ в общем случае загруженные данные не должны обновляться; ♦ в приложениях должны быть предусмотрены специальные меры для пред- отвращения обновления; + пользователи должны быть осведомлены о возможных проблемах. Контроль доступа: ♦ данные могут быть реплицированы на нескольких компьютерах; ♦ процедуры контроля доступа к данными являются более сложными. Потенциальная опасность компьютерных преступлений: ♦ нелегальное копирование трудно предотвратить; ♦ дискеты и нелегальный доступ по сети легко скрыть; ♦ риск компьютерных преступлений может заставить отказаться от разра- ботки приложений, работающих с загруженными данными. Использование веб-сервера для публикации загруженных данных На рис. 15.9 показан один из способов использования веб-сервера для публикации загруженных данных. Шлюз и сервер базы данных изображены здесь на одном компьютере, однако их можно разместить и отдельно — шлюз на одном компьютере, а сервер на другом. Для получения загруженных данных веб-сервер обращается к серверу базы данных. Затем данные выводятся на браузеры пользователей. Рис 15-©. Обработке загруженных данных на веб-сервере
706 Глава 15. Совместное использование данных предприятия Оперативная аналитическая обработка данных (OLAP) Б последние годы появился новый способ представления информации под назва нием оперативная аналитическая обработка данных (on-line analytic processing) или OLAP. Б OLAP данные представляются в системе координат с п осями, на- пример с двумя (в рамках таблицы) пли тремя (в рамках куба (cube)). Поскольку OLAP не накладывает ограничении на количество осей, используется термин гипер- куб (hypercube). Этот термин означает представление с неограниченным числом осей. Чаще всего применяется термин куб OLAP (OLAP cube). Рассмотрим пример отношения, изображенный в табл. 15.1. Б нем приведены данные по односемейным домам и кондоминиумам в Калифорнии и Неваде. Как можно видеть, запрашиваемая цена и цена продажи указаны как для существую- щих, так и для строящихся домов. Терминология OLAP Куб OLAP для этих данных показан в табл. 15.2. Данные откладываются по двум осям (axes), которыми являются строки и столбцы. На каждой оси может быть показано одно или несколько измерений (dimension). По оси строк в табл. 15.2 по- казано измерение Дата, а по оси столбцов — измерения Категория и Место. Когда на одной осп показываются два или более измерения, то приводятся все возможные комбинации данных одного измерения с данными другого. Так, например, данные о существующих и строящихся домах приведены по каждому месту. Ячейки куба представляют меры (measures) куба, или отображаемые данные. Б этом кубе мерой является средняя цена продажи. Могут быть и другие меры — например, запра- шиваемая цена или даже разница между ценой продажи и запрашиваемой ценой. Обратите внимание, что все данные в табл. 15.2 относятся к односемейным домам Данных о кондоминиумах этот куб ие содержит. На самом деле таких кубов два: один с данными по одпосемейиым домам, а другой — с данными по кондоминиумам. Эти кубы удобно мысленно располагать один за другим, как показано па рис. 15.10. При таком взгляде эти два куба представляются в виде слоев данных, и действительно, измерения, остающиеся в кубе постоянными, на- зываются слоями (slices). Таким образом, в приведенном примере куб расслоен по измерению Тип. Возможные значения данных в измерении называются членами (members). Измерение Тип состоит из членов {Односемейный дом, Кондоминиум}, а измерение Категория — из членов {Новый, Существующий}. В этом кубе членами измерения Штат являются значения {Калифорния, Невада}, но при рассмотрении недвижимости па всей территории Соединенных Штатов измерение Штат может иметь 50 членов. Иногда измерение содержит очень большое количество членов — представьте себе, например, все комбинации {Штат, Город}. Наконец, в некоторых случаях члены являются вычисляемыми. Хорошими примерами являются дата и время. Имея дату, мы можем вычислить члены Месяц, Квартал, Год и Век.
Табяыца 15. t. Отношение, содержащее исходные данные для OLAP-куба Категория Тип Город Штат Дата Цена продажи, долл Запрашиваемая цена, долл Новый Односемейный Сан-Франциско Калифорния 01.01.2000 679 000 685 000 Существующий Кондоминиум Лос-Анджелес Калифорния 05.03.2001 327 989 350 000 Существующий Односемейный Элько Невада 17.07.2001 105 675 125 000 Новый Кондоминиум Сан-Диего Калифорния 22.12.2000 375 000 375 000 Существующий Односемейный Парадайз Калифорния 19.11.2001 425 000 449 000 Существующий Односемейный Лас-Вегас Невада 19.01.2001 317 000 325 000 Новый Односемейный Сан-Франциско Калифорния 01.01.2000 679 000 685 000 Существующий Кондоминиум Лос-Анджелес Калифорния 05.03.2001 327 989 350 000 Существующий Кондоминиум Лас-Вегас Невада 19 06.2001 297 000 305 000 Существующий Односемейный Лос-Анджелес Калифорния 01.04.2000 579 000 625 000 Новый Кондоминиум Лос-Анджелес Калифорния 05.08.2001 321 000 320 000 И т. д. Таблица 15.2. Пример OLAP-куба Средняя цена продажи односемейных домов, тыс. долл. Существующие дома Новые дома Калифорния Сан-Франциско Лос-Анджелес Сан-Диего Невада Калифорния Сан-Франциско Лос-Анджелес Сан-Диего Невада 2000 К1 Янв 408 465 375 179 418 468 371 190 Фев 419 438 382 180 429 437 382 185 Мар 427 477 380 195 426 471 387 198 К2 433 431 382 188 437 437 380 193 КЗ 437 437 380 190 438 439 382 190 К4 435 439 377 193 432 434 370 198 2001 К1 Янв 452 454 368 198 450 457 367 197 Фев 450 467 381 187 457 464 388 191 Мар 432 444 373 188 436 446 371 201 К2 437 437 368 190 444 432 363 196 КЗ 436 452 388 196 447 455 385 199 К4 441 455 355 198 449 455 355 202
708 Гпава is Совместное использование дани»* <..*> <и« Рис. 15.10. Слои OLAP-куба Последним важным термином OLAP является уровень (level). Уровень Изме- рения — это его позиция в иерархии. Рассмотрим, например, измерение Дата У него есть уровни Год, Квартал и Месяц. Уровнями измерения Место являются Город и Штат. Терминология OLAP сведена в табл. 15.3. Таблица 15.3. Терминология OLAP Термин Значение Пример в табл. 15.2 Ось Координата гиперкуба Строки, столбцы Измерение Свойство данных, которое откладывается по оси Время. Тип жилья, Место Уровень Подмножество измерения (иерархическое) {Калифорния, Невада) {Сан-Франциско, Лос-Анджелес, Прочие} {К1, К2, КЗ, К4} Член Элемент данных в измерении {Новый, Существующий} {Янв, Фев, Мар} Мера Исходные данные для куба Цена продажи, Запрашиваемая цена Слой Измерение или мера, являющиеся постоянными в пределах отображения Тип жилья (все приведенные данные — для односемейных домов; для кондоминиумов существует еще один куб) Определения куба и представления терминология OLAP нахол! она является несколько > ГТСЯ„В постоянн°м изменении, и на настоящий момент зуется для описания как г^ТК°И В °ДН?М Важпом отношении. Термин куб исполь- показанный в табл 15 2 яв <ИТИЧеско“ стРУктуры, так и ее материализаций. Куб, ей, семантической ствСк-ХТ^ ™‘nb °ДПИМ ‘Ч^Дотамепнем, или материализаци- ры. Мы могли бы создать лп *’ Те,°и‘ей опРедсленпые измерения, уровни и ме- И столбцы, и третий kv6 ’ f У' °И Куб С 31111411 Данными, поменяв местами строки его членом располагалнсъетолбии ? п ° ”г‘ХОД1,лось бы свс')х>’’ а под каЖДЫМ Документов OLAP важно & роящееся и Существующее. Поэтому при чтении понимать, в каком значении используется слово куб.
Оперативная аналитическая обработка данных (OLAP) 709 Чтобы проиллюстрировать это, рассмотрим определение куба в листинге 15 1 Используемый здесь синтаксис основан на документации Microsoft OLE DB для OLAP, но сходные конструкции используются и другими производителями Оператор Create Cube определяет четыре измерения и два уровня логической структуры. Измерения Время и Место имеют уровни, а измерения КатегорияЖилья и ТипЖилья - нет. Хотя это здесь не показано, измерение может иметь более од- ного набора уровней. В этом случае для измерения определяются две или более иерархии. Листинг 15.1. Расширенный синтаксис SQL для OLAP CREATE CUBE КубПродажЖилья ( DIMENSION Время TYPE TIME. LEVEL Год TYPE YEAR. LEVEL Квартал TYPE QUARTER. LEVEL Месяц TYPE MONTH. DIMENSION Место. LEVEL США TYPE ALL. LEVEL Штат. LEVEL Город. DIMENSION КатегорияЖилья. DIMENSION ТипЖилья. MEASURE ЦенаПродаж, FUNCTION СРЕДНЕЕ MEASURE ЗапрашиваемаяЦена. FUNCTION СРЕДНЕЕ ) Листинг 15.2. Пример многомерного оператора SELECT SELECT CROSSJOIN ({Существующие дома. Новые дома}. {Калифорния Children. Невада}) ON COLUMNS. {199В.KI.Children. 1998.К2. 1998.КЗ. 1998.К4. 1999.KI.Children. 1999.К2. 1999.КЗ. 1999.К4} ON ROWS FROM КубПродажЖилья WHERE (ЦенаПродажи. ТипЖилья = 'Односемейный') Структура, представленная в листинге 15.1, — это определение способа интер иретации, или осмысления, данных о жилье. Она не является представлением данных. Для определения представления, или материализации, с У ‘^томпо требиостеи OLAP был расширен синтаксис SQL В листингах ’ ’ . заны операторы OLAP SQL, создающие материализацию кУба- > в табл 15.2. Единственное, что может смущать в этом опера р , I CROSSJOIN. Результатом выполнения оператора CROSSJOIN ({А, В}, {1, }) является следующее отображение. А в 12 1 2
710 Глава 15. Совместное использование данных предприятия Выполнение оператора CROSSJOIN ({1, 2}, {А, В}) приводит к отображению - 2 АВА В Если несколько развить эту идею, можно составить оператор CROSSJOIN ({Су- ществующее жилье. Строящееся жилье}, {Калифорния.С1н1с1геп, Невада}), результатом которого будет Существующие дома Новые дома Калифорния_______________Невада Калифорния ________ Невада Сан-Франциско Лос-Анджелес Сан-Диего Сан-Франциско Лос-Анджелес Сан-Диего Единственным добавлением к последнему оператору является выражение Ка- лифорния.Children, которое означает, что нужно провести разбиение по всем по- томкам члена Калифорния для всех уровней куба. SQL-оператор в листинге 15.2 содержит выражения ON COLUMNS и ON ROWS. Тем самым объявляются оси, по которым будут откладываться измерения. Обратите также внимание, что для задания слоев представления используется предложение WHERE. В соответствии с рисунком, показываться должны только продажная цена и тип жилья для односемейного дома. Заметьте, что расслоение может осуществ- ляться как по измерению, так и по мере. Структуры схемы OLAP Все данные в приведенном примере (см. табл. 15.1 и 15.2) взяты из одной таблицы. Такая ситуация нетипична: обычно данные по крайней мере нескольких измере- ний хранятся не в той таблице, которая содержит меры. На рис. 15.11 показан пример табличной структуры OLAP для базы данных галереи View Ridge. Дан- ные измерений, например SalesPrice, хранятся в таблице TRANS, а данные о прочих измерениях хранятся в родительских таблицах, соединенных с таблицей TRANS через внешние ключи. Куб, основанный на данных на рис. 15.11, а, может иметь измерения CUSTOMER, ART_DEALER, SALESPERSON и WORK. Данные членов этих измерений будут считы- ваться из соответствующих таблиц. Структура, изображенная на рис. 15.11, а, столь распространена, что ей было дано специальное название — схема «звезда» (star schema), которое отражает принцип расположения таблиц с данными изме рений вокруг таблицы с данными мер. Обратите внимание, что на этом рисунке отсутствует атрибут имени худож ника (ARTIST.Name). Чтобы добавить этот атрибут, OLAP-проектировщик может соединить столбец ARTIST.Name с таблицей WORK через ключ ArtistID. Но в этом случае таблица WORK не будет находиться в доменно-ключевой нормальной форм в результате чего возникнет дублирование данных. , |р Альтернатива хранению таких соединений изображена на рис. 15.11,6. Здесь та ца ARTIST не соединяется с таблицей WORK, а хранится в нормализовании; N Добавлена также другая таблица, GENRE (жанр). Такая структура также возш^^ регулярно, и она была названа схемой «снежинка» (snowflake schema)-
Оперативная аналитическая обработка данных (OLAP) 711 между структурами, имеющими форму звезды и снежинки, заключается в том что в структуре типа «звезда» каждая таблица с данными измерения непосредст- венно связана с таблицей, где хранятся значения мер. Эти таблицы могут по не обязаны) быть нормализованными. Структура типа «снежинка» может иметь не- сколько уровней таблиц, и каждая таблица в ней нормализована. [customer ’CustomerlD Name AreaCode LocalNumber Street City [State Rip SALESPERSON В CUSTOMER 'V Salesperson© Name Phone HtcDate WORK CompanyName СДУ State Country WORK._______ WorkID Artist© Title Copy Description Genre© SALESPERSON Salesperson© Name Phone HreDate GENRE Genre© Genre Description TRANSj PurchaseDate SalesPnce Customer© AskingPrice Salesperson© ArtDealerlD ArttSt© ArtistName Nationality Buthdate Deceaseddate art., dealer ж....". ArtDealer© CompanyName City State Country [CustomerlD | Name AreaCode LocalNumber Street City State I Ze TRANS', . TputchaseDate SalesPrice Customer© AskjngPnce Salesperson© ArtDealerlD WorkID Artist© Title Copy Description Ж я я б АКНЗТ^^^СжЙЙ . ft_ппимер схемы «снежинка» « . m АР пример скемы «звезда», б - пример Рис. 1В.11. Типы схем OLAE а »
712 Глава 15. Совместней использование данных предприятия Выбор между этими двумя структурами загшеих or объема и лриро д-щ ных, а также от нагрузки OLAP. В общем случае схема «звезда» требует больше- го количества памяти, ио она быстрее в обработке. Схема «г пежинка» обр вается медленнее, зато требует меньше памяти. Способы хранения данных OLAP (ROLAP, MOLAP и HOLAP) ROLAP, MOLAP и HOLAP представляют собой различные способы хранения данных OLAP. В сущности, вопрос заключается в следующем: что позволит до- стичь максимальной производительности — внедрение средств OLAP в реляци- онные СУБД, использование специализированных автономных средств или и т и другое одновременно? Сторонники ROLAP (реляционной OLAP) заявляют, что СУБД с расши- ренными возможностями, включающими предварительную обработку опреде- ленных запросов и некоторые другие функции, могут служить вполне адекват- ными средствами хранения данных OLAP. Сторонники MOLAP (многомерной OLAP) считают, что, хотя СУБД хорошо подходят для обработки транзакций, выполнения запросов и создания отчетов, требования OLAP к обработке данных настолько специфичны, что ни одна СУБД не может достичь в этой сфере при- емлемой производительности. Сторонники третьего пути, HOLAP (гибридной OLAP), считают, что и СУБД, и специализированные OLAP-процессоры .мо- гут успешно использоваться для этих целей, и каждая из составляющих имеет свою роль. Microsoft использует эти термины более узко — в контексте средств оператив- ной аналитической обработки СУБД SQL Server. Для Microsoft термин ROLAP означает, что хранение исходных данных и заранее вычисленных агрегаций дан- ных происходит в базе данных SQL Server. При MOLAP данные, структура куба и заранее вычисленные агрегации данных хранятся в специализированной мно- гомерной структуре данных. При HOLAP данные остаются в реляционной базе данных, но агрегации данных хранятся в многомерной структуре. MOLAP дает максимальную производительность, но и требует больше всего памяти. ROLAP требует меньше памяти, но работает медленней. ROLAP пред- назначена для больших баз данных, информация из которых запрашивается ред- ко. В способе HOLAP высокоуровневая обработка дает большую производитель ность, но при исследовании мелких деталей быстродействие снижается. На рис. 15.12 показана архитектура OLAP, заявленная Microsoft для при- менения в SQL Server 7.0 и Office 2000. Это гибридная архитектура, которая включает OLAP-обработку на центральных серверах данных, веб-сервере и кли ентских компьютерах. Организационные базы данных обрабатываются цен тральными серверами данных, показанными на диаграмме справа. Дост)п к р^ зультатам этой обработки предоставляется через главную службу га Н ( Table Service) на веб-сервере или локальном компьютере. Кроме того, на * сервере или на локальном компьютере могут храниться локальные версии ных OLAP.
Оперативная аналитичрскл- Р^отка Данных (OLAP) 713 Клиентский компьютер Рис. 15.12. Архитектура OLAP Microsoft У этой архитектуры есть несколько ключевых элементов. Во-первых, это главная служба таблиц, которая представляет собой OLAP-процессор, доступ- ный в виде службы NT и Windows 2000. Эта служба работает и в других версиях Windows, где работает Office 2000. Фактически главная служба таблиц вызыва- ется всякий раз, когда в Access создаются страницы доступа к данным. Еще чаще она используется Excel. Доступ к главной службе таблиц осуществляется через расширение OLE DB, которое называется OLE DB для OLAP. Эго расширение построено па базе тех- нологии OLE DB, рассматривавшейся в главе 12; в сущности, оно расширяет поня- тие Набора строк, включая в пего не только наборы записей, но и наборы данных, являющиеся абстракциями кубов. Расширение ADO для обработки OLE DB для OLAP называется ADO MD (многомерная ADO). В ADO MD объекты Connection и Command могут открыла! ь наборы данных п обрабатывать их динамически
714 Глава 1S Совместное использование данных прадяриа>и» подобно тому, как это делалось для тщбпрод записей в главе 12 Данные могут как считываться, так и записываться. Такая архитектура в максимально возможной степени приближает < iLAP# у)да. енту, поскольку вычислительные требования OLAP могут быть огромны Эго не представляет трудностей при обработке локальных данных, но для создания кубов, требующих загрузки данных с центрального сервера предприятия, может понадобиться передача значительных объемов данных Возможно, это окажется неосуществимым. Определенно, такие системы нужно будет настраивать ио мере накопления опыта. Как указано на рис. 15 12, OLAP-обработке могут подвергаться централизо- ванные, загруженные пли локальные данные. По мере того как организации пе- редают все большее количество своих данных в распоряжение пользователей, воз- растают проблемы с управлением данными. Возможным решением этих проблем являются информационные хранилища, обсуждаемые в следующем разделе. Информационные хранилища Загрузка данных действительно приближает эти данные к пользователю, тем самым повышая их эффективность. Управление одним или двумя компьютерами, осуще- ствляющими загрузку, не представляет трудностей. Однако, если каждый отдел пожелает иметь свой источник загруженных данных, возникновение управленче- ских проблем неизбежно. В связи с этим у организаций возникла потребность в стандартизированной службе, обеспечивающей перемещение данных к пользо- вателю и увеличение их полезности. Такая служба называется информационным хранилищем. Информационное хранилище (data warehouse) — это место хранения данных предприятия, предназначенное для упрощения принятия управленческих реше- ний. Информационное хранилище включает в себя не только данные, но также инструменты, процедуры, обучение, персонал и другие ресурсы, облегчающие доступ к данным и делающие его более осмысленным для лиц, принимающих ре- шения. Назначение информационного хранилища состоит в увеличении ценно- сти информационных активов предприятия. Как показано на рис. 15.13, роль информационного хранилища заключается в том, чтобы хранить выдержки из рабочих данных и выдавать их пользователям в удобном формате. Это могут быть как выдержки из базы данных и файлов, так и отсканированные образы документов, записи, фотографии и другие нечисловы данные. Информационное хранилище служит для хранения, комбинирования, агрегирования, преобразования и доставки данных пользователям с помощью средств анализа и принятия решений, таких как OLAP. Компоненты информационного хранилища Компоненты информационного хранилища перечислены во врезке. Как уже говорилось, источником данных для информационного хранилища служит чая база данных. Следовательно, в информационном хранилище должны
хранилищ 7,„ средства для извлечения и хранения данных. Носами та даиныебесполезны без соответствующих метаданных, описывающих природу, происхождение, формат данных, ограничения на их использование и другие свойства, влияющие на ис- пользование данных. Рис. 15.13. Информационное хранилище КОМПОНЕНТЫ ИНФОРМАЦИОННОГО ХРАНИЛИЩА --------------------------------------- ♦ Средства извлечения данных. ♦ Выдержки из данных. ♦ Метаданные, описывающие содержимое информационного хранилища. ♦ СУБД и OLAP-серверы информационного хранилища. ♦ Средства управления данными информационного хранилища. ♦ Программы доставки данных. ♦ Аналитические программы /для конечных пользователей. ♦ Курсы обучения пользователей и учебные материалы. ♦ Консультанты информационного хранилища. Потенциально информационное хранилище содержит миллиарды байтов дан- ных Но множестве различных форматов. Соответственно, для хранения н обработки
716 ааа 15 Совместное исполмрааниа дойным ________ данных ему необходимы собственные С У ЬД и < срвер О1ЛР Для эт<ж I» к но использовать разные СУБД и ОБЛР-продукты, и их воаможимсти и ф, „ц(Ии могут быть расширены путем разработки ДипоЛ1Шн*лЬжмо П|К>граммного oG-< (lr чення, которое осуществляло бы пе|нп|х>рмати|х»иание, агрегирование, иптег|мн цию и передачу данных от одного процессора информационною хранилища другому Кроме того, могут потребоваться программы для хранения и обработки нечисловых данных, например графики и анимации. Поскольку назначение информационного хранилища в том, чтобы сделать данные организации более доступными, в нем должны быть средства не толь- ко доставки данных пользователям, но и передачи данных для анализа, ответов на запросы, составления отчетов, а также оперативной аналитической обработки с определяемыми пользователем принципами группировки и разгруппировки. Информационное хранилище предоставляет важный, но сложный набор ре- сурсов и услуг. Поэтому в нем должны быть предусмотрены курсы обучения персонала, учебные пособия, интерактивные справочные утилиты и другие подоб- ные продукты, облегчающие использование ресурсов информационного хранили- ща. Наконец, информационное хранилище должно иметь квалифицированный персонал, предоставляющий консультационные услуги. Требования к информационному хранилищу Требования к информационному хранилищу отличаются от требований к обыч- ному приложению базы данных. Во-первых, в типичном приложении базы дан- ных структура отчетов и запросов стандартизирована: содержащиеся в них дан- ные могут меняться со временем, но структура их остается прежней. В отличие от этого, пользователям информационного хранилища часто нужно менять структу- ру запросов и отчетов. СМОТРИМ пример. Допустим, компания определяет зоны ответственности п1««ДаВЦ0Д П° ге°5₽аФическомУ принципу — скажем, на каждый штат или про- пппЧИЮ евеРнои Америки имеется свой продавец. Теперь предположим, что ьзователь 11НФ°Рма1111ОННОГО хранилища хочет узнать, как изменятся разме- mm ° 4*1СС11ОННЫХ> если вместо географического распределения персонала про- д ам удут назначаться конкретные клиенты. Чтобы сравнить эти альтернативы, ажно сгруппировать продажи по компаниям и по штатам. Структура запросов Еще одно раз ш i °Надобятся для этой «ели, будет различаться. давать принцип г * С0СТ0Ит в гом’ что пользователи хотят самостоятельно за- исследовать эгЬж Руппировки Данных. Например, пользователю, который хочет . жет потоебопят СКТ °Т различных маркетинговых кампаний, в одном случае мо- тинговой программе’ГХтьем "° ЦВ<ЛУ упаКОВКН’ В лруГ0М - "° ШрКе" вых программ, а в четвертом ~ Ц”еТу упаковки лля каждой из маркетннго- цвета упаковки В каждой от "° Маркст,,нговым программам для каждого просто Л 1 ог,С1е аналитику важны одни и те же данные, ему просто нужно т.ра.,„шр и tm„„upmamb >
Информационные хранилища Пользователи информационного хранилища хотят самое г параметры не только группировки, но и разгруппировки или ЗЭДаВаТЬ разбиения (drill down), данных. Пусть, например .«экранепо ПараметР11Чет о совокупных продажах за определенный год ’ Пользовавадсгавлс,1ы да,,ПЬ1е чтобы одним щелчком на данных можно было разбить нх на пр». по меся” нам, а следующим щелчком - „а продажи по месяцам „ продукт ли по £ гионам, продуктам и месяцам. Хотя можно написать приложение ба. ы да "пых которое обеспечивало бы такую возможность для фиксированного набора пара- метров разбиения, чаще всего эти параметры зависят от пользователя и задачи Б действительности, некоторые пользователи и сами не знают, какое разбиение данных нм нужно, пока не увидят данные и не попробуют различные типы раз биения. Следовательно, средства параметрического разбиения данных должны быть гибкими. Еще одним общим требованием является графическое отображение результа- тов. Пользователи хотят видеть результаты географического разбиения данных в соответствующей форме - например, продажи, сгруппированные по штатам и провинциям, должны быть показаны на фоне карты Северной Америки, а пере распределение сотрудников по офисам должно быть представлено на диаграмме офисного пространства. Опять-таки, эти требования выполнить труднее, посколь ку они зависят от конкретного пользователя и конкретной задачи. Наконец, многим пользователям информационных хранилищ нужна возмож ность импортировать данные из них в специализированные программы. Например, финансовым аналитикам хочется импортировать данные в электронные таблицы и программы финансового анализа. Менеджерам портфеля заказов нужно им- портировать данные в программы управления портфелем заказов, а инженерам буровых установок — в программы сейсмического анализа. Все это обычно означа- ет, что данные из информационного хранилища должны форматироваться опре- деленными способами. Список требований к информационному хранилищу при- веден во врезке. КАТЕГОРИИ ТРЕБОВАНИЙ К ИНФОРМАЦИОННОМУ ХРАНИЛИЩУ » Запросы и отчеты с переменной структурой. ♦ Группировка данных по произвольным критериям. ♦ Параметрическое разбиение данных по произвольным критериям. ♦ Графический вывод. ♦ Интеграция со специализированными программами. Проблемы разработки и эксплуатации информационных хранилищ Лосих пор мы идеализировали информационные О НИХ могло возникнуть впечатление как о “а1|< ,мож11Остей является весьма Пени ний I1а де и- же реализация писанных нам“ которые сложной задачей. В этой связи существуй несколько I Предстоит решить.
718 Глава 15. Совместное использование данных предприятия Несогласованность данных Если информационное хранилище предоставляет недостоверные данные, то ясно что такое хранилище является бесполезным, а то и вредным. Дело заключается не только в качестве данных, которые информационное хранилище извлекает из своих источников. Информация из источника данных может быть достоверной на момент извлечения, но при объединении данных, нс согласованных между собой по времени или типу (домену), можно нечаянно внести ошибки. Рассмотрим пример извлеченных данных (табл. 15.4 и 15.5). Первая таблица представляет собой выдержку из данных о заказах, а вторая — выдержку из дан- ных о выписанных продавцам премиальных. Предположим, пользователь инфор- мационного хранилища хочет исследовать связь между эффективностью работы продавца и его премиальными. Как может показаться на первый взгляд, все, что для этого нужно сделать, — это сложить суммы заказов каждого продавца и срав- нить итоговый результат с суммой его премиальных. Эгу задачу может выпол- нить следующий SQL-код: Т*. ж л f О т I I SELECT ИмяПродавца. 5иш(СуммаЗаказа). СуммаПремиальных FROM ЗАКАЗ. ПРЕМИЯ WHERE ЗАКАЗ.НомерПродавца = ПРЕМИЯ.НомерПродавца GROUP BY ЗАКАЗ.НомерПродавца (Попутно заметим, что типичный пользователь информационного хранили- ща, скорее всего, не знает SQL в объеме, достаточном для написания такого кода, поэтому должен найтись кто-то, кто сделает это за него, или должна быть какая- то программа, которая сгенерирует его автоматически через графический интер- фейс запроса.) Таблица 15.4. ЗАКАЗ НомерПродавца НомерЗаказа СуммаЗаказа 100 1000 $12000 200 1200 $17000 100 1400 $13500 300 1800 $11335 Таблица 15.5. ПРЕМИЯ НомерПродавца ИмяПродавца СуммаПремиальных — 100 Mary Smith $3000 200 Fred Johnson $2500 300 Laura Jackson $3250 Будем считать, что данные были достоверными на момент извлечения, и пред- положим, что они были получены из двух различных информационных систем системы обработки заказов и системы учета заработной платы сотрудников, скольку данные извлекались из разных информационных систем, то неизвестно,
согласованы ли они между собой по о достоверными по сос™„„ю на „жктб“''И альных - на последний день месяца. В данных „ет LZ „о™™ Т”"’ это различие, а в реальности о нем может „„кто и не знаГьО,п™ оказать существенное влияние на результаты анализа. ° °U° М°ЖСТ таблицы ПРОДАВЕЦ и РЕГИОН^табл °1Тб Г15 7) ДаНПЫХ <«OMe»)- Рассмотрим ставить отчет о совокупных п'род^х по” ся следующий SQL-код: У-А этою потребует- SELECT ТорговаяЗона. 5ит(СовокупныеПродажи) FROM РЕГИОН. ПРОДАВЕЦ WHERE РЕГИОН.ТорговаяЗона = ПРОДАВЕЦ Регион GROUP BY ТорговаяЗона Таблица 15.6. ПРОДАВЕЦ ИмяПродавца Регион Год СовокупныеПродажи Johnson SO 2000 $175998 Wu NW 2000 $223445 O'Connor NE 2000 $337665 Abernathy SE 2000 $276889 Lopez SW 2000 $334557 Johnson SO 2001 $225998 Wu NW 2001 $276445 O’Connor NE 2001 $389737 Abernathy SO 2001 $362768 Lopez so 2001 $419334 Таблица 15.7. РЕГИОН ТорговаяЗона Менеджер NW NE Allen Brendlmann Currid Для приведенных в таблицах 15.6 и 15.7 данных результатом запроса будет таблица с гремя строками, по одной на каждую из торговых зон NW, NE и SO Поскольку ли зона SE, ни зона SW не указаны в таблице РЕГИОН, они не появи- лись в соединении, и продажи из этих зон не будут учтены в результате. Скорее всего, в намерения пользователя входило нечто другое. В реальности дело обстояло так: в период между 2000 и 2001 годами компа- ния внесла изменения в каргу торговых зон, объединив зоны SE и . в одну зону SO Соогвсгствснно, в строку SO результата запроса следовало добавить суммы продаж всех продавцов из зон SE н SW. Если выразить это в терминах •Сирии баз данных, можно сказать, что домены атрибутов ТорговаяЗона и Регион
720 Глава 15. Совместное использование данных предприятия различаются. Домен атрибута ТорговаяЗона — это множество торюных зон на настоящий момент, а домен атрибута Регион — название гирпшой зоны, в которой была произведена продажа, на момент этой продажи Для небольших объемов данных, как в табл. 15 6 и 15.7, ни проблемы имеют очевидный характер. Но, когда таблицы содержа г тысячи строк данных, такое несоответствие может ускользнуть о г внимания аналитика, и принимаемые ре шения будут основываться на недостоверных данных. Для решения этой проблемы должны создаваться метаданные, описывающие временные характеристики и домены исходных данных. Эти метаданные долж- ны быть легко доступными для пользователей информационного хранилища а пользователей необходимо научить уделять серьезное внимание этим во- просам. Интеграция средств Еще одна серьезная проблема, связанная с информационными хранилищами, ка- сается интеграции разнообразных средств, необходимых пользователям для ра- боты. Парадигмы различных продуктов и категорий продуктов, как правило, раз- личаются. СУБД оперируют таблицами, средства OLAP — кубами, программы обработки электронных таблиц — электронными таблицами, пакеты финансово- го планирования — планами, и т. д. Б результате пользовательские интерфейсы этих продуктов оказываются непохожими. Обучение пользователей работе с не- сколькими продуктами, принадлежащими к различным категориям, может по- требовать существенных затрат, и зачастую у самих пользователей на это нет ни времени, ни желания. Еще более серьезную проблему представляют экспорт и импорт данных между продуктами из различных категорий. Рассмотрим электронную таблицу (табл. 15 8). В ней содержатся данные по трем различным темам: отделы, менед- жеры и сотрудники. Чтобы импортировать эту таблицу в нормализованном виде в базу данных, каждую тему нужно будет вынести в отдельную таблицу: СОТРУДНИК (НомерСотр, ИмяСотр, НомерОтдела) ОТДЕЛ (НомерОтдела, КодОтдела, Менеджер) МЕНЕДЖЕР (Менеджер, ТлфМенедж) Если нормализацию не проводить, результатом будет значительное дубли- рование данных, как описано в главе 4. Однако обычный пользователь базы данных, во-первых, не поймет, для чего требуется нормализация, а во-вторых, не будет знать, как ее выполнить. О1 * %* т КС & в в а в д о 0 д р л с а 3 л 8 Таблица 15.8. Электронная таблица ——. И НомерСотр ИмяСотр НомерОтдела Менеджер ТлфМенедж КодОтдела 5 1000 Wu 10 Murphy 232-1000 A47 Cl 2000 O’Connor 20 Joplin 244-7788 D87 3000 Abernathy 10 Murphy 232-1000 A47 II 4000 Lopez 20 Joplin 244-7788 D87 4
Информационные хранилища 721 Наконец, при совместном испольчппямтт,. ,«водитель продукта, из которого экспортируются данные. ZZ , ™ в некорректном экспорте-импорте виновата программа, „ у,,Х™я , ? „орт, а производитель этом программы может заявлять прямо про™, .П”^?.Т““та"теЛи1 "" ™ °"“та эксплуатации „роду™ дру”^ чужих решений, техническая под- ни желания способствовать использованию держка может превратиться в кошмар. Отсутствие средств управления данными информационного хранилища Хотя есть множество продуктов и средств, предназначенных для извлечения информации из источников данных, и множество ориентированных на конеч- ного пользователя средств анализа данных и создания запросов и отчетов, на настоящий момент наблюдается отсутствие средств управления самим инфор- мационным хранилищем. Если бы информационное хранилище состояло толь- ко из выдержек из реляционных баз данных, а проблемы различия временных характеристик и доменов могли быть разрешены путем обучения и четкого опре- деления процедур, задача управления ресурсами информационною хранилища была бы под силу коммерческим СУБД. В большинстве случаев, однако, это не так. Большая часть информационных хранилищ содержит выдержки не только из баз данных, но также из файлов, электронных таблиц, изображений и внешних источников данных. Поэтому управлять ресурсами информационного хранили- ща средствами одной только коммерческой СУБД невозможно, и организации, создающие информационное хранилище, вынуждены разрабатывать собственное программное обеспечение. Обычно ядром такого программного обеспечения яв- ляется СУБД, а штатный персонал информационного хранилища осуществляет реализацию дополнительных возможностей и функций, необходимых для управ- ления ресурсами хранилища. Другая, сходная проблема касается управления метаданными. Лишь в немно- гих СУБД возможности словарей данных отвечают потребностям информацион- ного хранилища в сфере управления метаданными. Как уже говорилось, поль- зователям необходимо знать не только то, что содержится в информационном хранилище, но и происхождение данных, их временные характеристики, домены, предположения, сделанные при извлечении данных, и г. д. Персоналу информа ционного хранилища необходимо разрабатывать собственное программное о ес лечение управления метаданными, дополняющее возможности СУБД и друг ix средств управления словарями данных. Разработка программного обеспечения управления данными является слож- ным и дорогостоящим делом. Созданное программное обеспечение должно ОД Держиваться П)юизводители программ извлечения и анализа данных совершим гвуют свои продукты, и для поддержки новых .н.терфешов придется
722 Глава 15. Совмести исп< ьзование данных щмщприяуии вносить изменения в собственное программной обеспечение Более того будут меняться и требования пользователей, что приведет к необходимости стячниа новых программ, которые нужно будет затем mnei pnpouai ь в программна печение управления информационным хранилищем. Особый характер требований Информационные хранилища предназначены для поддержки принятая управ- ленческих решений. В то время как значительная часть принимаемых управлен- ческих решений имеет стандартный и повторяющийся характер, многие решения имеют особенную природу. Вопросы о том, следует ли объединять торговые зоны и склады, продавать определенную линию продуктов, внедрять новые стратегии Интернет-продаж и маркетинга, не относятся к числу стандартных и возника» щих регулярно. Компьютерные системы, подобно системам бюрократическим, неповоротли- вы и дороги в настройке, и наиболее эффективно они работают, когда потребно- сти отвечают определенному шаблону. Поэтому эти системы отлично выполня- ют такие задачи, как ввод заказов и бронирование мест. Сложнее разработать систему', которая бы оперативно приспосабливалась к нестандартному измене- нию требований и нужд. Таким образом, информационные хранилища успешнее всего работают в приложениях, где изменение требований следует определенно- му шаблону. Если новое требование сходно по структуре с предыдущим, напри- мер, «консолидация серверной торговой зоны будет похожа на консолидацию южной торговой зоны», то информационное хранилище сможет быстро приспо- собиться к этому требованию. Если же нет, понадобятся значительные затраты времени, средств и усилий. Информационные лавки В связи с описанными выше неудобствами некоторые организации решили огра- ничить область охвата информационных хранилищ, чтобы взамен получить большую управляемость. Информационная лавка (data mart) — это то же инфор- мационное хранилище, но с более узкой направленностью. Информационные лавки могут быть ориентированы на определенный тип входных данных, кон- кретную бизнес-функцию, отдельную организационную единицу или некоторую географическую область. Ограничение содержимого информационной лавки определенным типом дан- ных (например, базы данных и электронные таблицы) облегчает управление ин- формационным хранилищем и потенциально позволяет использовать для этих целей обычную коммерческую СУБД. К тому же, метаданные в этом случае име- ют более простую структуру, и их легче поддерживать. В информационной лавке, ориентированной на выполнение конкрет ой биз- нес-функции, может быть множество типов данных и метаданных, требующих поддержания, но все эти данные служат одному и тому же типу цользовате.
Администрирование данных 723 Средства управления информационным хранилищем и выдачи данных пользо- вателям могут быть разработаны с учетом предпочтений рыночных аналитиков. Наконец, информационная лавка, ограниченная отдельной организационной единицей или географической областью, может иметь много различных типов входных данных и пользователей, но количество обрабатываемых в пей данных оказывается меньшим, чем для всей компании. Меньше будет и запросов па об- служивание, поэтому ресурсы информационного хранилища могут быть выделе- ны меньшему количеству пользователей. На рис. 15.14 показаны области охвата различных вариантов совместного ис- пользования данных, рассматривавшихся в этой главе. Загрузка данных — самая узкая по направленности и наиболее простая альтернатива. Данные извлека- ются из работающих систем и доставляются определенным пользователям для конкретных целей. Загружаемые данные предоставляются регулярно, поэтому структура приложения фиксирована, пользователи хорошо обучены, а возник- новение таких проблем, как несогласованность по времени и домену, маловеро- ятно, поскольку пользователи приобретают опыт, работая с одними и теми же данными. На другом полюсе находится информационное хранилище, пре- доставляющее множество различных типов данных и услуг, как в обычном по- рядке, так и по запросам особого характера. Информационные лавки находятся посередине. По мере движения слева направо по диаграмме альтернативы ста- новятся более мощными, но при этом более дорогостоящими и сложными в реа- лизации. Загрузка данных Информационные лавки Конкретный тип Конкретная Конкретная входных данных бизнес- организационная функция единица или географическая область Информационное хранилище Проще — Рис. ---------—------Сложнее 15.14. Варианты совместного использования данных предприятия по степени сложности Администрирование данных Данные оршпизации являются таким же ресурсом, как и производственные помещения, оборудование и финансовые активы. Сбор данных требует боль- ших затрат времени и средств, а применение полученной информации не огра- ничивается iojii.iw произволе!венной деягел1.н<>сп.1о. Информация, полученная в ре »ульт,| ге анализа данных, мож<ч бы i ь попользована для оценки работы персо- нала, качества продукции и зффек! пвпосгп маркетинговых программ, а также
724 Глма 1&- Совмоетнов иелол«.к>»<1нив данных »цм»днрм»гт для определения тенденций в покупательских пре.кияо пйм. . 1<ми и т д С ее помотьм можно модслпрсмать <ФФГК'Т ..i изменения П|юдукт<я»,«гдамий продаж и торговых эон. t пнсок «можных применении столь ы жк, что в кости данные зачастую служат средством к к i и а гни и и удержании ирецмудавдг ва компании в конкурентной борьбе. К сожалению, однако, пока данные нхшьмт ся в рабочих базах данных, полезность их оцыничсна, Ввиду потенциальной ценности данных как одного из видов организацион- ных ресурсов на многих предприятиях были создан^ отделы ддашииырирьь, ння данных (data administration). В задачи лих отделов входит не только охрана и защита данных, но и обеспечение их эффективного использования В каком-то смысле администратор данных (data administrator) выполняет в отношении данных ту же функцию, что ревизор - в отношении денежных средств. Ревизор отвечает не только за то, чтобы финансовые активы были надежно защищены и правильно учтены, но также за то, чтобы они хМ-ективно использовались. Если хранить деньги предприятия где-нибудь в подвале, они, вероятно, будут защищены, но не будут эффективно использоваться. Деньги сле- дует инвестировать таким образом, чтобы они служили достижению целей орга- низации. Аналогичным образом, в администрировании данных одной только защиты данных недостаточно. Нужно также стремиться к повышению Д-с- - тивности использования организационных данных. Потребность в администрировании данных Чтобы понять, для чего нужно администрирование данных, рассмотрим анало- гию с университетской библиотекой. Обычно университетская библиотека со- держит сотни тысяч книг, журналов, правительственных отчетов и т. д., но от них нет никакого проку, если они просто стоят на полках. Чтобы книги и журналы приносили пользу, необходимо, чтобы ими могли воспользоваться люди, которые в них нуждаются. Ясно, что библиотека должна иметь какое-то описание своего содержимого, чтобы потенциальные читатели могли узнать, что имеется в наличии. На первый взгляд решение выглядит тривиально — например, создать карточный каталог. Но это потребует большой работы. Как должны идентифицироваться единицы хранения? Как они должны описываться? Есть и фундаментальный вопрос — что вообще такое единица хранения? Каким образом можно обеспечить сосу- ществование различных способов идентификации (ISBN, десятичная система Дьюи, номер правительственного отчета)? Как помочь людям найти материалы, о существовании которых они и не подозревают? Есть и другие сложности. Предположим, университет настолько велик» имеет несколько библиотек. Как в этом случае следует организовать ра оту с браниями книг, чтобы они представляли собой единый ресурс? Болес некоторых кафедрах могут быть собственные библиотеки. Следует ли их в университетскую библиотечную систему? У многих преподавателей? ся обширные личные библиотеки. Должны ли они быть частью сис
Администрирование данных 725 Проблемы администрирования данных Описанная выше аналогия с библиотекой недостаточно глубока, поскольку ад- министрирование данных организации является значительно более сложной задачей, чем администрирование библиотеки. Во-первых, в принципе не ясно что здесь представляет собой «единица хранения». Библиотеки содержат кни- ги, периодику и т. п„ а данные организации поступают в огромном множестве форматов. Это могут быть традиционные записи, но есть еще документы, элек- тронные таблицы, графики и иллюстрации, чертежи, аудио- и видеофайлы. Как это все должно описываться? Каковы основные категории организацион- ных данных? Эти вопросы представляют важность, поскольку ответы на них определяют способ организации, каталогизации, защиты, оценки и управления данными. В большинстве организаций для одних и тех же вещей существует множество названий. Например, номер телефона может называться НомерТелефона, Телефон, ТелефонныйНомер, ТелефонСотрудника и ТелефонОтдела Какие из этих названий являются более предпочтительными? Когда графический дизайнер разрабаты- вает форму с номером телефона, какое обозначение он должен использовать? Когда программист пишет программу, какое имя он должен дать переменной, содержащей номер телефона? Когда пользователь запрашивает код региона клиента при анализе покупательских тенденций, какое имя он доджей указать в запросе? Есть также много способов представления элемента данных. Номер телефона может быть представлен 10-значным целым числом, текстовым полем из 10 сим- волов, текстовым полем из 13 символов в формате (ппп)ппп-пппп, текстовым по- лем из 12 символов в формате ппп-ппп-пппп или в других форматах. Какой из них следует выбрать? Какой следует сделать стандартным, если потребуется? И все же, такие различия между данными организации и материалами биб лиотеки — ничто по сравнению с главным: люди должны иметь возможность из- менять данные организации. Что было бы, если бы люди, беря книги в библиотеке, принимались в них пи- сать, вырывать страницы, вставлять новые, а потом возвращали бы их на полки? Или еще хуже: представьте, что некто берет в библиотеке три книги, вносит во все три какие-то изменения и возвращает обратно, заявляя библиотекарю. «Вы должны либо поменять все три книги, либо не менять ни одной». Поскольку данные организации являются совместно используемыми ресур- сами, на права и обязанности по их обработке должны быть наложены ограниче- ния Например, когда сотрудник покидает компанию, его записи нельзя удаля ь сразу же: они должны поддерживаться в течение нескольких лет для управлен- ческой отчетности и расчета налоговых отчислений. Следовательно, ни один от- дел ие может самостоятельно удалить информацию из базы данных юлько на том основании, что сотрудник в нем больше не числится. Отдел админш три- рования должен помочь в определении прав и обязанностей пользователей ио
726 Глава 15. Совместное использование данных нредг ооработке Эта роль анал«н ичиа роли администратора С*даедик, <к1мс*ш^4 в главе 9, однако в том случае зона иПи и ин нИрсти ограничивалась вту >« »<jfc базой данных; здесь же такой зоной является вся органи шния В дополнение ко всем этим техническим проблемам существуют также яр^ блемы организационного порядка Например, прапа на доступ к данным могут быть источником власти в организации, следовательно, изменения в этих пра- вах могут означать перераспределение полномочий власти Таким образом за администрированием данных стоят всевозможные политические вопросы. И/ обсуждение выходит за рамки настоящего изложения, но от этого они ие ста- новятся менее важными. Проблемы администрирования данных перечислены во врезке. ПРОБЛЕМЫ АДМИНИСТРИРОВАНИЯ ДАННЫХ ----------------------------—-------— ♦ Существует множество типов данных. ♦ Базовые категории данных не очевидны. ♦ Одни и те же данные могут называться по-разному. ♦ Одни и те же данные могут иметь много описаний и форматов. ♦ Данные изменяются, зачастую параллельно. ♦ Политические и организационные вопросы усложняют решение цабо-иж эаоаосо. Задачи отдела администрирования данных Описанные выше проблемы усложняют администрирование данных. Чтобы за- щитить данные организации и одновременно увеличить выгоду от них, отдел ад- министрирования данных должен выполнять несколько задач. Как показывает врезка «Задачи отдела администрирования данных», их можно разделить на не- сколько категорий. Связи с общественностью В первую очередь, отдел администрирования данных отвечает за осведомлен- ность организации о собственном существовании и за предоставление своих услуг остальной части организации. Сотрудники должны знать, что существует администрирование данных, что оно включает определенную политику, стандар- ты и руководящие принципы, касающиеся данных организации и строящиеся по определенным правилам; они должны понимать, почему необходимо уважать и соблюдать эти правила, руководящие принципы и ограничения. Администрирование данных должно быть сервисом, и именно так его долж ны воспринимать пользователи. Таким образом, мероприятия по администрн рованию данных должны представляться организации в позитивном свете, как нужная и полезная услуга. Сотрудники должны верить, что они могут что-то приобрести, участвуя в этих мероприятиях. В противном случае пользователи будут видеть для себя в администрировании одни сплошные затраты и никакой выгоды, и им будут пренебрегать.
Админис i рирование данных 727 ЗАДАЧИ ОТДЕЛА АДМИНИСТРИРОВАНИЯ ДАННЫХ ————________________________ Связи с общественностью ♦ Информировать сотрудников организации о существовании та.™ а, нистрирование данных. ° аНИИ такои Функции, как адми- > Объяснять причину существования стандартов, политики и руководящих принципов * ХТяСХыхЬ В П0Л0ЖИТеЛЬНОМ свете У^УИ- оказываемые отделом администриро- Стандарты организации данных Устанавливать стандартные способы описания элементов данных. Стандарты чают название, определение, описание, ограничения на обработку и т. д. Назначать распорядителей данных. вклю- Политика в отношении данных ♦ Устанавливать политику организации в отношении данных. Примеры: обеспечение безопасности, назначение распорядителей данных, распространение. Форум для разрешения конфликтов ♦ Устанавливать процедуры извещения о конфликтах. ♦ Обеспечивать возможность заслушивания всех точек зрения. ♦ Иметь полномочия на принятие решений, направленных на разрешение конфликтов Возврат средств, инвестированных организацией в данные ♦ Привлекать внимание к стоимости инвестиций в данные организации. ♦ Исследовать новые методы и технологии. ♦ Следовать упреждающей стратегии информационного управления. Стандарты организации данных Для эффективной работы с данными предприятия необходима их четкая органи- зация. Если бы каждый отдел или сотрудник мог по-своему определять понятие элемента данных или способ его именования или описания, возник бы хаос. Невозможно было бы даже составить опись данных, не говоря уже о том, чтооы работать с ними. Соответственно, многие организации пришли к выводу, что важные элементы данных должны описываться стандартно. Например, 01дел администрирования данных может решить, чго каждому элементу данных, пред ставляющему важность для организации, будут присвоены стандартное имя, оп ределение, описание, набор ограничении на обработку и т. п. Когда эта структура «дана, возникает следующий вопрос; кто будет устанавливать эти стандартные описания? Например, к го будет определять стандартное имя пли стандартные ограничения па обработку? Во многих организациях отдел администрирования данных не разра( а стандартные описания. Вместо этою для каждою элемента данных назначается так называемый распорядитель данных (data proponent) отдел или другая ор пшизациоиная единица, ответственная за работу с этим элементом. В обязанно- сти распорядителя входит разработка и поддержание официальных определении организации, касающихся назначениого ему элемента данных. Хотя отдел адм
728 Глава 15 Совместное использование данных предприятия нпстрнрования данных может быть распорядителем каких ю элементов дан большинство распорядителен относится к другим отделам. Встречается термин владелец данных (data owner), который обычно исполин ется в том же значении, что и введенный ранее термин распорядитель данных Мы будем избегать использования здесь этого термина, поскольку он в какой-то степени предполагает право собственности, что в действительности не имеет места. И с юридической, и с практической точки зрения организация является единственным владельцем своих данных. Хотя некоторые пользователи или группы пользователей имеют обоснованное право претендовать на большую свободу распоряжения определенными данными, чем другие, эти группы не яв- ляются владельцами данных. Поэтому мы отдаем предпочтение термину распо- рядитель данных. Итак, в основе администрирования данных лежит система стандартов органи- зации данных. Отдел администрирования данных отвечает за работу с пользовате- лями и менеджерами для установления работоспособной системы стандартов, которая должна быть документирована и представлена организации некоторым эффективным способом. Кроме того, должны быть разработаны процедуры оцен- ки степени соблюдения стандартов сотрудниками. Политика в отношении данных Еще одна группа функций отдела администрирования данных касается политики в отношении данных. Чтобы показать необходимость существования такой поли- тики, рассмотрим сначала вопрос безопасности данных. У каждой организации имеются конфиденциальные данные, и отдел администрирования данных отвеча- ет за разработку системы безопасности для их защиты. При этом необходимо от- ветить на вопросы: какие схемы обеспечения безопасности данных должны быть применены? Нужна ли организации многоуровневая система безопасности, подоб- ная существующей в военных организациях, или достаточно будет более простой системы? Политика безопасности должна также определять, какие требования будут предъявляться к людям, имеющим доступ к конфиденциальным данным, и какие договоры они должны будут для этого подписывать. Следует ли допускать копирование конфиденциальных данных? Как должно проводиться обучение сотрудников мерам по безопасности данных? Что следует предпринимать при нарушении установленных процедур безопасности? Второй тип политики в отношении данных касается распорядителен данных и прав на обработку. Что значит быть распорядителем данных? Какие права имеет распорядитель по сравнению с другими группами? Кто выбирает распоря дителя данных, и как можно поменять ответственного за выбор? Третий тип политики в отношении данных затрагивает распределение дан ных — например, должны ли официальные данные распределяться по множеств} компьютеров, и если да, то какой из экземпляров этих данных будет сч! официальным (если таковой будет). Какие виды обработки должны быть разре- шены по отношению к распределенным данным? Должны ли данные, которые
Администрирование данных 729 йыли распределены, возвращаться в официальное хранилище? Если да то какие процедуры проверки необходимо к ним применять перед принятием? Форум для разрешения конфликтов относительно данных Чтобы данные организации использовались эффективно, доступ к ним должен быть коллективным, но природа людей такова, что они не любят делиться Соот ветственно, организация должна быть готова к разрешению споров, касающихся распорядителен данных, ограничений на обработку и других вопросов. Первое, за что в этой связи отвечает отдел администрирования данных, — за ведение процедур извещения о конфликтах. Когда у одного пользователя или группы пользователей возникает конфликт с другим пользователем или группой, сторонам необходим четкий порядок извещения об имеющем место конфликте' После признания конфликта всем сторонам, вовлеченным в него, должна быть обеспечена возможность представить свою точку зрения в рамках установленных процедур. Персонал отдела администрирования данных, возможно, при участии распорядителей затронутых конфликтом данных, должен разрешить конфликт. Данный сценарий предполагает, что организация дает отделу администрирова- ния данных полномочия выносить и исполнять решения по возникающим кон- фликтам. Отдел администрирования данных организует форум по разрешению кон- фликтов, работающий в масштабе всей организации. В задачи отдела админист- рирования базы данных также входит организация такого форума, но относяще- гося к конкретной базе данных. Увеличение отдачи от инвестиций в данные предприятия Последняя функция отдела администрирования данных — увеличение отдачи от инвестиций в данные предприятия. В рамках этой функции отдел администриро вания может задаваться такими вопросами: с максимальной ли эффективностью используются ресурсы данных организации? Можно ли получить большую отда чу? Если нет, то почему? Стоит ли все это понесенных затрат? Данная функция включает в себя все остальное — связи с общественностью, установление стан Дартов и политики, разрешение конфликтов и т. д. Инотда эта функция предпола тает также исследование новых способов хранения, обработки и представления Данных, новых методов, технологий и г. и Успешное выполнение этой задачи требует упреждающей стратегии инфор- мационною управления. Интерес представляют вопросы о том, можно ли ис пользовал. информацию для улучшения положения на рынке, повышения кон Курентоспособности и увеличения собственного капитала компании .Отдел администрирования данных должен работал, в нт ном тотрхдни ,CC1IJ- *’•'’ ‘ ми планирования и развития предприятия, чтобы предвидеть новые требования к информации, а не просто ре<п иронать на них.
730 IS COBMeciи ИСПОЛЬЗОвапуч ДАННЫХ Првд/Ц>ив(И* Наконец, данные необходимо сделан» дс»! у иными для нот» ншы.юмю зователей. Дсктупнос! ь означает не npu< w техническую возможность получ«шя данных опытным и це ieycJ ремленпым персоналом, а П|>ед<хтавление мимэд телям данных удобным для них способом и и форматах, которые исодфедстмэд но применимы к выполняемой ими рабою. Резюме Классической архитектурой обработки многопользовательских баз данных явля- ется удаленная обработка. При ней пользователи работают с «глупыми» тер- миналами или персональными компьютерами, их эмулирующими Программа управления коммуникациями, прикладные программы, СУБД и one: система работают на едином центральном компьютере. Поскольку вся обрабола производится единственным компьютером, пользовательский интерфейс систем удаленной обработки обычно прост и примитивен. Клиент-серверная система состоит из компьютеров, объединенных в сеть, ча- ще всего локальную (LAN). Почти во всех случаях компьютеры пользователей, называемые клиентами, являются персональными компьютерами, и в большин- стве случаев в роли сервера также выступает персональный компьютер, хотя для этой цели может использоваться и большая ЭВМ. Прикладные программы рабо- тают на клиентском компьютере, а СУБД и часть операционной системы, отве- чающая за обработку данных, находятся на сервере. Системы с совместным использованием файлов также состоят из компьюте- ров, объединенных в сеть, и, подобно клиент-серверной архитектуре, сеть обыч- но является локальной, а компьютеры — персональными. Основное различие между системами с совместным использованием файлов и клиент-серверными системами состоит в том, что серверный компьютер предоставляет меньшее ко- личество услуг компьютерам пользователей. Сервер, который в данном случае называется файловым сервером (file server), а не сервером базы данных (database server), предоставляет доступ к файлам и другим ресурсам. Следовательно, как СУБД, так и прикладные программы должны быть установлены на пользова- тельских компьютерах. В системе распределенной обработки базы данных одну и ту же базу данных обрабатывает множество компьютеров. Есть несколько типов распределенных баз данных: разделенная и нереплицированная, неразделенная и реплициро- ванная и разделенная и реплицированная. В общем случае, чем больше степень разделения и репликации, тем больше гибкость, независимость и надежность. С другой стороны, возрастают временные затраты и увеличивается сложность управления и обеспечения безопасности. Существуют три способа обработки распределенных баз данных: загрузка дан- ных только для чтения, выделение специализированного компьютера для обнов- ления базы данных и обновление данных множеством компьютеров. При распре- деленном обновлении возникает три типа конфликтов: потеря уникальности,
Резюме 731 „отер» обновлений из-за параллельных транзакций и обновление стертых дан- Если удаление допускаете» более нем на одном компьютере, зги необходимо решать. 1 рмилемы Координация распределенных атомарных транзакций сложна и требует двух- фазного сохранения. Для решения зтих проблем „редназналевы так™ техволо- ГИИ. как OLE Distributed Transaction Server и Enterprise Java Beans. С появлением мощных персональных компьютеров стала возможна загрузка значительных объемов данных предприятия на компьютеры пользователей для локальной обработки. Пользователи могут запрашивать загруженные данные и составлять на их основе отчеты, используя установленные на своих машинах СУБД. В большинстве случаев пользователям не разрешается обновлять и воз- вращать данные, поскольку это может привести к потере целостности дан- ных. Даже если загружаемые данные не обновляются и не возвращаются, могут возникать проблемы координации данных, согласованности, контроля доступа и компьютерной преступности. Для публикации загруженных данных можно использовать веб-сервер. Оперативная аналитическая обработка данных (OLAP) — это новый способ представления информации. Данные изображаются в кубах, имеющих оси, из- мерения, меры, слои и уровни. Оси описывают физическую структуру пред- ставления — строки и столбцы. Измерения — это характеристики данных, от- кладываемые вдоль осей. Меры — это отображаемые значения данных. Слоями называются атрибуты куба (измерения или меры), которые должны оставаться постоянными в представлении. Уровень — это атрибут измерения, описывающий его положение в иерархии. Термин куб относится как к семантической структуре, используемой для ин- терпретации данных, так и к конкретной материализации данных в такой семан- тической структуре. В листинге 15.1 показан один из способов определения структуры, а в листинге 15.2 — один из способов определения материализации структуры куба. ROLAP (реляционная OLAP), MOLAP (многомерная OLAP) и HOLAP (гиб- ридная OLAP) представляют собой три разновидности оперативной аналитиче- ской обработки данных. Сторонники ROLAP говорят, что реляционной СУБД с некоторыми расширениями достаточно для удовлетворения вычислительных требований OLAP, сторонники MOLAP возражают, что для этих целей необхо- дим специализированный многомерный процессор, а сторонники заяв ляют, что нужно использовать и то и другое. Компания Microsoft создала для OLAP расширения OLE DB и ADO. OLE Do Для OLAP включает объект, называемый набором данных; объектная модель ADO MD содержит новые объекты, позволяющие обрабатывать наборыданных так же, как и наборы записей. В Office 20Q0/XP и Windows 2000/ХР была добав- лена Главная служба таблиц. Архитектура Microsoft переносит а=ю часть OLAP обработки па клиентские компьютеры; будет ли это приемлемо для обработки данных па серверах предприятии, пока неизвестно
732 Глава 15. Совместное использования данных предприятия Информационное хранилище — это хранилище данных предприятия, пред* назначенное для упрощения принятия управленческих решений 13 информа- ционном хранилище содержатся выдержки из рабочих баз данных, файлы изображения, записи, фотографии, внешние данные и другая информация Ин- формационное хранилище предоставляет доступ к этим данным в формате, у добном для пользователей. Компонентами информационного хранилища являются средства извлечения данных, выдержки данных, метаданные, одна или несколько СУБД, разрабс ное на предприятии программное обеспечение для управления данными, про- граммы доставки данных, аналитические средства, курсы обучения пользовате- лей и консультирующий персонал. Типичные требования к информационному хранилищу включают создание запросов и отчетов с переменной структурой, группировку данных по задаваемым пользователем критериям, параметрическое разбиение данных, графическое отображение результатов и интеграцию со спе- циализированными программами. В ходе создания и использования информационных хранилищ приходится решать несколько важных проблем. Во-первых, при объединении данных из раз- Л1 чных источников результат может содержать несогласованности из-за разли- чия временных характеристик и доменов исходных данных. Далее, в инфор- мационном хранилище, как правило, имеется большое количество прикладных программ, относящихся к разным областям. Пользовательские интерфейсы этих программ могут значительно различаться, экспорт и импорт данных между ними может осуществляться некорректно, а получить техническую поддержку может быть трудно. Еще одна проблема — отсутствие средств управления самим информаци- онным хранилищем. Организация может быть вынуждена самостоятельно разра- батывать программное обеспечение для управления нереляционными данными и поддержания соответствующих метаданных. Разработка такого программного обеспечения является сложной и дорогостоящей. Наконец, многие запросы к ин- формационному хранилищу имеют необычную природу; такие запросы трудно выполнить. В связи с этим многие организации разработали информацион- ные хранилища с ограниченной областью охвата, называемые информационны- ми лавками. Данные являются важнейшим активом организации, который обеспечива- ет поддержку как деловых операций, так и принятия управленческих решений. Задача отдела администрирования данных состоит не только в охране и защите информационных активов, но и в обеспечении их эффективного использования. Одной из наиболее важных функций отдела администрирования данных являет ся документирование содержимого информационных активов организации. Это сложная задача, поскольку данные хранятся во множестве различных форма и разбросаны по всей организации. Отдел администрирования данных должен помогать в j гановлепии организационных стандартов на имена и форматы эле ментов данных, а также в определении прав и обязанностей по обработке. Нако-
Вопросы группы I 733 иец, поскольку данные представляют собой одни из видов ресурсов, пользование ими может быть источником власти, поэтому отдел администрирования данных должен иметь дело с организационными и политическими вопросами. Специфическ е функции отдела администрирования данных включают продви- жение его услуг, выработку стандартов организации данных и назначение распо- рядителен данных, выработку правильно» политики в отношении данных н соз- дание форума для разрешения конфликтов. Все эти функции направлены на то чтобы увеличить отдачу от инвестиций в информационные активы пре шрпягпя’ Вопросы группы I 1. Перечислите архитектуры, используемые для обработки многопользова- тельских баз данных. 2. Нарисуйте архитектуру системы удаленной обработки. Укажите, какие компьютеры и программы входят в се состав, н объясните, на каком компь- ютере работает каждая из программ. 3. Почему пользовательский интерфейс приложений удаленной об]жботкн обычно ориентирован на текст и примитивен? 4. Нарисуйте архитектуру клиент-серверной системы. Укажите, какие компь- ютеры н программы входят в ее состав, и объясните, на каком компьютере работает каждая из программ. 5. Какие типы компьютеров используются в клиент-серверных системах? 6. Сколько серверов имеет клиент-серверная система? Каковы ограничения, касающиеся серверов? 7. Нарисуйте архитектуру системы с совместным использованием файлов. Укажите, какие компьютеры и программы входят в се состав, и объясните, на каком компьютере работает каждая из программ. 8. Объясните, чем будет отличаться обработка следующего SQL-запроса в кли- ент-серверной системе от обработки в системе с совместным использова нием файлов: SELECT ИмяСтудента. НазваниеПредмета FROM СТУДЕНТ. УСПЕВАЕМОСТЬ WHERE СТУДЕНТ. НомерСтудента = УСПЕВАЕМОСТЬ. НомерСтудента AND УСПЕВАЕМОСТЬ.Оценка = '5' Пусть база данных имеет две таблицы. СТУДЕНТ (НомерСтудента, ИмяСтудента, ТелефонСтудента) УСПЕВАЕМОСТЬ (НомерПредмета, НомерСтудента, Оценка) Будем предполагать, «то nonepe„4,Mf, н ключам построены Я Обь,,, ..........ему системы совместным шпмо Вс„„л,.,у,о,с>, » приложениях, обрабатывающих т|>,,н.икц.ш с большими обкомами данных.
734 Глава 15. Совместное использование данных предприятия 10 {анте определения терминов разделение и реп шкацим в контексте прило- жении распределенных баз данных. И. Объясните разницу между вертикальным и гори.чоталышм фр.н ментам 12. Объясните, чем различаются четыре типа баз данных на рис 15 5 13. Перечислите и опиши те три способа обработки рас прсдслснной базы данных 14. Опишите три типа конфликтов, возникающих при распределенном обнов ленив 15. Каково назначение двухфазного сохранения? 16. Опишите в общих чертах проблему координации обработки загруженных баз данных. 17. Опишите в общих чертах проблему согласованности при обработке загру- женных баз данных. 18. Опишите в общих чертах проблему контроля доступа при обработке за- груженных баз данных. 19. Почему при обработке загруженных баз данных существует повышенный риск компьютерных преступлений? 20. Нарисуйте компоненты системы, использующей веб-сервер для публика- ции данных. 21. Что такое куб OLAP? Приведите пример, отличный от приведенного в табл. 15.2. 22. Объясните разницу между осью и измерением в OLAP. 23. Что такое мера куба OLAP? 24. Что означает термин слой по отношению к кубу OLAP? 25. Что такое член измерения? Приведите примеры для измерении Время и Место. 26. Объясните использование уровней в табл. 15.2. 27. В чем заключается неоднозначность термина куб? 28. Каким будет результат выражения CROSSJOIN ({Мэри, Линда}, {Парусный спорт. Лыжи})? А выражения CROSSJOIN ({Парусный спорт, Лыжи}, {Мэри, Линда})? 29. Напишите SQL-оператор SELECT, создающий куб, аналогичный приведен- ному в табл. 15.2, но в котором строки и столбцы меняются местами, а из мерение Место представлено перед измерением Категория (если читать сле- ва направо). 30. Объясните разницу между схемами «снежинка» и «звезда». 31. Что такое ROLAP, MOLAP и HOLAP? 32. Опираясь на обсуждение в этой книге, объясните, как стандарт OLE был расширен для OLAP? 33. Как расшифровывается ADO MD и каковы его функции?
—————————— -----------------.-------------Вопросы группы I 735 34. Данте определение термина «информационное хранилище». 3 . Сравните работу с информационным хранилищем и обработку загружен- ных данных. r J ру-жен 36. еречислите и опишите компоненты информационного хранилища. 37. Объясните, что означает изменение структуры запроса или отчета, и в чем его отличие от изменения данных в запросе или отчете. 38. Приведите пример (отличный от данного в книге), когда пользователю не- обходимо сгруппировать данные. 39. Приведите пример (отличный от данного в книге), когда пользователю требуется параметрическое разбиение данных. 40. У кажите два источника несогласованности данных и приведите пример каждого из них, отличный от приведенного в книге. 41. Опишите проблемы, возникающие при использовании средств, имеющих различные парадигмы и лицензированных различными производителями. 42. Объясните, почему приходится самостоятельно разрабатывать программ- ное обеспечение для информационного хранилища. 43. Почему особый характер запросов к информационному хранилищу пред- ставляет трудности? 14. Что такое информационные лавки, и почему компании их разрабатывают? 45. Перечислите и кратко опишите три типа информационных лавок. 46. Объясните, почему данные являются важным активом организации. 47. Приведите несколько примеров использования данных, помимо поддерж- ки функционирования системы. 48. В чем работа администратора данных схожа с работой ревизора? 49. Кратко обоснуйте потребность предприятий в администрировании данных. 50. Перечислите и кратко опишите проблемы администрирования данных. 51. Опишите функцию маркетинга в администрировании данных. 52, Какую роль играет администрирование данных по отношению к стандар- там организации данных? 53. Определите термин распорядитель данных. 54. В чем разница между распорядителем данных н владельцем данных? 55. Опишите роль адм>н.исгрнрова.шя данных в выработке поднтннн по от- ношению к данным. 56 Объясните, что включает в себя создание форума для разрешения кон- фликтов. 57 Каким образом администрирование данных может помочь повысить отда- чу от инвестиций в данные орншнзацип?
736 Глава 15. Совместное использование данных предприятия Вопросы группы II 58. Рассмотрим компанию, у которой есть национальный менеджер по прода жам и 15 региональных продавцов. Еженедельно продавцы загружают данные о продажах с главного компьютера и на их основе обновляют свои прогнозы продаж на следующий месяц. После этого они соединяются по модему с базой данных сервера и сохраняют в ней свои прогнозы. Затем менеджер объединяет эти данные в прогноз масштаба всей компании. Какие проблемы, вопросы и сложности могут возникнуть в этой ситуа- ции (если иметь в виду координацию, согласованность, контроль доступа и компьютерные преступления)? 59. Рассмотрите данные, которыми обладает ваш колледж или университет. Как вам кажется, эффективно ли ваше образовательное учреждение ис- пользует свои информационные активы? Каким образом вы можете опре- делить, что информационные ресурсы используются не только для под- держки функционирования системы? Опишите, как, по вашему мнению, ваш колледж или университет мог бы использовать свои информацион- ные ресурсы в следующих областях: ♦ набор студентов; ♦ сбор средств; ♦ планирование программ; ♦ студенческие дела; ♦ дела выпускников; ♦ другие области.
л Часть VI Работа с объектно- ориентированными базами данных Steals. Часть VI книги состоит из одной главы, в которой рассматриваются объектно- ориентированное программирование и объектные СУБД. Она содержит краткое введение в объектно-ориентированное программирование и обсуждение объ- ектно-реляционной СУБД Oracle, объектного расширения SQL под названием SQL3 и стандарта объектного управления данными под названием ODMG-93. Эта часть дополняет материал по OLE DE, ADO, ADO.NET и JDBC, находя- щийся в главах 12-14. В тех главах были изложены практические вопросы ис- пользования объектных интерфейсов для обращения к базам данных, а здесь представлен концептуальный взгляд на цели и задачи объектно-ориентирован- ных баз данных.
Глава 16 Объектно-ориентированные базы данных В этой главе рассматриваются вопросы постоянного хранения объектов, реализо- ванных на таких языках программирования, как Java, C# и C++. Как вы знаете, в реляционных базах данных информация хранится в форме таблиц, строк и столб- цов. Как таковые, реляционные базы данных не слишком хорошо приспособлены для хранения объектов, поскольку объекты могут содержать сложные структуры данных, а также указатели на другие объекты. Кроме того, у объектов есть ис- полняемые функции, называемые методами, поэтому, чтобы объект можно было перевести в постоянную форму, необходимо предусмотреть какой-то способ хра- нения методов. Специализированные СУБД, носящие название объектно-ориентированных СУБД, или ООСУБД (Object-Oriented DBMS, OODBMS), были разработаны в начале 1990-х годов для обеспечения постоянного хранения объектов. Эти про- дукты не имели коммерческого успеха, так как требовали преобразования суще- ствующих данных в формат ООСУБД. Организации отказываются делать такое преобразование, поскольку оно является весьма дорогостоящим и выигрыш от него не покрывает понесенных затрат. Однако объектно-ориентированное программирование в настоящий момент переживает взлет, и потребность в постоянном хранении объектов никуда не исчезла, В связи с этим производители традиционных СУБД стали расширять возможности своих продуктов, чтобы наряду с обычным хранением реляцион- ных данных обеспечить постоянное хранение объектов. Такие продукты получи- ли название объектно-реляционных СУБД (object-relational DBMS), и они, веро- ятно, будут находить все более широкое применение в будущем. В частности, средства моделирования и хранения объектов разработаны компанией Oracle. Поскольку мы не предполагаем, что вы владеете объектно-ориентирован- ным программированием, эта глава начинается с обсуждения основных терми нов и идей ООП. После этого мы рассмотрим различные способы реализации постоянного хранения объектов и продемонстрируем, как постоянное хранение реализовано в Oracle. В конце мы затронем два важных объектных стандарта SQL3 и ODMG-93.
----------gg^2g_B-96beKTHO-opneHTnpoBaHHoe программирование 739 Введение в объектно-ориентированное программирование Объектно-ориентированное программирование, или ООП (object-oriented ргос- amming Р) представляет собой способ проектирования и написания программ ООП существенно отличается от традиционного программирования, поскольку оно влечет за собой новое видение программных структур. В ООП программа не представляется в виде последовательности инструкций, а рассматривается как набор структур данных, содержащих как элементы данных, так и программные инструкции. Разницу между традиционным программированием и ООП можно предста- вить и по-другому: традиционное программирование структурируется вокруг логики в первую очередь и данных - во вторую, а ООП - в первую очередь во- круг данных и во вторую — вокруг логики. Например, для разработки традици- онной программы создания заказа нужно сначала представить ее логику в виде блок-схемы алгоритма или псевдокода. Обрабатываемые данные документиру- ются при этом как часть логики. Разрабатывая объектно-ориентированную программу создания заказа, мы сначала должны выявить объекты, участвующие в этом процессе, — например, ЗАКАЗ, ПРОДАВЕЦ, ТОВАР и КЛИЕНТ. Затем следует спроектировать эти объекты в виде элементов данных и программ, открытых для доступа друг к другу. После этого нужно описать поведение объектов в виде блок-схемы алгоритма или псев- докода. Терминология ООП Объект ООП — это инкапсулированная структура (encapsulated structure), имеющая атрибуты (attributes) и методы (methods). Термин инкапсулированная структура означает, что объект является самодостаточным: программы, внешние по отношению к объекту, ничего не знают о его структуре, и такое знание нм не требуется. «Внешний вид» объекта называется его интерфейсом (interface). Ин- терфейс состоит из тех атрибутов и методов, которые являются видимыми для внешнего мира. Инкапсулированное внутреннее строение объекта называется его реализацией (implementation). Атрибуты1 объектов ООП организуются в онредс ленную струк гуру. Методы объектов ООП представляют собой последовательности инструкции, выполняемых объектом Например, у объекта може> быть метод, отооражающпи данный объект, метод, создающий данный объект, и метод, изменяющий данный объект. Рассмотрим метод, изменяющий объект КЛИЕНТ. Этот метод, входящш ' Вместо термина атрибуты пио.да вс пользуется термин сети тва.^ • стандарт ODMG 93, где термин атрибут используется и бо н е узком смысле как мы \ш ш Wm. Сендая. ь с терминам.! илт <. тип, < «о«< «««>.. атрибут. * <МЫ«урда»ы.йвторы и< пользуют >ти термины немного ио разному 3 икь мы 6ч тем упспреСиятт * тн термины » готп-нгн пит < осуждаемой темой
740 Глава 16. Объектно-ориентированные базы данньы в состав объекта, является пршраммой; программа содержи) иис»р кции, «гго- рые получают щиные от пользования или па других п< ючпиков Объекты взаимодействуют, вызывая методы друг дру!а. Метод Изменить объ- екта КЛИЕНТ, например, вызывает методы других объектов для получения дал ных, изменения собственного содержимого п запроса услуг. Вызываемые мето- ды, в свою очередь, могут вызывать другие методы, и так далее. Пос кольку все объекты являются инкапсулированными, пи одни объект не может знать струк- туру другого объекта и не нуждается в таком знании. Это упрощает структуру приложения и способствует эффективному взаимодействию отдельных объектов Многие объекты имеют общие методы. Чтобы уменьшить количество одина- кового кода, объекты создаются как подклассы более общих классов. Объект 01, являющийся подклассом другого объекта, 02, наследует (inherit) все атрибуты и методы 02. Например, приложение может иметь общий класс СОТРУДНИК имеющий два подкласса, ПРОДАВЕЦ и ИНЖЕНЕР. Методы, являющиеся общими для всех трех классов, например ПолучитьНомерТелефона, помещаются в класс СОТРУДНИК. Подклассы ПРОДАВЕЦ и ИНЖЕНЕР наследуют эти методы. Следователь- но, когда программа вызывает метод ПолучитьНомерТелефона класса ПРОДАВЕЦ пли ИНЖЕНЕР, в реальности вызывается метод ПолучитьНомерТелефона класса СОТРУДНИК. Если требования приложения таковы, что сведения о номерах теле- фонов инженеров должны получаться иным путем, чем о номерах телефонов прочих сотрудников, то класс ИНЖЕНЕР будет иметь собственную версию метода ПолучитьНомерТелефона. Эта собственная версия будет использоваться при вызо- ве программой метода ПолучитьНомерТелефона объекта ИНЖЕНЕР. Такая характе- ристика называется полиморфизмом (polymorphism). В ООП часто используются несколько терминов. Логическая структура объ- екта — его имя, атрибуты и методы — называется объектным классом (object class). Группа объектных классов называется библиотекой классов (class library). Экземпляры классов называются экземплярами объектов (object instances), или просто объектами (objects). Объекты создаются путем вызова конструкторов (constructors) — программ, получающих оперативную память для объекта и формирующих структуры, необхо- димые для создания экземпляра объекта. Деструкторы (destructors) объектов — эго программы, уничтожающие объекты и освобождающие занимаемую ими па- мять. Объекты могут быть временными (transient) или постоянными (persistent). Временный объект существует только в оперативной памяти компьютера во вре- мя выполнения программы. Когда программа завершается, объект прекращает свое существование. Постоянный объект — это объект, записанный на физиче- ский носитель, например диск. Постоянный объект существует вне пределов программы п может быть считан в оперативную память с физического носителя. Целью ООСУБД является обеспечение постоянного хранения объектов. У объ ектов имеются как данные, так и методы; следовательно, ООСУБД, в отличие oi традиционной СУБД, должна хранить и данные, и программы. Поскольку каж дый объект данного класса имеет один и тот же набор методов, методы сохраня- ются только один раз — как методы класса. В отличие от методов, значения эле- ментов данных являются уникальными для экземпляра объекта, полому данные каждого экземпляра объекта должны храниться отдельно. Эту мысль иллюстрирует
Пример ООП 741 рис. 16.1. Па самом деле немногие ООСУБД в настоящий момент обеспечивают постоянное хранение методов, но, вероятно, в будущем эта ситуация изменится. Объектный класс КЛИЕНТ Набор методов является единым для всех экземпляров одного класса. Данные каждого экземпляра объекта хранятся отдельно Рис. 16.1. Пример объекта КЛИЕНТ Пример ООП В табл. 16.1 изображен фрагмент объектно-ориентированного интерфейса, а в лис- тинге 16.1 — пример метода. Чтобы не углубляться в детали, не имеющие значения для настоящего изложения, код написан в обобщенной форме, соответствующей принципам объектно-ориентированного программирования, а не какому-либо реальному языку программирования. Эту форму следует рассматривать как нечто вроде псевдокода для объектной программы. Таблица 16.1. Объекты, их методы и атрибуты (пример) Атрибуты ________ Объект Методы СОТРУДНИК Создать Номер (R) Сохранить Уничтожить Имя (R) ПРОДАВЕЦ (подкласс класса СОТРУДНИК) Создать Сохранить Уничтожить Назначить (ЗАКАЗ, Индекс) ВсегоКомиссионных (R) ВсегоЗаказов (RW) КЛИЕНТ Создать Сохранить Уничтожить Назначить (ЗАКАЗ) Имя (R) Телефон (R) Индекс (R) ТекущийБаланс (RW) Найти
742 Глава 16. Объектно-ориентированные базы данных Таблица 16-1 (продолжение) Объект Методы Атрибуты ТОВАР Создать Сохранить Уничтожить Найти (Номер) Взять (ЗАКАЗ, Количество) Положить (ЗАКАЗ, Количество) Найти Номер(R) Название (R) Описание (R) Цена (R) ЗАКАЗ Создать Сохранить Уничтожить Распечатать Номер(R) Дата (R) Сумма(R) ИмяКлиента (R) ИмяПродавца (R) Листинг 16.1. Фрагмент объектно-ориентированной программы ЗАКАЗ!Создать method Dim Клиент as object. Продавец as object. Товар as object Dim СуммаЗаказа as Currency, ДатаЗаказа as Date, НомерЗаказа as Number Dim СтрокаЗаказа as Structure [ НомерТовара as Number. НазваниеТовара as Text(25). КоличествоТовара as Count. ОтложенноеКоличество as Count. Стоимость as Currency ] {Получаем имя клиента из некоторого источника} Set Клиент = КЛИЕНТ'Найти(ИмяКлиента) If Клиент = Nothing then Set Клиент = КЛИЕНТ!Создать(ИмяКлиента) End If Клиент '.Назначить(Me) Set Продавец = ПРОДАВЕЦ!Назначить(Ме. Клиент.Индекс) {Получаем из некоторого источника код и количество единиц первого товара в заказе} Me.СуммаЗаказа = О While Not НомерТовара.EOF Me.СтрокаЗаказа!Создать Me.СтрокаЗаказа.НомерТовара = НомерТовара Set Товар = ТОВАР'Найти(НомерТовара) {обрабатываем ошибку, если такого товара не существует} Me.СтрокаЗаказа.НазваниеТовара = Товар.Название
Пример ООП 743 Me.СтрокаЗаказа.Количество = Т0ВАР!Взять (Количество) If Me.СтрокаЗаказа.Количество <> Количество Then Me.СтрокаЗаказа.ОтложенноеКоличество = Количество Me.СтрокаЗаказа.Количество End If Me.СтрокаЗаказа.Стоимость = СтрокаЗаказа.Количество * ТОВАР Цена Ме.СуммаЗаказа = Ме.СуммаЗаказа + Me.СтрокаЗаказа.Стоимость' Товар!Сохранить Me.СтрокаЗаказа!Сохранить {Получаем из некоторого источника код и количество единиц следующего товара. Предполагаем, что источник устанавливает переменную EOF в значение true, когда все строки заказа обработаны.} While End Продавец.СуммаПродаж = Продавец. СуммаПродаж + Ме.СуммаЗаказа Клиент.ТекущийБаланс = Клиент.ТекущийБаланс + Ме.СуммаЗаказа Продавец'Сохранить Клиент!Сохранить ME!Сохранить End ЗАКАЗ!Сохранить В табл. 16.1 показан фрагмент интерфейса нескольких объектов, используе- мых в приложении обработки заказов. Каждый объект имеет набор методов и ат- рибутов, открываемых им для доступа извне. Каждый объект имеет конструктор (метод Создать) и деструктор (метод Уничтожить). У некоторых методов есть параметры: например, метод Присвоить объекта ПРОДАВЕЦ принимает в качестве параметров указатель на объект ЗАКАЗ и значение атрибута Индекс. Атрибуты, по- меченные буквой (R), могут только считываться, но не изменяться; атрибуты, помеченные буквами (RW), могут и считываться, и записываться. Обозначения в листинге 16.1 требуют пояснений. Во-первых, в фигурные скобки заключаются комментарии. Они используются здесь для описания функ- ций программного кода, который должен присутствовать в реальной программе, ио опущен в данном примере для краткости или в рилу ненужности для данного рассмотрения. Оператор Dim используется для объявления переменных и их ти- пов, как в языке Basic. Тип данных СтрокаЗаказа объявлен как структура, состоя- щая из элементов данных, перечисленных в квадратных скобках. Восклицатель- ный знак служит разделителем между именем объекта и именем одного из его методов. 'Гак, КЛИЕНТ!Найти обозначает метод Найти объекта КЛИЕНТ. Точка ис- пользуется в качестве разделителя между именем объекта и именем одного из его атрибутов 1 ак, Клиент.Индекс обозначает атрибут Индекс объекта, на который указывает переменная Клиент В листинге 161 исполыукггся два особых ключевых слова. Ключевое слово Nothing является указателем па пустой объект. Выражение И Клиент « Nothing о6г»1и st «сравнить значение объектной переменно!) Клиенте указателем на Пустой пбмчст». Ключевое слово Me ио укататель На объект, код которого ВЫ-
744 Глава 16. Объектно-ориентированный базы Данных полняегся в данный момент. Код, изображенный в лис инне 16 1, будет вы» пяться экземпляром объекта ЗАКАЗ, поскольку эго код метода данною объекта Соответственно, Me здесь указывает па конкретный экземпляр объекта ЗАКАЗ выполняющий этот код. Метод ЗАКАЗ’Создать начинает свою работу с получения имени клиента, де- лающего заказ; как конкретно происходит получение этих данных (например, из поля ввода в форме), для пас сейчас не важно. Затем вызывается метод Найти объекта КЛИЕНТ, который ищет в базе данных клиента с заданным именем и воз- вращает указатель на найденный объект. Подробности выполнения этого поиска скрыты внутри метода КЛИЕНТ'Найти, п мы не знаем, как делается выборка, что происходит при обнаружении более одного клиента с заданным именем и т. д В результате выполнения этой операции переменной Клиент присваивается значение указателя на экземпляр объекта КЛИЕНТ или специальное значение Nothing, то есть указатель на пустой объект. Если Клиент указывает на пустой объект, то с помощью метода КЛИЕНИСоздать создается новый объект КЛИЕНТ, и указатель на этот объект записывается в переменную Клиент. Как можно видеть, логика работы метода предполагает, что метод КЛИЕНТ!Создать действительно возвращает указатель на экземпляр объекта КЛИЕНТ. В реальности в этом месте следовало бы снова выполнить проверку на пустое значение переменной Клиент, но для краткости в остальной части программы такая проверка опускается. У объекта КЛИЕНТ имеется открытый для внешнего доступа метод Назначить, с помощью которого заказ назначается определенному клиенту'. Из-за инкапсу- ляции мы не знаем, что делает метод Назначить, но мы вызываем его и передаем ему значение Me — указатель на текущий объект. Фактически, метод Назначить здесь является примером того, что называется обратным вызовом (callback) Объект ЗАКАЗ в методе Создать передает указатель на себя объекту КЛИЕНТ, в ре- зультате чего клиент может отслеживать свои заказы. Это делается, в частности, для того, чтобы объект КЛИЕНТ перед своим уничтожением мог вызвать все свя- занные с ним объекты ЗАКАЗ. Таким образом, объекты ЗАКАЗ смогут уничтожить указатель на объект КЛИЕНТ, когда этот указатель станет недействительным Обратные вызовы имеют также много других применений. Далее метод ЗАКАЗ'Создать записывает в переменную Продавец указатель на объект ПРОДАВЕЦ. Этому методу передается почтовый индекс клиента (атрибут Индекс), и это подсказывает нам, что индекс имеет какое-то отношение к распре- делению клиентов между продавцами. Опять-таки, из-за инкапсуляции мы не знаем, как это делается. Так как методология приложения скрыта, способ рас- пределения клиентов между продавцами в объекте ПРОДАВЕЦ может оыть изме- нен, но это никак не повлияет на логику этой или какой-либо другой программы Таким образом, если метод ПРОДАВЕЦЖазначить будет назначать клиентов про- давцам в соответствии с фазами Луны, ни одну строку кода в листинге 16.1 ме- нять не потребуется! Следующий раздел кода заполняет строки заказа. Обратите внимание, что локальные элементы данных адресуются с помощью ключевого слова Me. ( а самом деле, в большинстве объектно-ориентированных языков программирова ния Me подразумевается и не является обязательным; здесь мы помещаем его для
Постоянное хранение объектов 745 ясности.) В начале каждого повторения цикла While < каза!Создать выделяется память и следую,,,ей строки ХТ° Р<”3а' Метод TOBAR! Взять забирает товары со склада, «^^вмавие- логика м <юты метода предполагает, что если „„ело едвввп товара „а складе « е ,ем заказанное количестпо ед,„,„„ товара, то недостающее ,юлите™ д”““б, “ о. »рмле,,о как отложенный заказ. Также обратите „нвмавпе. что ,з.ме№ ооъект TOBAR сохраняется после обработки каждой строк,, заказа Кроме того в отличие от объектов КЛИЕНТ и ПРОДАВЕЦ, объектам ТОВАР „е передается ,ка«- тель для обратного вызова. Это означает, что объекты ТОВАР не знают с какими объектами ЗАКАЗ они связаны. Понятно, что в данном приложении для объектов TjBAP несущественно, в каких заказах они фигурируют. Цикл продолжается, пока все требуемые товары не будут перечислены в зака- зе. После этого обновляются итоговые суммы в объектах ПРОДАВЕЦ и КЛИЕНТ и оба эти объекта сохраняются вместе с Me. Фрагмент кода в листинге 16.1 представляет собой типичный пример объект- но-ориентированной программы и выявляет несколько важных вопросов, имею щих значение для объектно-ориентированных систем баз данных. Один из этих вопросов таков: как обеспечивается постоянное хранение объектов? Постоянное хранение объектов На рис. 16.2 изображены структуры данных, существующие после создания зака- за. Объект ЗАКАЗ содержит основные сведения о заказе — ЗАКАЗ.Номер, ЗАКАЗ.Дата, ЗАКАЗ.Сумма, а также повторяющуюся группу строк заказа, имеющих атрибуты НомерТовара, НазваниеТовара, Количество, ОтложенноеКоличествои Стоимость. Кроме того, в основные сведения о заказе входят указатели па объекты КЛИЕНТ н ПРОДАВЕЦ, с которыми связан этот заказ, а также указатели на каждый из объектов ТОВАР, фигурирующих в заказе. Эти указатели являются частью данных ооъекта ЗАКАЗ. Чтобы сделать этот объект постоянным, необходимо сохранить все эти дан- ные. Кроме того, нужно сохранить каждый из объектов КЛИЕНТ, ПРОДАВЕЦ и ТОВАР, хотя их структура и неизвестна. В объектах КЛИЕНТ и ПРОДАВЕЦ сохраняется также указатель на объект ЗАКАЗ в результате обратных вызовов, сделанных в мето- дах ! Назначить. _ « , Эти указатели вызывают особенные трудности. В оольш1|ИС1?е„ ъе'^ *° оптированных языков программирования указатели являют со он ту .- " форму адреса в памяти. Такие адреса действительны только в период выпо иия программы; при повторном ее запуске адреса объектов будут уже • Следовательно, сохраняя объект, необходимо преобразовать У— в памяти в постоянные уникальные идентификаторы, кеш >' н1. тельпы втеч тис все.о времени сущее.вова.н.я объекта. ..став м ; одигся си. в .. .мят,, или не.. Процесс „реобразова.н.я ..о с томит ьх кентнфпка Торов в адреса в памяти называется настройкой по адриам (scx./zl ng)
746 Глава 16 Объектно ориентир олиныв базы даннык Наконец, вспомните, что объект определяется как совокупность данных и ме- тодов. Следовательно, чтобы сделать объект постоянным, необходимо сохранить и его методы, и данные его экземпляров. Но в отличие от элементов данных, ме- тоды каждого объекта данного класса остаются одними и теми же, поэтому их требуется сохранить лишь однажды — для всех экземпляров данного объектного класса. Итак, вот действия, которые необходимо выполнить для обеспечения по- стоянного хранения объектов: ♦ сохранить данные экземпляра объекта; ♦ преобразовать указатели на объекты, находящиеся в оперативной памяти, в постоянные уникальные идентификаторы (настройка по адресам); ♦ сохранить методы объектного класса. Для постоянного хранения объектов может использоваться традиционная фай левая система, реляционная СУБД или объектно-ориентированная СУБД Р с смотрим каждый из этих вариантов. Постоянное хранение объектов в традиционной файловой системе Объекты можно хранить в традиционной файловой системе, но это возлагает на плечи программиста тяжелое бремя Рассмотрим данные в табл. 16.2. Разработки*
—----------—--------- Постоянное хранение объектов 747 ку может принта в голову мысль создать один файл для методов всех объектов и второй фаты для данных всех объектов. Для этою необходимо (£дет «ZS Итъ оообщеиную структуру датших, когорм noMT записьнй Ле™ „ые в файлы и считывать их отгула „х при необходимости В табл 16XX, пример файла. в котором храня™ элементы лаииых. (Для хранения мстожХ ооходнмо создать еще один подобный файл.) д нс Таблица 16.2. Использование файла фиксированной длины для хранения данных объекта НомерЗаписи КодЗаписи Содержимое “ Ссылка 1 ЗАКАЗ Данные заказа 100 4 2 ПРОДАВЕЦ Данные продавца Джонса null 3 КЛИЕНТ Данные клиента 10000 null 4 СТРОКАЗАКАЗА Данные строки заказа 100 5 5 СТРОКА_ЗАКАЗА Дарные строки заказа 100 null Для работы с таким файлом программист должен будет написать метод, кото- рый будет записывать и считывать содержащиеся в нем данные объектов, нахо- дить объекты по запросу, организовывать неиспользуемое файловое пространст- во и т. д. Кроме того, придется разработать и реализовать алгоритмы настройки по адресам и обратной ей операции. Но существует еще проблема начальной за- грузки. Ведь все методы хранятся в файлах, включая методы, выполняющие со- хранение и чтение методов. Как должен загружаться метод, который считывает первый метод? Все эти трудности были преодолены еще много лет назад в файловых подсис- темах операционных систем. Но в этом-то все и дело: такое программирование медленно, утомительно, рискованно и трудно, и оно уже было выполнено в тради- ционных системах обработки файлов. Зачем проделывать все то же самое еще раз? Из-за этих проблем хранение объектов в традиционных файловых системах имеет смысл лишь тогда, когда приложение имеет несколько простых объектов, структура которых не меняется. Немногие деловые приложения удовлетворяют этому критерию. Постоянное хранение объектов с использованием реляционной СУБД Другой подход к постоянному хранению объектов заключается в использовании коммерческих реляционных СУБД При .л ом подходе бремя, ложащееся напле- чи „ро.раммнста, „«ааиааст», меньше, чем при не,,ол,«„«и,uu гриднижнои об- работки файлов. поскольку „гаонпые .шач„ управлении фанла,™ - записей, индексирование, управление файловым нростраш ibom ’ _ себя Ь Программисту остается определить реляционные структуры д. теля СУЬД Программ у........ шпающийрольпосредпнкамеждупро- предстапления обм-кгов и напшан. код, nip.iiohi и 1 граммой и СУБД при чснип записи объекта н пас.ропкс подцхеам.
Ниже Приведен список THo.trtH, необходимым дли крмнгиЯЯ ШОД. CTP0KAJAKA3A. КЛИЕНТ. ПРОДАВЕЦ и ТОВАР Мы уже ш цтдм эту ’ Ца «туру ' нее. Едино венный новый элемент в ней — это »аблица> где зфэиитсм метп*>« объектов; она имеет текстовое ноле большой длЩ!Ы, в котором и хршшпж мл( методов. сотрудник (Номер. Имя....) ПРОДАВЕЦ (Номер. ВсегоКомиссионных, СуммаПродаж,.,) КЛИЕНТ (Имя. Телефон. Индекс, ТекущийБаланс,.,.) ТОВАР (Номер. Название, Описание, Цена,...) ЗАКАЗ (Номер. Дата. Сумма, ПРОДАВЕЦ.Номер. КЛИЕНТ.Имя, . ) СТРОКА_ЗАКАЗА (ЗАШ,Номер. НазваниеТовара. КоличествоТоеара, ОтложенноеКоличество, Стоимость,...) МЕТОДЫ (ИмяОбтукта. ИмаМетвда. КодМетода) В реляционных базах данных связи представляются через внешние ключи. Это означает, что программист должен реализовать некоторый способ постоян- ного хранения связей с помощью внешних ключей. Наиболее распространенный способ — обеспечить в конструкторе объекта создание уникального идентифика- тора. Этот идентификатор может храниться в базовой таблице объекта и показы- ваться объектом как свонство только для чтения. Объ кты, которым требуется ссылка на этот объект, могут хранить у себя значение этого идентификатора. Такая стратегия создает одну трудность: когда объект уничтожается, он должен уведомить об этом все объекты, имеющие ссылку на него, чтобы они могли уда- лить эту ссылку и предпринять другие необходимые действия. Это одна из при- чин, по которой используются обратные вызовы, как в листинге 16.1. Объектно-ориентированное мышление хоронит саму концепцию связи Так, например, когда объект ЗАКАЗ устанавливает связь с объектом ПРОДАВЕЦ, он ин- тересуется только своей стороной этой связи. Eqiii объект ЗАКАЗ захочет устано- вить связь с несколькими объектами ПРОДАВЕЦ, он сможет это сделать. Объект ЗАКАЗ не знает, со сколькими объектами ЗАКАЗ имеет связь объект ПРОДАВЕЦ. Это знание скрыто в объекте ПРОДАВЕЦ и не является частью логики объекта ЗАКАЗ. Эта характеристика может быть как преимуществом, так и недостатком, в за- висимости от того, как на это смотреть. Предположим, что один заказ могут об- рабатывать несколько продавцов, и у каждого продавца может быть много зака- зов. Выражаясь языком баз данных, объекты ЗАКАЗ и ПРОДАВЕЦ имеют связь М X В этом случае в реляционной базе данных создается таблица пересечения, содер- жащая идентификаторы объектов ЗАКАЗ и ПРОДАВЕЦ, связанных между собой. В объектном мире продавец знает, что у него есть много заказов, а заказ что его обрабатывают много продавцов, однако они не знают этого друг о друге- Следовательно, структуры данных, в которых хранятся связи, будут разделе- ны. В объекте ЗАКАЗ будет место для хранения множества ссылок на ооъекты ПРОДАВЕЦ, а в объекте ПРОДАВЕЦ будет место для храпения множества ссылок на объект ЗАКАЗ. Эги наборы ссылок будут изолированы друг от друга. Имеет ли это значение? Нет, пока нет ошибок в обработке объектов, но тако риск существует, поскольку ссылки на объекты хотя и разделены, но ие незави- симы. Если заказ 1000 связан с продавцом А, то, по определению, продавец «
Постоянное хранение объектов 749 связан i заказом 1000. В мире реляционных CVR7T ется строкой в таблице пересечения vmpHw> ИОСКОЛЬВУ СВЯЗь представля- чески приводит к удалению соответс-пш! ••СТроки с o/llIoil стороны автомата- в mpe Ы скто» CIT' С ДРУГОЙ ст°роиы- второ,™ „ „е будет у.Z й ‘ «иом Л, „о продавец Л „одЛ „е “ZZwoOoZX что это ошибка и что такого не следует допускать, „о така» ситуация ткнул ест определение свлаей происходит исключительно c'oZZ™. тированной точки зрения. и орисн , При использовании реляционной СУБД для постоянного хранения объектов ооъем раооты для программиста оказывается меньше, чем при использовании традиционных файловых структур. Однако остается необходимость преобразо- вывать объекты в реляционные конструкции, писать запросы на SQL (или дру- гом языке), считывать и записывать объекты с помощью СУБД и производить настройку по адресам. Для выполнения этих задач были разработаны объектно- ориентированные СУБД. Постоянное хранение объектов с использованием ООСУБД Третий способ постоянного хранения объектов — использование объектно-ори- ентированных СУБД. Такие продукты специально приспособлены для постоя! - него хранения объектов и, следовательно, сводят к минимуму труд прикладных программистов. ООСУБД изначально интегрирована с объектно-ориентированным языком программирования. Таким образом, в код приложения не нужно встраивать ни- каких дополнительных структур типа SQL. В примере на рис. 16.2, возможно, методы Сохранить фактически предоставляются ООСУБД. Следовательно, вызы- вая метод Сохранить, программист обращается к ООСУБД. Кроме того, в состав ООСУБД входит компилятор (или ООСУБД входят в состав компилятора — все зависит от точки зрения), который обрабатывает ис- ходный текст и автоматически создает в объектной оазе данных шруктуры для хранения объектов. Соответственно, в отличие от реляционных СУБД пли сис- тем обработки файлов, программист не должен преобразовывать объекты в реля- ционные или файловые структуры — ООСУБД делает это авюматп jecKii. Наконец, поскольку ООСУБД специально предназначены для хранения объектов, в них обтспсчннаегся га или иная форма пастрс ЗТП;Л1ОО- сам. Таким образом, для кода, подобного показанному в пн ищи ’ ’ всегп Гномы нс будс! Объект- получает ссылку па другой объект, па ждяется действию/....ой. Бело ссылк i принимает другие формы, нротралма ‘X. X шг,п<е ООСУБД. I», шт» «падк»,- йеной памятью В некоторых ООСУБД программе кд> Ю00 имеет Мисту) не нужно знать, находи пя объект в ....тли • - ‘ \ ’ свойства снятье продавцом Л, заказ 1000 может смело использовать доступные
щхщавца А, не проверяя, загружены ли ни данные в намять, не выполняя чптпщ и не посылая SQL запрос. Если объект, описывающий продавца Л, находится в памяти, ООСУБД создает ссылку, а <ч’ли нет, ООСУБД загружает объекте па- мять и затем создает на пего ссылку. В табл. 16.3 сравнивается количество работы* которое приходится проделать программисту при каждом из грех способов постоянного хранения объектов Очевидно, что ООСУБД предоставляет программисту ООП существенные пре- имущества. Почему же тогда эти продукты не исполыуюгся повсюду? Этому во- просу посвящен следующий раздел. Таблица 16.3. Сравнение методов постоянного хранения объектов ООСУБД Реляционные СУБД Традиционные системы обработки файлов Вызов специального метода ООСУБД Преобразование адресов объектов в памяти в постоянные идентификаторы и наоборот (настройка по адресам) Создание реляционных структур данных Написание процедуры на SQL (или на другом языке) Встраивание SQL а программу Преобразование адресов объектов в памяти в постоянные идентификаторы и наоборот (настройка по адресам) Создание реляционных структур данных Написание процедуры сохранения объекта в постоянной форме Вызов процедуры сохранения объекта в постоянной форме Преобразование объектов в файловую структуру и наоборот Нахождение объектов по требованию Управление дисковым пространством Другие задачи по управлению файлами Постоянное хранение объектов в Oracle Компания Oracle расширила возможности своих СУБД, включив в них поддерж- ку объектного моделирования и постоянного хранения объектов. Как уже гово- рилось, такие базы данных иногда называются объектно-реляционными базами данных. По ходу чтения подумайте над тем, каким образом Oracle удалось соединить объектно-ориентированное мышление с реляционной моделью. Хотя в некото- рых отношениях этот гибрид довольно неуклюж, он позволяет организациям по- степенно мигрировать от реляционного способа хранения данных к объектному. Как уже упоминалось, чистые объектно-ориентированные СУБД, требовавшие резкой смены парадигм, были отвергнуты. Во многих отношениях Oracle выпол- нила блестящую работу, обеспечив поддержку текущей клиентской базы и в то же время распространив возможности продукта в объектном мире. Настоящее изложение основывается на 9-й версии Oracle. Эти возможности и функции, несомненно, будут совершенствоваться и расширяться, так что сюит просмотреть документацию к более новым версиям Oracle, чтобы узнать о по следних достижениях Oracle в области хранения объектов.
Постоянное хранение объектов в Oracle 751 Типы объектов и коллекции далее использоваться в отношении птпбт ш из четырех возможных способов Ппогтрйшы» - сношении любым object), когорт ,цет о коллекции объектов одного из трех типов: Z1 (eamble leHgTh array), алажеииая таблица (nested table) или абытт-страка (row object). Рассмотрим каждый из этих типов. v Объекты-столбцы Следующий оператор определяет объектный тип obj_Apartment, описывающий квартиру: CREATE TYPE obj_Apartment AS OBJECT ( BuildingName VARCHAR2(25). ApartmentNumber CHAR(4). NumberBedrooms NUMBER) / Этот тип имеет три столбца (название здания, номер квартиры и число спаль- ных комнат), использующих встроенные типы данных Oracle. (Вспомните, что косая черта заставляет SQL Plus выполнить только что введенный оператор. С этого момента мы будем опускать косую черту в конце всех примеров.) Следующий оператор CREATE определяет объект-столбец Location (место жи- тельства), принадлежащий к типу obj_Apartment: CREATE TABLE PERSON ( Name VARCHAR (50). Location obj_Apartment) Данные из этой таблицы, содержащей данные об имени и месте проживания людей, можно запрашивать и обрабатывать так же, как и данные из всякого дру того отношения. Однако синтаксис операторов INSERT и UPDATE несколько। разли чается Следующий оператор выполняет вставку строки в та лиц} INSERT INTO PERSON (Name. Location) VALUES ('Selma Whitbread . obj_ Apartment!'Eastlake'. '206'. 2)); Обратите внимание на то, как используется имя типа данных в предложении VALUES Следующий оператор выполняет обновление строки. UPDATE SET WHERE И снова обратите внимание на использование пою ан результат запроса из этой таблицы. PERSON , ,Z1„. Location-obj_Apartment('Eastlake . 412 . J) Name-'Seima Whitbread'. имени типа данных. Па рис. 16.3
SQL> SELECT • FROM ft «SUN; NAME LOCAIIUN(BUILDINGNAME, APARTHFHTNUMBEH, NUHBERBEMOO*.) Lynda Janes OBJ_APARTHENT("Eastlake1, '206 . 2) Selna Whitbread OBJ APARTMENT('Eastlake', '444 3) a SQL> SELECT * FROM BUILDING1; BUILDINGID NAME UNITS(APARTMENTNUMBER, NUMBERBEDROOMS) ___________________________________________________________________________________ 1 Eastlake APARTHENT_LIST1(APT_UNIT("100 ", 1), APT_UNIT(1200 •» 2), APT_UNIT('300 1)) 2 Westview APARTMENT_LIST1(APT_UNIT('101 1), APT_UNIT('201 2), APT_UNIT('301 ', 1)) 6 SQL> SELECT * FROM BUILDING2; BUILDINGID NAME UNITS(APARTMENTNUMBER, HUHBERBEDROOMS) 1 Eastlake APARTMENT_LIST2(APT_UNIT( ' 100 ', 1), APT_UNIT('2OO 2), APT_UNIT(' 300 1)) 2 Westview APARTMENT_LIST2( APT_UNIT( ‘ 101 1), APT_UNIT(' 201 2), APT_UNIT('301 ', 1)) 6 SQL> SELECT » FROM APARTMENTS; BUILDINGNAME APAR NUMBERBEDROONS Westview 333 2 Westview 235 2 г Рис. 16.3. Работа оператора SELECT с объектными структурами: а — запрос объекта- столбца; б — запрос массива переменной длины; в — запрос вложенной таблицы; г — запрос объекта-строки Массивы переменной длины Массивы переменной длины — это один из способов создания коллекций объ- ектных типов. Чтобы понять, как используются такие массивы, предположим, что нам нужно создать таблицу с данными о многоквартирном доме. В ней должно быть значение суррогатного ключа, название здания и перечень квартир в здании.
Л2£12^£21Ранение объектов в Oracle 753 Создадим объект, ппедстэвпяггыи.тк меннои мины, как показано в следую^ 5™’^”"""”" его " «фе- CREATE TYPE AptJJnit AS OBJECT ( ApartmentNumber char(5) Number-Bedrooms Int): CREATE TYPE APARTMENTJ.IST1 AS VARRAY(50) OF APT Unit Здесь тип APARTMENT.LIST1 может иметь д„ 50 э„,1тв т„Па Следующий оператор создаст таблицу с информацией о ломах и,»,,,™ щую этот массив переменной длины: пспользхю CREATE TABLE BUILDING1 ( BuildingID NUMBER. Name VARCHAR2(50) Units APARTMENT_LIST1); Теперь, чтооы вставить данные в таблицу, мы должны использовать имена массива и его элементов, как показано здесь: INSERT INTO BUILDING1 (BuildingID. Name. Units) VALUES (1. Eastlake'. APARTMENTJ.IST1 (Apt_Unit(’100'. 1). (Apt_Umt('200'. 2). (AptJJn1t('300'. 1))): Считывать значения всех столбцов можно с помощью обычного оператора SELECT, но только если в предложении WHERE нет ссылок на элементы Apt_Unit. На рис. 16.3, б показаны результаты оператора SELECT * для всех строк. Если же вы хотите получить значения Apt_Unit или использовать его значе- ния в предложении WHERE, вы должны будете вывернуть этот запрос наизнанку, как показано ниже: SELECT FROM ApartmentNumber TABLE ( SELECT UNITS FROM BUILDING1 WHERE Name='Eastlake') ApartmentNumber > 100: WHERE Этот запрос делает выборку атрибута ApartmentNumber из объекта UNITS, являю- щегося массивом переменной длины. I аблица BUILDING о >ра >а1ывастся, у 1Ьег женном запросе. Результатом будет габлнца, содержащая столбец ApartmentNumber и две строки 200 и 300. пспемеп- В ОпЛс нельзя ..л« Л..М» «й длины с „оиощыо UPOA' иа(чЕсли ХОТ1|ГС „с,1гаь- процедуру ИД 1 L/SQ - ПЧ« ( 1U>1 пуж1](1 ГО„ВТ1. эопать для этой пели онсраюры ш lwi г . иую таблицу, как <>пи< ывается в tjie/iyioiiuM разде
754 Глава 16, Ооьектно ориенгироианиыс б.> >ы дани** Вложенные таблицы Вложенные таблицы определяются почти так же, как и массивы п> ремеишН! ны. Разница межд) ними заключается я том, что данные мас< ива пе^м-м-ниой длины хранятся в таблице, в которой оин определены, я данные вложенных таб- лиц — в отдельной таблице Создать таблицу BUILDING с помощью вложенных таблиц можно посредством следующего оператора: CREATE ПРЕ APARTMENT_LIST2 AS TABLE OF AptJJnit; / CREATE TABLE BUILDING2 ( BulldingID NUMBER Name VARCHAR2(50). Units APARTMENT_LIST2) NESTED TABLE Units STORE AS UNITS_TABLE; Единственное отличие от синтаксиса определения массивов переменной дли- ны состоит в том, что вложенной таблице должно быть дано имя. Здесь таблица названа UNITS_TABLE. На рис. 16.3, в показан результат запроса всех строк таблицы BUILDING? обра- тите внимание, что он идентичен результату, который был получен в примере с массивом переменной длины. Операторы вставки и запроса, используемые со вложенными таблицами, идентичны тем, которые используются для массивов переменной длины: INSERT INTO BUILDING2 (BuildingID. Name. Units) VALUES (1. ’Eastlake’. APARTMENT_LIST2 (Apt_Unit(’100’. 1). (Apt_Unit('2OO’. 2). (Apt_Unit(’3OO’. 1))): и SELECT FROM WHERE ApartmentNumber TABLE ( SELECT UNITS FROM BUILDING2 WHERE Name=’Eastlake’) ApartmentNumber > 100; Однако, как было обещано, вы можете обновлять и удалять элементы вло- женной таблицы: UPDATE TABLE ( SELECT Units FROM BUILDING2 WHERE Name=’Eastlake’) SET NumberBedrooms=5 WHERE ApartmentNumber>100;
Постоянное хранение объектов в Oracle 755 и delete FROM TABLE ( SELECT Units FROM BUILDING2 WHERE Name='Eastlake') WHERE ApartmentNumber=100: Как можно видеть, массивы переменной длины и вложенные таблицы весьма похожи между собой, но у них есть и различия. Во-первых, как уже говорилось, операторы UPDATE и DELETE работают только со вложенными таблицами. Кроме того, массивы переменной длины ограничены максимальным размером, а вло- женные таблицы — нет. К тому же, Oracle хранит массивы переменной длины вместе с таблицей, а данные вложенных таблиц — отдельно. Наконец, в массиве переменной длины поддерживается определенный порядок строк, а во вложен- ной таблице порядок строк может меняться по мере того, как в нее добавляются новые строки. Объекты-строки Четвертый способ использования объектных типов в таблицах — это объекты- строки. Таблица объектов-строк — это просто таблица, которая содержит исклю- чительно объекты. Для нашего примера определим объект-квартиру obj_Apartment, как прежде: CREATE TYPE obj_Apartment AS OBJECT ( Bui 1dingName VARCHAR2(25). ApartmentNumber char(4). NumberBedrooms NUMBER): Следующий оператор создаст таблицу с объектами obj_Apartment. INSERT INTO APARTMENTS (BuildingName. ApartmentNumber. NumberBedrooms) VALUES ('Westview'. '333'. 2) А этот оператор произведет обновление строки в таблице APARTMENTS UPDATE apartments SET NumberBedrooms • 5 WHERE ApartmentNumber - '100'. Наконец, удаление строки выполнит оператор DELETE FROM APARTMENTS WHERf ApartmentNumber-'100'; Объекты Oracle Выпи было показано, как определяются объектные тины и эовать « качестве элементов таблиц. При таких гктная - груктура накладывался на отношения, а результирующие
756 Глава 16 Объектно-ориентированные базы данных могут обрабатываться с помощью различных нарнаций SQL Но Owfe? н[-,г->г. ег и другой вариант наложение реляционных структур на ибы-кты^Дад*ыбш- ботки этих структур SQL непригоден. Эти гчруктуры представляют <обоц ты, хранящиеся в базе данных, но манипуляции с ними должны ММнолияться объсктцр-орпентнрованными программами Определение объектного типа В листинге 16.2 показаны определения объектных типов Oracle ия системы об- работки заказов, изображенной па рис 16.2. Как показано ранее, структур объек- тов и пользовательские типы данных' определяются с помощью оператора CREATE TYPE. Первые два типа, определенные на рисунке, — это пользовательским тип obj_ADDRESS (адрес) н массив переменной длины под названием obj_PHONE LIST (список телефонов), имеющий максимальную длину 5. Эти два типа могут ис- пользоваться в операторах CREATE TYPE AS OBJECT точно так же, как используются типы данных при создании таблиц. Листинг 16.2. Определение объектов в Oracle CREATE TYPE obj_ADDRESS AS OBJECT ( Street VARCHAR2(50). City VARCHAR2(50). State VARCHAR2(2). Zip VARCHAR2(10). Country VARCHAR2(15) CREATE TYPE obj_PHONE_LIST AS VARRAYI5) OF VARCHAR2U2) I CREATE TYPE obj_SALESPERSON AS OBJECT ( SalespersonlD NUMBER. Name VARCHAR2(50). Address obj_ADDRESS. PhoneNums obj PHONE LIST CREATE TYPE obj_CUSTOMER AS OBJECT ( SalespersonlD NUMBER. Name VARCHAR2(50). Address obj ADDRESS. PhoneNums obj_PHONE_LIST ) Тннкогпа / CERATE TYPE obj.ITEM / CREATE TYPE obj_LINEITEM AS OBJECT ( ItemNumber NUMBER. ItemRef REF objJTEM. Quantity NUMBER.
Постоянное хранение объектов в Oracle 757 QuantityBackordered NUMBER. ExtendedPrice NUMBER ) I т, , CREATE TYPE list_LINEITEM AS TABLE OF obj LINEITEM CREATE TYPE obj_ITEM AS OBJECT ( ItemNumber NUMBER. ItemName VARCHAR2(25). Price NUMBER ) , m X я / >.>< ни 4 f « CREATE TYPE obj_ORDER AS OBJECT ( OrderNumber NUMBER. OrderDate VARCHAR2(25). Lineitems list_LINEITEM, ShipToAddress obj_ADDRESS. Customer REF obj_CUSTOMER. Salesperson REF obj_SALESPERSON ) / ~ ) гл и и MEMBER FUNCTION total Items RETURN NUMBER ) 1 ' J и । ' . { > f* П ”1 . i <M щ ч .и Далее в листинге 16.2 определены типы obj_SALESPERSON (продавец) и obj_ CUSTOMER (клиент). В обоих задействованы пользовательские типы obj_ADDRESS и obj_PHONE_LIST. Такое использование означает, что каждый из объектов obj_ SALESPERSON и obj_CUSTOMER имеет атрибуты Street (улица), City (город), State (штат), Zip (Индекс) и Country (Страна). Каждый из них имеет также массив пе- ременной длины, содержащий номера телефонов. Следующий оператор CREATE TYPE является пустым; он нужен для того, чтобы сообщить синтаксическому анализатору типов Oracle, что далее последует опре- деление объекта obj_ITEM (товар). Этот оператор позволяет использовать в опре- делении типа obj_LINEITEM (строка заказа) символ obj_ITEM, хотя последний еще не был определен. Определение типа obj_LINEITEM включает атрибуты ItemNumber (номер товара), Quantity (количество), QuantityBackordered (отложенное количество) и ExtendedPrice (стоимость), как показано на рис. 16.2. Однако, помимо этого, оно включает ссылочный атрибут. Этот атрибут, представляющий собой ссылку па товар и на- званный ItemRef, определен как REF obj_ITEM. 1акая запись означает, что дан- ный атрибут содержит предоставляемое системой значение указателя на коп- Кретный экземпляр объекта ITEM. Этот указатель будет депо втелен вне зави- симости от тою, находи гея ли объект, па который он указывает, в оперативной памяти или иа диске Если требуется настройка но адресам, Oracle выполнит се автоматически
758 Глава 16. Объектно ориентированные балы данные Разумеется, прикладная программа должна присвоить Itt-mRef значение Од ним из способов сделать это является использование следующею S<jl ра). .,м INSERTINTO ItemRef SELECTREF(itemPtr) FROM objJTEM ItemPtr WHEREitemPtr.ItemNumber-10000. Здесь предполагается, что только одни элемент имеет значение ItemNumber, равное 10 000. Вы можете спросить, в чем разница между тинами данных REF и внешними ключами. Первое отличие заключается в том, что значения REF скрыты гл поль- зователей и не имеют для них смысла. Таким образом, как и для суррогатных ключей, для таких ссылок не требуется каскадной модификации. Но если экзем- пляр objJTEM, на который указывает ссылка, будет удален, значение этой ссылки окажется недействительным. Программа должна проверить ссылку на допусти- мость, прежде чем пользоваться ею Во-вторых, такие ссылки указывают на объекты, а не на строки таблиц. Объ- ект, на который указывает ссылка, может сам иметь сложную структуру данных н, кроме того, обладать методами. В Oracle есть библиотека классов, упрощаю- щая манипулирование такими ссылками. Последним различием является то, что такие ссылки являются однонаправленными. Объект obj ITEM, на который ука- зывает ссылка, может, но не обязан иметь обратный указатель на объект obj_ LINEITEM — например, в данном примере указатель назад отсутствует. Это озна- чает, что мы можем двигаться от objJINEITEM к objJTEM, но не наоборот. В следующем операторе определяется объект list_LINEITEM как таблица, со- стоящая из объектов objJJNEITEM, Это напоминает приведенное ранее определе- ние APARTMENTJIST2. Последним определен объект obj_ORDER (заказ). В отличие от BUILDING2, определенного как таблица, obj_ORDER определяется как объект. Поскольку он является объектом, атрибут Lineitems вложенной таблицы, указы- вающий на тип ListLINEITEM, не обязан иметь вложенную таблицу. Рассматривая листинг 16 2, имейте в виду, что мы определяем элементы дан- ных объекта, а не реляционные таблицы или что-нибудь им подобное. Структу- ры данных этого объекта будут обрабатываться только методами объекта, В последнем разделе определяется интерфейс методов объекта. Здесь интер- фейс имеет только один метод, под названием totalitems (всего товаров), который возвращает одиночное значение типа NUMBER. В более реалистичном примере было бы определено много методов. Определение методов объекта В листинге 16.3 показан пример метода объекта Oracle. Задачей этого метода яв- ляется перебор строк заказа и подсчет стоимости каждой строки с учетом нало- гов Функция начинается с объявления трех переменных н затем перебирает в цикле FOR набор объектов Lineitems. Оператор FOR 1 In 1..SELF.Lineitems.COUNT LOOP означает следующее: присвоить переменной значение 1, выполнить инструк- ции до конца блока, обозначенного END LOOP, п прибавить к i единицу. Эти
Стандарты ООСУБД 759 операторы следует повторять, пока i рибуте Lineitems. Листинг 16.3. Пример метода Oracle CREATE OR REPLACE TYPE BODY obj ORDER MEMBER FUNCTION total Items RETURN itemPtr objltem; Order-Total NUMBER : = 0: I INTEGER: BEGIN FOR I IN 1..SELF.Lineltems.COUNT LOOP UTL_REF.SELECT_OBJECT(LineItems(i).ItemRef. itemPtr): orderTotal : = orderTotal + SELF.Lineltems(i).Quantity * itemPtr.Price: END LOOP: RETURN orderTotal; END: END: Оператор UTL_REF.SELECT_OBJECT(Lineitems(i).ItemRef. itemPtr) вызывает класс, предоставляемый в составе библиотеки классов Oracle. Назна- чение этой функции состоит в том, чтобы присваивать переменной itemPtr значе- ние действительного указателя на объект obj_ITEM, на который ссылается ItemRef в текущей строке. После того как этот оператор будет выполнен, с помощью itemPtr можно ссы- латься на любые свойства obj_ITEM. Это делается следующим оператором, где itemPtr.Price имеет значение атрибута Price в объекте obj_ITEM, на который ссыла- ется текущая строка. Не беспокойтесь, если пока не все из этого вам понятно. Стремитесь к пони- манию роли и задач, а не подробностей работы операторов в листинге 16.3. Из этого изложения вы должны уяснить общие характеристики и природу объек- тов Oracle и понять, каким образом они продвигают традиционные базы данных в сторону объектно-ориентированного программирования. не окажется больше, чем число строк в ат- AS NUMBER IS Стандарты ООСУБД Над определением стандартов объекгпо-ориептированиых баз данных, который мог бы использоваться в качестве основы для построения ООСУБД, работают нисколько групп. Здесь мы рассмотрим работу двух из этих групп. Первая со- стоит из представителей комитетов ANSI и ISO, цепью который является рас- ширение тандарта SQL-92 для поддержки обработки объектов. Вторая, Object Management Group, представляет собой консорциум производителей объектных
760 Глава t6 Обье* ^.ориентированные базы данных баз данных н других заинтересованных с юри и деиимм ся ж* ptwai цг.,.х., важного промышленного стандарта обобщенной мп, ели т ( Object Model) и языка описания интерфейсов (Intelfate Definition Unguagr) Как и с те дует ожидать, в нервом стандарт в качс< Тш отпртшоЙ гонки выбраны базы данных, а движение осуществляется в сторону объектною мышления Второй стандарт движется от обьекюв к управлению данными Оба стандарта являются важными. SQL3 SQL3 — это расширение стандарта SQL-92, включающее поддержку объектно-ори- ентированных баз данных. В разработке обсуждаемого здесь проекта стандарта SQL3 принимают участие комитеты по стандартизации ANSI Х.ЗН2 и ISO/IEC JTC1/SC21/AVG3. Работа над этим стандартом не окончена, и в будущих вариан- тах вероятны изменения по сравнению с текущим проектом. Более того, SQL3яв- ляется стандартом на продукцию, а не собственно продуктом. На сегодняшний момент нет ни одной коммерческой СУБД, реализующей этот стандарт. Вам сле- дует рассматривать этот раздел в большей степени как описание возможного пу- ти эволюции реляционных СУБД, а не как описание конкретных возможностей продукта. SQL3 уходит корнями в традиции баз данных, а не в традиции объектного мышления. Целью комитетов, работающих над SQL3, является создание стан- дарта, вертикально совместимого с SQL92. Это означает, что все возможности и функции SQL92 должны быть унаследованы SQL3. Следовательно, SQL 3 по сути является средством для работы с реляционными базами данных, к которо- му добавлены объектные функции, а не новым средством работы с объектно- ориентированными базами данных. В SQL3 появляются три группы новых идей: поддержка абстрактных типов данных, расширение синтаксиса определения таблиц и дополнительные языко- вые конструкции, делающие SQL3 самодостаточным с вычислительной точки зрерия языком. Абстрактные типы данных В SQL3 абстрактный тип данных (abstract data type), или АТД (ADT) - это опре- деляемая пользователем структура, эквивалентная объекту ООП. Абстрактные типы данных имеют методы, элементы данных и идентификаторы. Они могут ыть и подтипами других абстрактных типов данных, так как поддерживается наследование. Для реализации логпки методов абстрактных типов данных может использоваться как SQL (с новыми расширениями), так и внешние языки, напри- мер Java, C# и C++. Абстрактный тип данных может использоваться в SQL выражении, хранить- ся в таблице, а также и то и другое одновременно. Если абстрактный тип данных шгурирует в одном или более SQL-выражении, но не хранится ни в какой таб- лице, то он является временным; постоянным абстрактный тип данных можно сделать, по^сд-да его в таблицу.
Стандарты ООСУБД 761 В листинге 16.4 приведен пример определения абстрактного типа данных для объекта СОТРУДНИК, описывающего сотрудника компании. Текущий синтаксис SQL3 набран прописными буквами, а код, предоставляемый разработчиком, — строчными. Конкретный синтаксис нам не важен, гак как он может измениться. Вместо этого следует обратить внимание на то, что этот абстрактный тип данных, подобно объекту ООП, имеет элементы данных и функции (методы). Элементы данных включают атрибуты ИмяСотрудника, ЛичныйНомер, ДатаНайма, ТекущаяЗар- плата и виртуальный элемент данных Зарплата (элемент данных, существующий только как результат вычисления функции). Методов имеется три: узнать Зарпла- ту, изменить_3арплату и удалить Сотрудника. Листинг 16.4. Пример определения абстрактного типа данных в SQL3 CREATE OBJECT TYPE Сотрудник WITH OID VISIBLE (ИмяСотрудника VARCHAR NOT NULL. ЛичныйНомер CHAR(7) Зарплата UPDATABLE VIRTUAL GET with узнать_3арплату SET WITH изменить_3арплату. PRIVATE ДатаНайма DATE ТекущаяЗарпрата CURRENCY PUBLIC ACTOR FUNCTION узнать_3арплату (:E Сотрудник) RETURNS CURRENCY (здесь должен быть код. который проверяет полномочия пользователя, вызывающего метод, и возвращает текущую зарплату. если полномочия достаточны} RETURN Зарплата END FUNCTION, ACTOR FUNCTION изменить_3арплату (:E Сотрудник) RETURNS Сотрудник {здесь должен быть код. который проверяет полномочия пользователя, вызывающего метод, и устанавливает новое значение зарплаты, если полыэдоуйя достаточны} RETURN :Е END FUNCTION. DESTRUCTOR FUNCTION удалить Сотрудника^ (:E Сотрудник) RETURNS NULL {код. выполняющий необходимую подготовку и проверку перед удалением сотрудника} DESTROY :Е RETURN :Е END FUNCTION. В SQL3 определены два вида абстрактных типов данных: ЛТД-объект (OBJECT) и ЛТД значение (VALUE). ЛТД-объект представляет собой идентифицируемую, независимую структуру данных, которой присваивается идентификатор, назы- ваемый ОП) Эпп ид< игнфикагор является уникальным значением, существую- щим на протяжении всей жизни объекта Если нужно передавать 011) другим
762 Глава 16. Объектно-ориентированные базы данных функциям или хранить его в других таблицах, в первую строку определения объек- та необходимо добавить фразу WITH OID VISIBLE. Это было сделано в листинге 164, Значения OID — это указатели на объекты; сохранение OID в таблице озна- чает сохранение в ней указателя на объект. Это .может быть удобно, но создает одну проблему. При уничтожении абстрактного типа данных eio OIL) стано- вится недействительным, но данное конкретное значение OID может храниться в строках таблиц, которые даже не находятся в памяти, когда происходит уни- чтожение абстрактного типа данных. Стандарт SQL3 не указывает, что должно происходить в этом случае. Очевидно, необходимо в программе проверять 01D на допустимость, прежде чем пытаться его использовать. Второй вид абстрактного типа данных — АТД-значение. АТД-значениям не присваиваются OID, и они могут существовать только в том контексте, в кото- ром они были созданы. Если АТД-значение создается как столбец таблицы, оно будет сохранено вместе с этой таблицей. Однако сослаться на этот абстрактный тип данных будет невозможно, кроме как через имя таблицы. Если АТД-значе- ние создается функцией, оно будет временным и прекратит свое существование при освобождении данной функцией памяти. Код в листинге 16.4 определяет АТД-объект Сотрудник как тип. Имя типа мо- жет использоваться в определениях таблиц точно так же, как и встроенные типы данных. В листинге 16.5 определяется таблица Отдел; у нее есть атрибут Назва- ниеОтдела типа CHAR(IO), атрибут Менеджер типа Сотрудник и атрибут Администра- тор, также типа Сотрудник. Таким образом, этот абстрактный тип данных исполь- зуется в определении таблицы наряду с любыми другими типами. Листинг 16.5. Определение таблицы с помощью абстрактного типа Сотрудник CREATE TABLE Отдел (НазваниеОтдела char (10). Менеджер Сотрудник. Администратор Сотрудник INSTANCE) При определении столбца, имеющего абстрактный тип данных, для указания того, что должно храниться в таблице — объект или указатель на объект, — ис- пользуется ключевое слово INSTANCE. Если оно указано, то в столбце хранятся данные объекта. Если нет, в столбце хранится указатель на объект. Если абстракт- ный тип данных представляет собой АТД-значение, то подразумевается INSTANCE. В листинге 16.5 для столбца Менеджер ключевое слово INSTANCE не указано, но оно /казано для столбца Администратор. Это означает, что каждая строка табли- цы Отдел будет в столбце Менеджер содержать указатель на объект типа Сотрудник, а в столбце Администратор — данные и методы. Открытые элементы данных объекта могут использоваться в SQL-операторах точно так же, как обычные столбцы таблиц. Например, для таблицы, созданной в листинге 16.5, рассмотрим следующий SQL-запрос: SELECT НазваниеОтдела. Менеджер.010. Менеджер.Имя. Администратор.010. Администратор.Имя FROM Отдел
Стандарты ООСУБД 763 При выполнении этого запроса из таблицы Отдел будут извлечены атрибуты НазваниеОтдела, Менеджер.ОЮ, Администратор.ОЮ и Администратор Имя По значе- нию атрибута Менеджер.ОЮ СУБД найдет экземпляр объекта Сотрудник, на кото- рый он указывает. Затем СУБД извлечет из этого объекта атрибут Менеджер Имя и возвратит его в ответе на этот запрос. Результат будет таким же, как если бы все объекты Менеджер хранились в таблице. Очевидно, что если OID, хранящий- ся в таблице, стал недействительным по причине удаления объекта, на который он указывает, СУБД должна будет каким-то образом обработать эту ошибку. Рассмотрим SQL-оператор SELECT НазваниеОтдела. Менеджер.Имя. Менеджер.Зарплата FROM Отдел Для выполнения этого оператора СУБД нужно будет обратиться к таблице Отдел, получить OID менеджера, получить экземпляр объекта Сотрудник, который представляет этого менеджера, и вызвать его функцию узнать_3арплату, которая материализует виртуальный столбец Зарплата. Функция узнать Зарплату может при запуске выполнять аутентификацию пользователя, например, запрашивая имя пользователя или пароль, либо предлагая выполнить какие-то другие дейст- вия, прежде чем СУБД сможет получить запрашиваемые данные. Когда функ- ция узнать Зарплату возвратит значение или код ошибки, указывающий, что дан- ные предоставлены не будут, СУБД может выполнить форматирование данных для этого сотрудника. Аналогичные действия потребуются для обработки каж- дой строки таблицы Отдел. Закрытые элементы данных являются локальными переменными объекта. Соответственно, следующий SQL-запрос является ошибочным: SELECT НазваниеОтдела. Менеджер.ТекущаяЗарплата FROM Отдел Единственный способ извлечь значение атрибута ТекущаяЗарплата из объекта Сотрудник — через функцию узнать_3арплату. Столбцам могут присваиваться значения, как и в обычных SQL-операторах. Так, например, выражение UPDATE Отдел SET Администратор.Имя = "Фред П. Джонсон WHERE НазваниеОтдела = "Бухгалтерия" изменит значение атрибута Имя объекта Администратор, существующего в отделе под названием "Бухгалтерия". В связи с гем. что некоторые объекты представляются ‘ чениями лепных.....екоторых случаях можно получит., неожиданные резул гы Рассмотрим следующий запрос: UPDATE Отдел Менеджер Имя - "Фред п Джонсон WHERE Названий I дела "Бухгалтерия"
764 Глава 16 Объектно-ориентированные базы даннст. Этот оператор не назначает сотрудника по имели Фред Ц Джонсон новым менеджером бухгалтерии. Вместо этого он меняет имя сотрудника, который является менеджером в настоящий момент. Меняется имя < друдника,тояетъ в любой другой таблице, имеющей ссылку на данный объект Сотрудник, ею имя также изменится. Если на должность менеджера в бухгалтерии еще ие назначен нп один сотрудник, этот оператор выдай ошибку. Чтобы заменить менеджера бухгалтерии дру i им < от рудником, которого зовут Фред П. Джонсон, объект Менеджер должен указывать па правильный экземпляр объекта Сотрудник. Это можно сделать с помощью следующего SQL-кода: UPDATE Отдел SET Менеджер = SELECT Сотрудник.01D FROM Сотрудник WHERE Имя = "Фред П. Джонсон” WHERE НазваниеОтдела = "Бухгалтерия" С концегпл альной точки зрения, этот оператор является правильным. Будет ли он в реальности работать в СУБД, реализующей стандарт SQL3, — это, разу- меется, зависит от разработчиков СУБД. Как уже отмечалось, поскольку SQL3 нах дится в стадии разработки и поскольку ни в одном продукте этот стандарт еще не реализован, можно считать, что данное изложение указывает стратегиче- ское направление развития отрасли, а не конкретный отраслевой стандарт син- таксиса. Определение абстрактных типов данных дает возможность создавать, хранить и изменять объекты в SQL. Стандартом SQL3 предложены и другие изменения в SQL. Рассмотрим их далее. Табличные расширения SQL3 SQL3 расширяет определение таблиц в нескольких отношениях. Во-первых, таб- лицы в SQL3 имеют идентификатор строки (row identifier), представляющий со- бой уникальный идентификатор каждой строки таблицы. Этот идентификатор — го же самое, что и суррогатный ключ, термин, который мы использовали в преды- дущих главах. Приложения могут использовать этот идентификатор, если он вво- дится явно путем указания в определении таблицы фразы WITH IDENTITY. В любой таблице, определенной таким образом, создается скрытый столбец под названием IDENTITY. Значения из этого столбца могут использоваться приложением, но он не включается в результаты выполнения оператора SELECT *. Рассмотрим листинг 16.6, определяющий таблицу ПРЕПОДАВАТЕЛЬ, п следую- щие два SQL-оператора: SELECT ИмяПреподавателя. Идентификатор FROM ПРЕПОДАВАТЕЛЬ и SELECT FROM ПРЕПОДАВАТЕЛЬ
Стандарты ООСУБД 765 Листинг 16.6. Определение таблицы с ключевым словом WITH IDENTITY CREATE TABLE ПРЕПОДАВАТЕЛЬ WITH IDENTITY (ИмяПреподавателя char (Ю) Телефон char (7), Офис char (5) ) Результатом первого оператора будет таблица с двумя столб,™........ „з которых будет „мя преподавателя, а во втор,», - кагор строк,,. Результатом второго оператора будет та6.,„„а с тремя е,о.,6„. м, Ив, Преподавателя, Телефон и Офис. Вторым дополнением к концепции таблицы в SQL3 является введение трех типов таблиц: SET, MULTISET и LIST. Таблица типа SET - эго таблица без повторяю щнхея строк; таблица типа MULTISET может иметь повторяющиеся строки и жви валентна понятию таблицы в SQL92. (Эго определение, конечно игнорирует столбец IDENTITY, поскольку с учетом этого столбца нн одна таблица не пмеег но вторяющихся строк.) Наконец, таблица типа LIST - эго таблица, упорядоченная по одному пли нескольким столбцам. Третьим дополнением к концепции таблиц в SQL3 является подпит ища (subtablc). Подтаблица является подмножеством другой таблицы, называемой над таблицей (supertable). Подтаблица наследует все столбцы своей ийдтаб ш цы и может также иметь свои собственные столбцы. Таблица, имеющая иод- таблицу или па паблицу, имеет неявно определенный идентификатор строки В листинге 16.7 определены два типа преподавателей: ШТАТНЫЙ_ПРЕПОДАВАТЕЛЬ и ВНЕШТАТНЫЙ_ПРЕПОДАВАТЕЛЬ. Таблица ШТАТНЫЙ_ПРЕПОДАВАТЕЛЬ имеет столбцы ИмяПреподавателя, Телефон, Офис и ДатаЗачисленияВШтат. Таблица ВНЕШТАТНЫЙ_ ПРЕПОДАВАТЕЛЬ имеет столбцы ИмяПреподавателя, Телефон, Офис и ДатаСледующего- Рассмотрения. Хотя эти таблицы определены без ключевого слова W TH IDENTITY, они имеют столбец IDENTITY, поскольку являются подтипами. Листинг 16.7. Определение подтаблиц CREATE TABLE ПРЕПОДАВАТЕЛЬ WITH IDENTITY (ИмяПреподавателя char (10), Телефон char (7). Офис char (5) CREATE TABLE ШТАТНЫЙ_ПРЕПОДАВАТЕЛЬ UNDER ПРЕПОДАВАТЕЛЬ (ДатаЗачисленияВШтат Date) CREATE TABLE ВНЕШТАТНЫЙ_ПРЕПОДАВАТЕЛЬ UNDER ПРЕПОДАВА ЕЛЬ (ДатаСледуютегоРассмотрен.ия Date) Поразмыслите ш гем. какие последе™,,,.вызовет „в, аб< ,рак1ных типов данных и подтипов, ак а страх, > Политы и ,аб м...........меть подтипы, „о о,„. ие „„лжотс,, од, . те«же 11,ш абстракшмх типов данных определяют одну иерархию ’ . Ы1Ы. ,а6,и„ МИ или часшчпо перекрывающимися, ,
766 Глава 16. Объектно-ориентированные базы данных за его чрезмерную сложность в этом отношении, и ин гересио будет увидеть, какая часть этой сложной структуры будет в действительности реализована в СУБД Расширения языка SQL В SQL3 методы аострактных типов могут быть сами написаны на SQL. Чтобы сделать эту возможность более реальной, предложены дополнительные языковые элементы, делающие SQL полноценным в вычислительном отношении языком программирования. Предложенные расширения перечислены в табл. 16.4. Таблица 16.4. Предложенные в стандарте SQL3 расширения языка SQL Оператор_______Цель DESTROY Уничтожает АТД-объект; допустим только в функциях-деструкторах ASSIGNMENT Позволяет присвоить результат выполнения SQL-запроса локальной переменной, столбцу или АТД-атрибуту CALL Вызывает SQL-процедуру RETURN Возвращает значение, вычисленное процедурой или функцией CASE Выбирает путь, по которому пойдет выполнение программы в зависимости от значения управляющей переменной IF THEN ELSE Условный оператор WHILE LOOP Оператор цикла До сих пор SQL был языком, ориентированным на множества. Операторы SELECT выделяли множество строк и выполняли с ними некоторые действия. До- бавление языковых элементов, представленных в табл. 16.4, изменит эту харак- теристику. В SQL станет возможна реализация логики «одна строка за один при- ем». Это изменение сделает SQL еще более похожим иа традиционные языки программирования. Это необходимо, если предполагается использовать SQL для написания методов абстрактных типов данных, но обозначает также фундамен- тальную смену парадигмы SQL. ODMG-93 ODMG (Object Data Management Group, Группа управления объектными данны- ми) — это консорциум производителей объектных баз данных и других заинтере- сованных промышленных экспертов, который применил идеи другой группы, OMG (Object Management Group, Группа управления объектами), к проблеме объект- ных баз данных. Первый отчет ODMG был представлен в 1993 году и поэтому называется ODMG-93. Этот стандарт вышел из объектно-ориентированного про- граммирования, а не из традиционных реляционных баз данных. Следовательно, В качестве базовой конструкции в нем выступает объект, а не таблица, как в SQL3- ODMG-93 — это определение интерфейсов для продуктов, работающих с объ- ектными данными. Реализация идей ODMG-93 может весьма различаться. Про- дукт ODMG-93, предназначенный для хранения и манипулирования данными объектов C++, может иметь совершенно другую организацию, чем продукт для
Стандарты ООСУБД 767 хранения и манипулирования объектами языка Smalltalk. Эти два продукта мо- гут быть весьма различными, и все же реализующими интерфейсы ODMG-93. Поскольку ODMG-93 вырос из контекста объектно-ориентированного про- граммирования, его подробное описание требует существенного знания ООП. Такое описание выходит за рамки этой книги. Мы сосредоточим наше внимание на фундаментальных концепциях, лежащих в основе отчета ODMG-93. В приве- денной ниже врезке перечислены пять ключевых идей, согласно описанию Мэри Лумис (Mary Loomis)1. КЛЮЧЕВЫЕ ИДЕИ ОБЪЕКТНОЙ МОДЕЛИ ODMG-93 ----------------------------------- ♦ Объекты являются фундаментальными единицами. ♦ Каждый объект имеет постоянный, сохраняющийся в течение всего времени сущест- вования объекта уникальный идентификатор ♦ Объекты могут классифицироваться по типам и подтипам ♦ Состояние объекта определяется его данными и связями. ♦ Поведение объекта определяется его методами. Объекты — фундаментальные единицы Согласно объектной модели ODMG, объекты являются фундаментальными еди- ницами хранения и манипулирования. В отличие от SQL3, где в качестве фунда- ментальной единицы выступает таблица, а объекты хранятся в столбцах таблиц, базовой сущностью в ODMG является объект. Концепция ODMG более похожа на концепцию объектной программы из листинга 16.1. То есть прикладная про- грамма определяет объекты сами по себе, а делать ли их постоянными — решает ООСУБД. Никаких других структур, вроде таблиц, не требуется. В соответствии с моделью ODMG, объект может быть изменяемым (mutable) и неизменяемым (immutable). Изменяемые объекты, как следует из их названия, могут быть изменены; неизменяемые объекты являются постоянными, и ни одно приложение не может изменить состояние такого объекта. Реализация неизме- няемости возлагается на ООСУБД. Каждый объект имеет пожизненный уникальный идентификатор Вторая фундаментальная идея объектной модели ODMG состоит в том, что каж- дому объекту присваивается уникальный идентификатор, который является дей- ствительным на протяжении времени существования объекта. Более того, иден- тификатор должен быть действительным вне зависимости от того, где хранится объект — на внешнем носителе или в оперативной памяти. Настройка по адресам должна выполняться ООСУБД явно; прикладные программы могут использо- вать указатели на объекты так, как если бы они всегда были действительны. Этот стандарт оставляет свободу в определении конкретной формы объ- ектного идентификатора. Таким образом, различные производители ООСУБД могут использовать различные способы задания идентификаторов объектов. Это Mary Е. S. Loomis, Object Databases, The Essentials. Reading, MA Addison-Wesley, 1995, p 88-110.
768 Глава 16 Объектно*ориентированные базы данным означает, что идентификаторы объектов из различных баз данных уцр«* >мгнш> разными СУБД, не обязательно будут совместимыми Для н< |<а. п,- „ .и-И1Ш, баз данных это вряд ли сое гаиит проблему, так как вес объекты в дамкой йда ной базе данных будут создаваться п храни i ы я одном и ой Ь В распределенной системе проо тема идентификации о«п>ектов яп.1ястся (хуиа.' сложной ио двум причинам: во-первых. потому, что идентификаторы объектов в'различных СУБД могут иметь различные форматы, а но вторых» потому что и чентификаторы объектов нс обяза телъно будут уникальными в мат штабе шхколь- ких баз данных. Этот вопрос оставлен без внимания в стандарте ODMG-93 Объекты могут организовываться в иерархии типов и подтипов Объектная модель стандарта ODMG-93 указывает, что объекты организуются в группы по типу. Объекты создаются как принадлежащие к определенному ти- пу. Все объекты одного и того же типа имеют одинаковые характеристики и пове- дение. Объекты могут определяться как подтипы других объектов. В этом случае они наследуют все характеристики и поведение родительского типа. Согласно стандарту', объект создается как экземпляр определенного типа, и этот экземпляр не может изменить свой тип. Термины тип и класс часто используются как синонимы. Согласно книге Мэ- ри Лумис, это неправильно. Объектный класс — это логическая группа объектов, как они определены в ODMG-93; классы имеют подклассы, наследующие от сво- их родителей их характеристики и поведение. Тип — это реализация класса на конкретном языке. Так, например, класс Сотрудник представляет собой логиче- ское определение данных и методов; он может иметь подклассы Продавец и Бухгал- тер, являющиеся его наследниками. Реализация класса Сотрудник на C++ называ- ется типом, а реализации на C++ подклассов Продавец и Бухгалтер называются подтипами1, В языке Smalltalk класс Сотрудник может реализовываться по-друго- му7. Эта реализация будет являть собой другой тип. Различение класса и типа помогает отделить логические определения от конкретных реализаций логиче- ских структур. Объектные классы (а следовательно, и типы) могут иметь свойства Стандарт ODMG указывает, что каждый класс имеет имя и ограничения уникальности, являющиеся его свойствами. Совокупность всех экземпляров объектного класса называется экстентом (extent) объекта. Любой атрибут или комбинация атрпбу- юв может быть объявлена уникальной в масштабе экстента. Например, в классе Сотрудник атрибут НомерСотрудника может быть объявлен уникальным, как может оыть объявлено уникальным сочетание {Имя, Фамилия}, и т. д. Поскольку требова- ния уникальности относятся ко всему экстенту, а не к какому-нибудь определен- ному экземпляру объекта, такие требования являются свойствами класса, а не экземпляра класса. 3 аким образом, имя класса Сотрудник и требование, чтобы Но- мерСотрудника был уникальным, являются свойствами класса. С ам по себе Номер- Сотрудника, однако, является свойством экземпляра класса Сотрудник. 1 Mary Е S Loomis, Object Databases, The Essentials. Redding, MA: Addison-Wesley, 1995. p. 96
Стандарты ООСУБД 769 Поскольку ODMG представляет собой стандарт па интерфейс, а не на его реализацию, здесь не делается попыток описать, как должно осуществляться хранение типов и подтипов и манипулирование ими. Интерфейс просто показы- вает, что объекты должны записываться и считываться классом и что должно быть обеспечено наследование. Состояние определяется значениями данных и связями В соответствии со стандартом ODMG, состояние любого объекта представляется его свойствами. Этими свойствами могут быть либо атрибуты, либо связи. Атри- бут — это символьное значение или набор значений, ДатаНайма и ТекущаяЗарпла- та — значения констант, ЗарплатаРанее — набор значений констант. Связь — это свойство, указывающее на наличие отношений между экземпляром одного объекта и одним или несколькими экземплярами других объектов. В качестве примера связи можно привести свойство Отдел. ODMG указывает набор операций, которые могут выполняться над связями. Эти операции перечислены в табл. 16.5. Операции различаются по максималь- ной кардинальности связи. Это делается потому, что в случае связи 1:1 свойства являются однозначными, и наборы свойств рассматривать не требуется. В слу- чае связи 1:N или N:M свойство имеет много элементов, поэтому создается мно- жество, и программа должна уметь перебирать его элементы. Таблица 16.5. Операции над связями в ODMG Операция Описание Set Создать связь 1.1 Clear Удалить связь 1:1 lnsert_element Добавить элемент на множественную сторону связи 1.N или N:M Remove_element Удалить элемент со множественной стороны связи 1:N или N:M Get Возвратить ссылку на объект, состоящий в связи 1:1 Traverse Возвратить ссылку на множество объектов, состоящих в связи 1:N или N:M Create_rterator Создать структуру для обработки элементов множества объектов, — полученного посредством операции Traverse Когда объекты имеют связь, эта связь должна становиться постоянной, когда делается постоянным один из объектов. Стандарт не указывает, как должна пред- ci яться свял, и осуществляться naciройка связей по адресам. Эти вопросы следует решать при создании ООСУБД. Поведение объекта определяется его операциями Поведение объекгною юна определяется его методами. Все объекты заданного типа имеют одинаковые методы, и объекты подтипов наследуют эти методы. Ес- ли объект подтипа переопределяет метод, он гем самым замещает метод, унасле- дованный от роди юля Если, например, объект Сотрудник имеем метод узнать_3ар- плату, и объект Продавец, Подтип объекта Сотрудник, ьткже имеет метод узнать арплату, для получения снс/ц пии о гарплате продавца будсч н< нольлона! ься соб егвеиный метод мото объекта, Продавец!узнать Зарплату
770 Глава 16. Объектно-ориентированные базы данных Объекты взаимодействуют между собой, вызывая меч оды друг друга Иногда говорят, что объекты передают друг другу сообщения, причем сообщением явля ется строка наподобие Продавец!узнать_3арплату, включающая имя объектного типа и имя метода этого типа. У сообщений, разумеется, могут быть параметры. Назначение ООСУБД состоит в обеспечении постоянного хранения объек- тов. Стандарт ODMG указывает, что объекты имеют методы, поэтому в число функций ООСУБД, претендующей на соответствие этому стандарту, должно входить хранение методов и управление ими. На самом деле современные ООСУБД весьма отличаются по степени поддержки постоянного хранения ме- тодов. Некоторые из них в действительности вообще не обеспечивают такой поддержки. Другие обеспечивают ее в какой-то степени, по не позволяют созда- вать версии объектов. Хранение методов является важным вопросом и, вероятно, возможности ООСУБД в этой сфере в будущем будут улучшены. Ни одно приложение не яв- ляется статичным: требования меняются, и необходимо адаптировать поведение объектов к этим изменениям. Более того, методы могут меняться и при отсутст- вии изменений в структуре данных объекта. Без средств управления методами у двух экземпляров объекта могут оказаться различные версии методов. Рассмотрим пример. Допустим, экземпляр класса Продавец, который мы обо- значим Продавец А, создается и сохраняется с некоторой! версией метода назна- чить_3арплату. Теперь предположим, что способ вычисления зарплаты продавца изменился, и соответственно был изменен метод назначить_3арплату. После этого был создан и сохранен обз>ект Продавец Б. Теперь Продавец А и Продавец Б будут казаться эквивалентными в том, что касается их данных, но в действительности это не так. Без управления методами со стороны СУБД не существует способа определить, что Продавец А и Продавец Б представляют собой различные версии объекта Продавец. Эта ситуация не отличается от того, что происходит сегодня в прикладных программах, не имеющих отношения к ООСУБД, поэтому сторонники ООСУБД могут утверждать, что ООСУБД не ухудшили ситуацию. Однако это представля- ется лишь отговоркой. Если определено, что объекты имеют свойства, описываю- щие их данные, и свойства, описывающие их поведение, то неправомочно утвер- ждать, что постоянное хранение объектов относится только к одной разновидности свойств и не относится к другой. Слишком многое из того, что обещает нам ооъектное мышление, останется за бортом, если наряду с управлением данными ООСУБД не будут обеспечивать управление методами. Резюме Реляционные базы данных не слишком приспособлены для хранения объектов , поскольку объект могут содержать сложные структуры, плохо подходя- щие для хранения в таблицах. Кроме того, объекты имеют методы, которые также нужно хранить. Для постоянного хранения объектов были разработаны специа- лизированные объектно-ориентированные СУБД, но они не имели коммерческо-
Резюме 771 го успеха, так как требовали преобразования существующих реляционных дан- ных в формат ООСУБД. Выигрыш не стоил затраченных средств. Вместо этого начали появляться СУБД, сочетающие реляционный и объектный подходы к хра- нению объектов. Такие СУБД получили название объектно-реляционных. В объектно-ориентированном программировании (ООП) программы состоят из инкапсулированных объектов — логических структур, имеющих элементы данных и характеризуемых определенным поведением. Интерфейс — это как бы «внешний вид» объекта, а реализация — его инкапсулированная внутренняя структура. Объекты могут иметь подклассы, которые наследуют атрибуты и мето- ды своих надклассов. Полиморфизм допускает существование нескольких вер- сий одного и того же метода: компилятор вызывает правильную версию метода во время выполнения в зависимости от класса объекта. Класс — это логическая структура объекта; группа объектных классов назы- вается библиотекой объектных классов. Экземпляры объектного класса называ- ются экземплярами объекта пли просто объектами. Конструкторы объектов — это методы, выделяющие память иод объекты и создающие соответствующие структуры; деструкторы уничтожают объекты и освобождают оперативную па- мять. Временные объекты существуют только во время выполнения программы, а постоянные объекты записываются на физический носитель и существуют вне рамок работы программы. Постоянное хранение объектов может быть обеспечено с помощью традици- онных систем обработки файлов, реляционных СУБД пли объектно-ориентиро- ванных СУБД. Использование традиционных систем обработки файлов создает существенную нагрузку па программиста и имеет смысл только в приложениях, имеющих несколько простых объектов, структура которых меняется редко. По- стоянное хранение объектов возможно также с помощью реляционных СУБД, ио программист при этом должен преобразовывать объектные структуры в отно- шения, писать SQL-запросы и разрабатывать алгоритмы настройки по адресам. Использование ООСУБД — это наиболее простой и прямолинейный способ постоянного хранения объектов. СУБД Oracle поддерживает постоянное хранение объектов с использованием объектно-реляционного подхода. Можно определять типы объектов и применять их в таблицах как столбцовые объекты, массивы переменной длины, вложенные таблицы или строчные объекты. Можно также определять и «чистые» объекты; такие объекты могут включать массивы переменной длины и вложенные табли- цы. Они могут также содержать указатели на объекты, определенные как REF- агрибуты. Наконец, такие объекты могут имет ь методы, которые могут обращать- ся к библиотекам классов Oracle. SQL3 — это расширение SQL-92, которое предусматривает абстрактные типы данных (АТД), дополнения к концепции таблиц и новые возможности языка SQL. Абстрактные типы данных, постоянное храпение которых обеспечивается путем записи их в таблицу, могут быть двух типов: АТД-объект и АТД-значенпе. А1Д объекты имеют идентификаторы, называемые O1D. В SQL3 таблицы име- ют идентификаторы строк и могут иметь подтипы. Определено три типа таблиц- SET, MULTISET и LIST В табл. 16.4 приведен синеок расширений SQL, предложен- ных в SQL3.
772 Глава 16 Объектно-ориентированные базы данных Пятью ключевыми идеями стандарта ODMG-93 являются представление об объекте как о фундаментальной структуре данных, наличие у объектов пожиз- ненных уникальных идентификаторов, организация объектов в иерархии типов и подтипов, представление состояния объекта с помощью состояния его данных и связен, а также определение поведения объекта с помощью его действий. Се- мантические объекты, как они определены в главе 4, реализуют стандарт ODMG для атрибутов данных, но не для поведения объекта. Вопросы группы I 1. Объясните, чем объектно-ориентированное программирование отличается от традиционного программирования. 2. Почему реляционные базы данных более популярны, чем объектно-ориен- тированные? 3. Дайте определение объекта ООП. 4. Дайте определения терминов инкапсулированный, атрибут и метод. 5. Объясните разницу между интерфейсом и реализацией. 6. Что такое наследование? 7. Что такое полиморфизм? 8. Дайте определения терминов объектный класс, библиотека объектных клас- сов и экземпляр объекта. 9. Объясните, в чем состоят функции конструкторов и деструкторов объектов. 10. Укажите, в чем разница между временным и постоянным объектом. 11. Объясните различие в записи КЛИЕНТ'Найти и КЛИЕНТ.Индекс. 12. Какова функция ключевого слова NOTHING в листинге 16.1? 13. Какова функция ключевого слова ME в листинге 16.1? 14. Что такое обратный вызов и для чего он используется? 15. Что означает термин настройка по адресам? 16. Кратко охарактеризуйте задачи, стоящие перед программистом при исполь- зовании для постоянного хранения объектов традиционной системы обра- ботки файлов. » 17. Кратко охарактеризуйте задачи, стоящие перед программистом при ис- пользовании для постоянного хранения объектов реляционной СУБД. 18. Укажите преимущества и недостатки использования ООСУБД для посто- янного хранения объектов. 19. Напишите операторы ORACLE, определяющие объектный тип Pname (имя человека) с тремя атрибутами: FirstName, MiddleName и LastName (имя, от- чество и фамилия). Сохраните этот тип как объект-столбец в таблице PERSON (человек)
Вопросы группы I 773 20. Напишите оператор Oracle, создающий массив переменной длины, который может содержать максимум 100 объектов типа Pname. Напишите операто- ры, создающие таблицу данных о клубе под названием CLUB1, имеющую столбцы с суррогатным ключом, названием клуба (ClubName) и массив пе- ременной длины с именами людей. 21. Напишите операторы Oracle, создающие таблицу CLUB2. аналогичную CLUB1, но хранящую список имен людей во вложенной таблице, а не в массиве пе- ре ной длины Назовите вложенную таблицу Pname. Table 22. Объясните, в чем разница между таблицами CLUB1 и CLUB2 23. Напишите операторы Oracle, создающие таблицу с Pname как объектом- строкой. 24. Объясните назначение REF-атрпбутов в листинге 16.2. Чем э;ги атрибуты отличаются от внешних ключей? 25. Объясните назначение операторов FOR I in l..SELF.Lineitems.COUNT LOOP и UTI_REF.SELECT_OBJECT(LineItems(i).ItemRef, itemPtr) 26. Что такое SQL3? 27. Что такое абстрактный тип данных (АТД)? 28. Объясните разницу между АТД-объектом и АТД-значепием 29. Что такое OID? Для чего он используется? 30. Объясните, что должна делать СУБД при выполнении следующего SQL- оператора над таблицей созданной в листинге 16 5: SELECT НазваниеОтдела. Менеджер.Телефон. Администратор.Телефон FROM Отдел 31. Что произойдет, когда СУБД выполнит следующий SQL-оператор над таб- лицей созданной в листинге 16.5: UPDATE Отдел SET Менеджер.Имя = "Джон Джекоб Астор" 32. Напишите SQL-оператор, который нужно выполнить над таблицей создан- ной в листинге 16.5, для назначения на должность менеджера другого со- трудника. 33. Что такое идентификатор строки в SQL3? 34. Объясните, чем различаются SET, MULTISET п LIST в SQL3. 35. Объясните разницу между подтаблицей надтаблицей и таблицей. 36. Что такое ODMG-93? 37. Перечислите пять ключевых идей ODMG-93. 38. В чем заключается различие между типом и классом в ODMG-93? 39. Чем отличаются свойство и атрибут в ODMG-93?
774 Глава 16. Объектно ориентированные базы данны. 40 Что такое экстент? 41. Что такое свойства класса в ODMG-93? 42. Какие значения могут иметь свойства в стандарт ODMG? 43. Какие значения могут иметь атрибуты в стандарте ODMG? 44. Какие значения могут иметь свойства связей в стандарте 0DM(;? 45. В чем важность постоянного хранения методов? Какая проблема может возникнуть, если такое хранение не обеспечивается? 46. Объясните, в чем семантические объекты соответствуют стандарту ODMC, а в чем нет. Вопросы группы II 47. Рассмотрите требования и реляционную структуру базы данных галереи View Ridge в главе 7. Рассмотрите использование типов Oracle, а также объектов-столбцов, массивов переменной длины, вложенны-' таблиц и объ- ектов-строк в контексте потребностей галереи. Какие изменения вы бы внесли в реляционную структуру? Могли бы вы порекомендовать заме- нить таблицы TRANSACTION или WORK массивами переменной длины или вложенными таблицами? Если да, то как это сделать? Если нет, то поче- му? Покажите, как бы вы использовали REF-атрибуты Oracle для устра- нения необходимости в таблице пересечения. Стоит ли, по вашему мне- нию, идти этим путем? 48. Рассмотрите типы Oracle, а также объекты-столбцы, массивы переменной длины, вложенные таблицы и объекты-строки в контексте семантической ооъектной модели, описанной в приложении Б. Какие элементы этой мо- дели соответствуют типам? Массивам с переменной длиной? Вложенным таблицам? Покажите, как бы вы использовали объектно-реляционные воз- можности Oracle для моделирования каждого из типов семантических объектов, описанных в приложении Б.
Приложение А Структуры данных Все операционные системы предоставляют услуги по управлению данными. Но для удовлетворения специфических нужд СУБД этих услуг, вообще говоря, недостаточно. Поэтому для повышения производительности СУБД строят и под- держивают специальные структуры данных, о которых и пойдет речь в этом приложении Вначале мы обсудим плоские файлы и некоторые проблемы, возникающие при необходимости обрабатывать такие файлы в различном порядке. Затем мы обратимся к трем специализированным структурам данных: последовательным спискам, связным спискам и индексам (пли инвертированным спискам). Далее мы продемонстрируем, как с помощью различных структур данных можно пред- ставить каждую из трех специализированных структур, описанных в главе 6 (деревья, простые сети и сложные сети). В конце мы рассмотрим представление и обработку множественных ключей. Хотя для работы с большинством СУБД по требуется исчерпывающего зна- ния структур данных, приведенные здесь основы являются необходимыми для администраторов баз данных и системных программистов, работающих с СУБД. Знакомство со структурами данных помогает также при оценке и сравнении ме- жду собой различных СУБД. Плоские файлы Плоский файл (flat file) по файл, не содержащий повторяющихся групп. На рис А 1, а. Изображен пример плоского файла. Файл па рис. А.1, б, нс является Плоским, поскольку элсмеш Ловары в нем повторяется. Принцип доступа к плос- кому файлу можс! быть любым ши щдовагелып.щ, последовательным с нндек СаИиеЙ или прямым Плоские файлы используются на протяжении многих лет и Коммерческих системах обрабо|кн данных. Обычно они обрабатываются в не- котором заранее определенном порядке — например по возрастанию значения Ключевого ноля
776 Приложение А Структуры данных Файл ЗАНЯТИЯ НомерСтудента I КодПредмета | Семестр | । —------------- -------- Файл СЧЕТ pl—............................. | НомерСчета | Товар(ы) р Данные для примера Данные для примера 200 70 2000S 100 30 2001F 300 20 2001F 1000 10 20 30 40 | 200 30 2000S 1010 50 300 70 2000S 1020 10 20 30 100 20 2000S 1030 50 90 а б Рис. А.1. Хранение записей: а — в плоском файле; б — в файле, не являющемся плоским Обработка плоских файлов в различном порядке Иногда пользователям нужно обрабатывать плоские файлы такими способами, которые не имеют простой реализации при данной структуре файла. Рассмотрим, например, файл ЗАНЯТИЯ на рис. А.1, а. Чтобы составить расписание занятий сту- дентов, требуется упорядочить данные по полю НомерСтудента, а чтобы составить список группы — по полю КодПредмета. Разумеется, при физическом хранении за- писи могут быть упорядочены только по одному из полей — НомерСтудента или КодПредмета, ио не по обоим полям одновременно. Традиционное решение про- блемы обработки записей в различном порядке состоит в том, чтобы отсортиро- вать записи по номерам студентов, составить расписания занятий, затем отсорти- ровать записи по кодам предметов и составить списки предметов групп. В некоторых приложениях, например в системах пакетной обработки, это решение оказывается эффективным, несмотря на свою неуклюжесть. Но пред- ставьте, что сортировку требуется выполнить одновременно обоими способами, поскольку два параллельно работающих пользователя имеют различные пред- ставления файла ЗАНЯТИЯ. Что делать в этом случае? Одно из решений — создать две копии файла ЗАНЯТИЯ и отсортировать их в нужном порядке, как показано на рис. А.2. В связи с тем, что данные в такой структуре упорядочены в определенной логической последовательности, ее ино- гда называют последовательным списком (sequential list). Последовательные спи- ски можно хранить в виде файлов с последовательным доступом. Однако обыч- но СУБД не делают этого, так как последовательное чтение файла — процесс долгий. Кроме того, файлы последовательного доступа невозможно обновить в середине без перезаписи всего файла. К тому же хранение нескольких копий одного и того же последовательного списка неэффективно, так как это может За си бол щи пре тед CKDJ НИС] соде Вый ноле д Чсая ствуе М(*Ме
Плоские файлы 777 привести к нарушению целостности данных. К счастью, существуют структуры данных, позволяющие обрабатывать записи в различном порядке, по не требую- щие дублирования данных. Такими структурами являются, среди прочих, индек- сы (indexes) и связные списки (linked lists). Код Код НомерСтудента Предмета Семестр НомерСтудента Предмета Семестр 100 30 2001F 100 20 2000S 200 70 2000S 200 30 2000S 300 20 2001F 300 70 2000S 300 20 2001F 100 20 2000S 100 30 2001F 200 30 2000S 200 70 2000S 300 70 2000S а б Рис. А.2. Файл ЗАНЯТИЯ, организованный в виде последовательного списка: а — с упорядочением по полю НомерСтудента; б — с упорядочением по полю КодПредмета Замечание по поводу адресации записей Обычно СУБД создает в своих файлах прямого доступа физические записи большого размера, или блоки. В этих блоках содержатся логические записи. Как правило, одна физическая запись содержит множество логических. Здесь мы предположим, что обращение к физической записи происходит по ее относи- тельному номеру. Например, логическая запись может принадлежать физиче- ской записи с номером 7, 77 или 10 ООО. Таким образом, относительный номер за- писи — это физический адрес логической записи. Если одна физическая запись содержит несколько логических записей, адрес логической записи должен так- же указывать ее положение внутри физической записи. Следовательно, пол- ный адрес логической записи может иметь структуру вида «относительный номер записи 77, смещение 100». Это означает, что запись начинается с байта 100 физической записи 77, Для упрощения примеров в тексте мы будем предполагать, что одна физиче- ская запись содержит только одну логическую, чтобы нам не пришлось задумы- ваться о смещениях байтов внутри физических записей. Хотя это и не соответ- ствует действительности, зато ограничивает изложение только существенными моментами. Упорядочение с помощью связных списков Связные, списки (linked lists) позволяют производить логическое упорядочение записей, в общем случае не упорядоченных физически. Для создания связного списка к каждой записи добавляется специальное поле — поле ссылки. Это поле
778 Приложение А. Структуры данных содержит адрес (в нашем случ к- <н шлите н.пып помер) следующей записи в ло гической пос тедовательиостн. Например, па рис. Л 3 изображен модифици|юван ный файл ЗАНЯТИЯ со связным списком, в котором з;........и упорядочены по полю НомерСтудента. Обратите внимание, что поле ссылки в последней по леническому порядку записи имеет нулевое значение. Номер- Код Студента Предмета Семестр Ссылка Относительный номер записи 1 2 3 4 5 6 200 70 2000S 4 100 30 2001F 6 300 20 2001F 5 200 30 2000S 3 300 70 2000S 0 100 20 2000S 1 Начало списка = 2 Рис. А.З. Файл ЗАНЯТИЯ, упорядоченный по полю НомерСтудента с помощью связного списка На рис. А.4 показан файл ЗАНЯТИЯ с двумя связными списками, один из кото- рых упорядочен по полю НомерСтудента, а другой — по полю КодПредмета. Каждая запись имеет два поля ссылки, по одному па каждый список. Относительный Номер- Код Ссылка Ссылка номер записи Студента Предмета Семестр на студента на предмет 1 200 70 2000S 4 5 2 100 30 2001F 6 1 3 300 20 2001F 5 4 4 200 30 2000S 3 2 5 300 70 2000S 0 0 6 100 20 2000S 1 3 Начало списка студентов - 2 Начало списка предметов = 6 Рис. А.4. Файл ЗАНЯТИЯ, упорядоченный двумя различными способами с помощью связных списков При вставке и удалении связные списки имеют огромное преимущество перед последовательными. Например, чтобы вставить в файл ЗАНЯТИЯ запись о сту- денте 200 и группе 45, пришлось бы переписать оба списка па рис. А.2. В слу- чае связных списков новую запись можно добавить в конец физического спи- ска, а чтобы она заняла правильное место в связных списках, потребуется изменить только значения двух нолей ссылок. Эти изменения показаны на рис. А.5. Когда запись удаляется из последовательного списка, на ее месте возника- ет пустота. Но в связных списках запись можно удалить, просто изменив зна- чения полей ссылок, или указателей. На рис. А.6 запись о занятиях студента
Плоские файлы 779 200 по предмету 30 логически удалена из файла ЗАНЯТИЯ. Ни одна другая запись не имеет ссылки на ее адрес, так что она оказывается эффективно удаленной из цепочки, хотя физически по-прежнему существует. Относительный Номер- Код Ссылка Ссылка номер записи Студента Предмета Семестр на студента на предмет 200 70 2000S 4 5 100 30 2001F 6 7 300 20 2001F 5 4 200 30 2000S 7 2 300 70 2000S 0 0 100 20 2000S 1 3 200 45 2000S 3 1 Начало списка студентов = 2 Начало списка предметов = 6 Рис. А.5. Файл ЗАНЯТИЯ после вставки новой записи (упорядоченный двумя способами с помощью связных списков) Относительный Номер- Код Ссылка Ссылка номер записи Студента Предмета Семестр на студента на предмет 200 70 2000S 7 5 100 30 2001F 6 7 300 20 2001F 5 2 200 30 2000S 7 2 300 70 2000S 0 0 100 20 2000S 1 3 200 45 2000S 3 1 Начало списка студентов = 2 Начало списка предметов = 6 Рис. А.6. Файл ЗАНЯТИЯ после удаления записи о занятиях студента 200 по предмету 30 (упорядоченный двумя способами с использованием связных списков) Есть мною вариантов связных списков. Можно создать кольцевой список (circular list), или кольцо (ring), записав в поле ссылки последней записи вместо нуля адрес первой записи в списке. Теперь можно найти любой элемент в спи- ске, начав с произвольного элемента. На рпс. А.7, а, показан кольцевой список, упорядоченный по полю НомерСтудента Двцсвязиый список (two-way linked list) имеет ссылки в обоих направлениях. На рис. А.7, б, изображен двусвязпып спи- сок, упорядоченный по возрасганию и по убыванию поля НомерСтудента. Записи, упорядоченные посредством связных списков, не могут храниться в файлах с последовательным доступом, гак как для работы со ссылками необхо- дима та или иная форма прямого доступа. Таким образом, для обработки связ- ных списков требуется либо последовательный доступ с индексацией, либо пря- мой доступ.
Приложений А Структуры данным 780 Относительный номер записи Номер- Студента КОД Предмета Семестр Ссылка 1 200 ’ 70 20003 4 2 100 30 2001F 6 3 300 20 2001F 5 4 200 30 2000S 3 5 300 70 2000S 2 6 100 20 2000S 1 Начало списка = 2 Относительный номер записи Номер- Студента £ Код Предмета Семестр Ссылка на список, упорядоченный по возрастанию Ссылка на список, упорядоченный по убыванию 1 200 70 2000S 4 6 2 100 30 2001F 6 0 3 300 20 2001F 5 4 4 200 30 2000S 3 1 5 300 70 2000S 2 3 6 100 20 2000S 1 2 Начало списка, упорядоченного по возрастанию = 2 Начало списка, упорядоченного по убыванию = 5 б Рис. А.7. Файл ЗАНЯТИЯ, упорядоченный по полю НомерСтудента с использованием- а — кольцевого списка; б — двусвязного списка Упорядочение с помощью индексов спи Г1Орядочение записей может также производиться с помощью индек- Wuno XeS ’ ИЛИ’ КЛК ИХ С1ДС назыса,от> инвертированных списков (inverted lists). рС пРслставляе 1 с°бой таблиц}', где значениям некоторого поля сопостав- казпн ! ^"тлиоттГо10*’ содеРжащ,,с эти значения. Например, на рис А.8, а, по- инлрк-г- ИЛ и С неУпоРя^1ОЧенными записями, а на рис. А.8, б, изображен по nor>QHa ПОЛ<? Оме^тУДента- В этом индексе номера студентов расположены в И ДЛЯ каждого номера имеется ссылка на соответствующую запись в исходных данных. ный стп4г°ЖНО Виде1Ь’ инДекс представляет собой не что иное как отсортирован- по полю гГ студентов. Для последовательной обработки файла ЗАНЯТИЯ тая из . °Мер т^дента нУжно просто последовательно обрабатывать индекс, чп- еше плин гш' Записи’ на которые указывают ссылки. На рис. А.8, в. изображен Для тот Дек5.лля Фа,,ла ЗАНЯТИЯ, упорядоченный по полю КодПредмета. должны содержапющТ^йТЛ° Ра6°татЬ с индексами, упорядочиваемые данные доступом хот файле с прямым или индексируемым последовательным , . отя для хранения самих индексов можно использовать любой тип
Плоские файлы 781 файлов. В реальности почти все СУБД хранят и данные, и индексы в файлах прямого доступа. Относительный Номер- Код номер записи Студента Предмета Семестр 200 70 2000S 100 30 2001F 300 20 2001F 200 30 2000S 300 70 2000S 100 20 2000S а Номер- Относительный Студента номер записи 100 2 100 6 200 1 200 4 300 3 300 5 б Номер- Относительный Студента номер записи 20 3 20 6 30 2 30 4 70 1 70 5 в Рис. А.8. Файл ЗАНЯТИЯ с соответствующими индексами: а — файл ЗАНЯТИЯ; б — индекс по полю НомерСтудента; в — индекс по полю НомерГруппы Если сравнить связный список с индексом, между ними обнаружится ко- ренное различие. В связном списке указатели хранятся вместе с данными. Каждая запись имеет поле ссылки, содержащее указатель на следующую по по- рядку запись. При использовании же индексов указатели хранятся отдельно от данных — собственно в индексах. Таким образом, сами по себе данные не содер- жат указателей. В коммерческих СУБД используются оба подхода к хранению указателей. Бинарные деревья Специальным приложением концепции индексов, или инвертированных списков, являются бинарные деревья — многоуровневые индексы, предоставляющие воз- можность как последовательной, так и прямой обработки записей. Благодаря особенностям своей структуры они также обеспечиваю г определенное повыше- ние эффективности обработки. Бинарное дерево — эго индекс, состоящий из двух частей: последователь- ного набора (sequence set) и индексного набора (index set) (Эти термины ис- пользуются в документации компании IBM, описывающей структуру \ S \М- файла Вам могут встретиться н другие, синонимичные, термины.) Последова- тельный набор представляет собой индекс, содержащий указатели на все записи
782 Приложение А. Структу ы данных в файле. Этот индекс физически упорядочен, обычно по значению первичною ключа. Такая структура позволяет обращаться к записям последовательно считывая один за другим адреса записей и 1 последовательного набора и но ним считывая сами записи Индексный набор — это иерархический индекс для последовательного набора Эта структура обеспечивает быстрый доступ к записям в файле. Пример бинарного дерева изображен па рис Л 9, а конкретный экземпляр этой структуры показан на рис. Л.10. Обратите внимание, что нижняя строчка на рис. А.9 - последовательный набор - представляет собой обычный индекс. Он содержит указатель па каждую запись в файле (хотя для краткости данные и ад- реса записей были опушены). Также заметьте, что элементы последовательного набора сгруппированы по три Записи в каждой группе физически упорядочены, и каждая группа связана со следующей с помощью связного списка, как можно видеть на рис. А. 10. Последовательный набор (инвертированный список, указывающий на записи с данными) Рис. А.9. Общая структура простого бинарного дерева Взгляните на индексный набор па рис. Л.9. Верхняя запись содержит два зна- чения — 45 и 77 Следуя левой линии связи (к записи с относительным номе- ром 2), мы можем обратиться к записям, значения ключей которых .меньше или равны 45; следуя средней линии связи, мы можем обратиться к записям, значе- ния ключей которых больше 45 и меньше пли равны 77; наконец, следуя пра- вой линии связи (к записи с относительным номером 4), мы можем обратиться к записям, значения ключей которых больше 77. Аналогичным образом на следующем уровне имеются три значения и три ука- зателя на каждый элемент индекса. Всякий раз, когда мы спускаемся на уровень ниже, мы сужаем область своего поиска. Например, если от верхней записи мы проследуем по левой линии связи, а от следующего уровня — по правой линии, мы сможем обратиться ко всем записям, значения ключей которых больше 27, по меньше или равны 45. На первом уровне мы исключили все записи, значения ключей которых больше 45.
Плоские файлы 783 ОНЗ Ссылка 1 Значение 1 Ссылка 2 Значение 2 Ссылка 3 2 45 3 77 4 101 7 102 27 103 104 53 105 65 106 107 84 108 89 109 Индексный набор R1 Адрес 1 R2 Адрес 2 R3 Адрес 3 Ссылка 101 1 Указатель на 6 3 Указатель на 8 7 Указатель на 12 102 102 10 13 27 103 103 30 35 45 104 104 46 м 47 53 105 Последовательный 105 55 57 65 106 набор (адреса записей с данными опущены) 106 66 73 77 107 107 78 80 84 108 108 86 88 89 109 109 91 92 94 0 Рис. А. 10. Пример бинарного дерева со структурой, соответствующей рис. А.9 Бинарные деревья по определению являются сбалансированными. Это зна- чит, что все записи находятся на одинаковом расстоянии от верхней записи индексного набора. Это свойство бинарных деревьев обусловливает их эф- фективность, хотя алгоритмы вставки и удаления записей оказываются на- много сложнее, чем для обычных деревьев (которые могут быть несбалансиро- ванными), поскольку для того, чтобы при этих операциях сохранить все записи на одинаковом расстоянии, может потребоваться модификация нескольких записей. Резюме по структурам данных На рис. А.11 изображены все методы упорядочения плоских файлов. Для этой це- ли могут применяться три различные структуры данных. Одна из таких структур — последовательный список, но он имеет следующий недостаток: чтобы одновре- менно иметь записи, отсортированные в различном порядке, требуется дублиро- вать данные. В связи с тем, что последовательные списки не используются при работе с базами данных, далее мы их рассматривать не будем. При использовании связных списков и бинарных деревьев дублирования данных не требуется. Бинар- ные деревья являются особым приложением индексов. Как показано на рис А.11, последовательные списки могут храниться в фай- лах с любым принципом доступа. Па практике, однако, обычно они хранятся
784 Приложение А Структуры данных в файлах последовательного доступа. Кроме того, хотя и связные списки, и ин- дексы могут храниться и в файлах последовательного доступа с индексирова- нием, и в файлах прямого доступа, СУБД всегда храпят их в файлах прямого доступа. ---------------Обычно -------------- Редко Рис. А.11. Структуры данных и принципы доступа, используемые для упорядочения плоских файлов Представление бинарных связей В этом разделе мы увидим, каким образом каждый из рассмотренных нами в гла ве шести видов связей между записями (деревья, простые сети и сложные сети; представляется с помощью связных списков и индексов. П •чичи 113 за рбзор видов связей между записями Записи могут быть связаны между собой т ремя способами. Дерево имеет одну или несколько связей «один ко многим», но каждая дочерняя запись имеет не лее одного родителя. Данные сотрудника профессорско-преподавательскою става, показанные на рис. А.12, являют собой пример дерева. Дерево имее^”д сколько связей 1:N, но каждая дочерняя запись, как можно видеть из рис. имеет только одного роди геля.
Представление бинарных связей 785 Рис. А. 13. Схема дерева, описывающего сотрудника ППС Простая сеть — совокупность записей и связей вида 1;N между ними. От- личие простой сети от дерева состоит в том, что в простой сети дочерний узел может иметь более одного родителя, если родители принадлежат различным типам записей. Экземпляр показанной на рис. А. 14 простой сети, состоящей из записей о студентах, их руководителях и специализациях, схематически изо- бражен на рис. А. 15. Рис. А. 14. Пример простой сети
786 Приложение А. Структуры данных Рис. А.15. Общая структура простой сети Сложная сеть также является совокупностью записей и связей между ними, но связи в ней имеют вид «многие ко многим», а не «один ко многим». Связь между студентами и занятиями, которые они посещают, представляет собой сложную сеть. Пример такой связи можно видеть на рис. А. 16, а общую схему — на рис. А. 17. | СТУДЕНТЫ-] | ПРЕДМЕТЬГ, Рис. А. 17. Общая структура сложной сети Ранее мы видели, что связные списки и индексы можно использовать для об- работки записей в порядке, отличном от того, в котором они физически хранят- ся. Эти же структуры данных можно использовать и для хранения и обработки связей между записями. Представление деревьев Деревья могут представляться с помощью последовательных списков, связных списков и индексов. В варианте с последовательными списками приходится дуб- лировать большое количество данных, и кроме того, СУБД не используют после- довательные списки для представления деревьев. 11оэтому речь здесь будет идти только о связных списках и индексах.
Представление бинарных связей 787 Представление деревьев с помощью связных списков На рис. А. 18 показана древообразная структура, в которой записи типа ПОСТАВЩИК являются родителями, а записи типа СЧЕТ — потомками На рис. Л.19 изобра- жены два экземпляра этой структуры, а на рис. А.20 показан последовательный файл, в котором хранятся все записи ПОСТАВЩИК и СЧЕТ. Запись ПОСТАВЩИК АА имеет относительный номер 1, а запись ПОСТАВЩИК ВВ относительный номер 2. Как показано на рисунке, записи типа СЧЕТ расположены одна за другой. Обра- тите внимание. что эти записи никак не упорядочены, п упорядочение здесь не нужно. Рис. А. 18. Пример дерева, связывающего записи ПОСТАВЩИК и СЧЕТ Рис. А.19. Два экземпляра дерева ПОСТАВЩИК-СЧЕТ Номер записи 1 2 3 4 5 6 7 Содержимое записи ПОСТАВЩИК АА ПОСТАВЩИК ВВ 118 99.50 119 8.95 112 18.95 114 27.50 110 127 50 Рис. А.20. Представление деревьев с рис. А.19 в файле Трудность состоит в том, что из этого файла невозможно определить, какие счета пришли от каких пос гашников. Решить эту проблему можно с помощью связного списка. Для этою в каждую запись следует добавить ноле ссылки В >том иоле будет храниться адрес некоторой другой записи, связанной с ней Например, в поле ссылки записи ПОСТАВЩИК АА мы поместим адрес записи, представляющей первый счет ог данного поставщика. Эго запись СЧЕТ 110. имею щая относи тельный номер 7. В поле ссылки ной записи мы поместим указатель на запись, пред< ишляющую следующий счет oi поставщика АЛ, то есть па <а пись СЧЕТ 118 с относительным номером 3. Чтобы показать, что больше потомков
788 Приложение А. Структуры данных в данной цепочке нет. в поле ссылки лапцги с относительным номером 3 МЫ запишем 0. , Пример реализации этого метода показан на рис А 21 Исследован этот ржу нок, вы увидите, что аналогичный набор ссылок использован для представления связен между поставщиком ВВ и счетами от пего. Относительный номер записи Содержимое записи Поле ссылки 1 ПОСТАВЩИК АА 7 2 ПОСТАВЩИК ВВ 5 3 118 99 50 0 4 119 8.95 0 5 112 18 95 6 6 114 27.50 4 7 110 127 50 3 Рис. А.21. Представление деревьев с помощью связных списков В структуру на рис. А.21 намного легче вносить изменения, чем в последова- тельный список записей. Предположим, например, что нам нужно добавить но- вый счет за номером 111, пришедший от поставщика АА. Для этого нужно толь- ко добавить в файл новую запись и вставить ее в связный список. Физически данную запись можно поместить куда угодно. Но куда ее следует поместить логически? Обычно у приложения на этот счет имеется некоторое требование, например такое: потомки должны быть логически упорядочены в порядке воз- растания номера счета. В этом случае запись СЧЕТ НО должна указывать на за- пись СЧЕТ 111 (с относительным номером 8), а новая запись, СЧЕТ 111, должна указывать на запись СЧЕТ 118 (с относительным номером 3). Эти изменения по- казаны на рис. А.22. Относительный номер записи Содержимое записи Поле ссылки 1 ПОСТАВЩИК АА 7 2 ПОСТАВЩИК ВВ 5 3 118 99.50 0 4 119 8.95 0 5 112 18.95 6 6 114 27.50 4 % 7 110 127.50 8 8 111 19.95 3 DL'atiJ Icnriclzi запись Рис. А.22. Файл на рис. А.21 после добавления счета номер 111 Удаление счета происходит так же просто. Чтобы удалить счет номер 114, мы просто изменяем указатель записи, которая в данный момент указывает на за- пись СЧЕТ 114. В данном случае это запись СЧЕТ 112 с относительным номером 5. В поле ссылки этой записи мы записываем значение, которое имел указатель
Представление бинарных связей 789 записи СЧЕТ 114 до ее удаления. Таким образом, запись СЧЕТ 112 теперь указывает па запись СЧЕТ 119 (рис. А.23). Итак, мы исключили одно звено из цепочки и со- единили между собой два других звена, которые оно ранее связывало. Относительный Поле номер записи Содержимое записи ссылки 1 ПОС АВЩИК АА 7 2 ПОСТАВЩИК ВВ 5 3 118 99.50 0 4 119 8.95 0 5 112 18.95 4 Удаленная запись 6 114 27.50 4 7 110 127.50 8 8 111 19.95 3 Рис. А.23. Удаление счета номер 114 из файла на рис. А.22 Представление деревьев с помощью индексов Древообразную структуру можно также представить с помощью индексов. Метод заключается в хранении каждой связи «один ко многим» в виде индекса. По этим спискам далее устанавливается связь между родителем и потомками. Обратившись к записям ПОСТАВЩИК и СЧЕТ на рис. А.21, мы увидим, что запи- си ПОСТАВЩИК АА (с относительным номером 1) принадлежат записи СЧЕТ 110 (относительный номер 7) и СЧЕТ 118 (относительный номер 3). Таким образом, запись с относительным номером 1 является родителем записей с относительны- ми номерами 7 и 3. Данный факт можно представить в виде индекса, изображен- ного на рис. А.24. Этот индекс связывает адрес родителя с адресами каждого из его потомков. Родительская Дочерняя запись запись 1 7 1 3 2 5 2 6 2 4 Рис, А.24. Представление связи ПОСТАВЩИК-СЧЕТ с помощью индексов Если дерево имеет несколько связей 1:N, потребуется несколько индексов, по одному на каждую связь. Для ртруктуры па рис. А.13 потребуется пять ин- дексов Представление простых сетей Как и деревья, простые сети могут быть представлены с помощью связнь х спи- сков и индексов.
790 Приложение А. Структуры данных Представление простых сетей с помощью связных списков Рассмотрим простую сеть на рис. А.25. Во-первых, эта структура действительно является простой сетью, поскольку все связи в ней имеют вид 1:N, а записи типа ДОСТАВКА имеют родителей различных типов. Каждая запись типа ДОСТАВКА име- ет в качестве родителей запись типа КЛИЕНТ и запись типа ГРУЗОВИК. Связь между записями КЛИЕНТ и ДОСТАВКА имеет вид 1:N, поскольку одному клиенту может доставляться несколько заказов. Связь между записями ГРУЗОВИКи ДОСТАВКА также имеет вид 1:N, поскольку различные заказы мо1ут доставляться одним и тем же грузовиком (если считать, что размеры доставляемых товаров достаточно малы, чтобы поместиться на одном грузовике). Экземпляр такой сети показан на рис. А.26. Рис. А.25. Структура простой сети Чтобы представить простую сеть с помощью связных списков, для каждой связи 1:N нужно создать набор указателей. В данном случае это означает, что нужно создать один набор указателей, связывающий записи КЛИЕНТ и ДОСТАВКА, и один набор указателей, связывающий записи ДОСТАВКА и ГРУЗОВИК. Так, напри- мер, запись КЛИЕНТ будет содержать один указатель (на первую связанную с ней запись ДОСТАВКА), запись ГРУЗОВИК будет содержать один указатель (на первую связанную с ней запись ДОСТАВКА), а запись ДОСТАВКА будет иметь два указателя: один — на следующую запись ДОСТАВКА, принадлежащую той же записи КЛИЕНТ, и на следующую запись ДОСТАВКА, принадлежащую тон же записи ГРУЗОВИК. Эта схема изображена на рис. А.27. Простая сеть имеет по меньшей мере две связи 1:N, каждая из которых может быт ь представлена с помощью индекса, как было показано в ходе обсуждения де- ревьев. Рассмотрим, например, простую сеть, изображенную на рис. А.25. Она имеет две связи 1:N: одна между записями ГРУЗОВИК и ДОСТАВКА, а другая - меж-
Представление бинарных связей 791 лу записями ДОСТАВКА и КЛИЕНТ. Каждую из этих связей можно хранить в виде индекса. На рис. А.28 показаны два индекса, с. помощью которых можно предста- вить пример па рис. А.26 Будем предполагать, что записи находятся на тех же позициях, что и па рис. А.27. Относительный номер записи 1 2 3 4 5 6 7 8 9 10 Содержимое записи Поля ссылок сю 6 С20 7 Т1 6 Т2 9 ТЗ 8 S100 9 7 S200 8 0 S300 10 10 S400 0 0 S500 0 0 Ссылки Ссылки на клиентов на грузовики Рис. А.27. Представление простой сети с помощью связных списков Запись Запись о клиенте о доставке 1 6 1 9 2 7 2 8 2 10 Запись Запись о машине о доставке 3 6 3 7 4 9 5 8 5 10 Рис. А.28. Представление простой сети с помощью индексов Представление сложных сетей Сложные сети могут быть представлены множеством способов. Их можно разбиват ь на деревья или простые сети, а уже эти простые структуры щк'дставлягь с помощью одной из рассмотрепных только что методик. Кроме того, их можно пре цтавлягь непосредственно с помощью индексов. Связные списки нс используются СУБД для прямою представления сложных сетей. На практике сложные сети почти все тда разбиваются па более простые структуры, поэтому далее мы бу тем рассмат- ривать только такие представления. Распространенный подход к представлению сложной сети состоит в приве- дении се к простой сети и последующем представлении получившейся простой сети < помощью связных списков или индексов. Обратите, однако, внимание, что т пяти в сложной сети соединяют между собой две записи, а в простой септ — три
792 Приложение А. Структуры данных записи. Поэтому, чтобы преобразован. сложную сеть и ир«лтую, Т|кгбупся соз- дать третий тип записи. Запись, создаваемая при преобразовании сложной сети и простую, называется записью пересечения (intersection record). Рассмофим сложную сеть, отражаю щую посещение занятий студентами. Запись пересечения будет содержать уни кальный ключ записи СТУДЕНТ и уникальный ключ соответствующей ей записи ПРЕДМЕТ. Запись пересечения нс будет содержать никаких других данных прило- жения, хотя в ней могут быть поля ссылок. Общая структура эюй связи пока- зана на рис. А.29. Экземпляр связи СТУДЕНТ-ПРЕДМЕТ представлен на рис. АЗО (здесь предполагается, что имена записей, обозначенные С1, 31 и т. д„ являются уникальными). Рис. А.29. Преобразование сложной сети в простую
Предст вление бинарных связей 793 * > »' * < Обратите внимание, что связь записей СТУДЕНТ и ПРЕДМЕТ с записью пересече- ния имеет вид 1:N. Таким образом, мы создали простую сеть, которую можно представить с помощью связных списков или индексов, как было показано ра- нее. Файл с примером такой простой сети, для представления которой использу- ются связные списки, изображен на рис. А.31. Относительный номер записи 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Содержимое записи Поле ссылки S1 9 S2 12 S3 17 ci 9 С2 13 сз 10 С4 15 С5 11 S1C1 10 12 S1C3 11 14 S1C5 ' 0 16 S2C1 13 17 S2C2 14 0 S2C3 15 18 S2C4 16 19 S2C5 0 20 S3C1 18 0 S3C3 19 0 S3C4 20 0 S3C5 0 0 Ссылки Ссылки на студентов на предметы Рис. А.31. Пример сети со структурой, соответствующей рис. А.ЗО Резюме по представлению связей На рис. А.32 изображены все способы представления связей между записями. Деревья могут быть представлены с помощью последовательных списков (хо- тя мы не обсуждали этот подход), связных списков или индексов. Последова- тельные списки не используются в СУБД. Простую сеть можно разбить на деревья и затем представить с помощью соответствующих структур данных, а можно представить непосредственно с помощью связных списков или ин- дексов Сложную сеть можно преобразовать в дерево или в простую сеть (с по- мощью записей пересечения) либо представить непосредственно с помощью индексов
794 Приложение А. Структуры данных Вид связи между записями Структуры данных Принцип доступа к файлу ----------Обычно ---------Редко Рис. А.32. Представление связей между записями с помощью различных структур данных и принципов доступа Представление вторичных ключей Во многих случаях термином ключ обозначается одно или несколько полей, уни- кальным образом идентифицирующих запись. Такой ключ обычно называется первичным ключом. Но иногда приложениям нужно обращаться к записям и обра 6ai ывагь их по вторичному ключу, который обладает иными свойствами, чем нер вичиып. Вторичный ключ может быть уникальным (например, имя преподаваге 1я) пли неуникальным (например, почтовый индекс клиента). В этом разделе гермином множество (set) мы будем обозначать все записи, имеющие одина- ковое значение иеуннкального вторичного ключа, например множество записей, в которых поле Индекс имеет значение 98040. Для представления вторичных ключей можно использовать и связные списки, и индексы. Ио связные списки пригодны только в случае неуникальных ключей.
Представление вторичных ключей 795 тогда как индексы могут использоваться для представления как уникальных, так и неуникальных ключей. Представление вторичных ключей с помощью связных списков Рассмотрим файл КЛИЕНТ, структура которого показана на рис. А.ЗЗ. Первичным ключом является НомерСчета; есть также вторичный ключ, МаксимальныйКредит. Возможные значения поля МаксимальныйКредит — 500, 700 и 1000. Таким обра- зом, у нас будет три набора записей: с максимальным кредитом 500, 700 и 1000. НомерСчета Имя Адрес МаксимальныйКредит ОстатокНаСчете ПервичныйКлюч ВторичныйКлюч Рис. А.ЗЗ. Структура файла КЛИЕНТ Чтобы представить этот вторичный ключ с помощью связных списков, доба- вим в структуру файла КЛИЕНТ поле ссылки. В этом поле ссылки мы создадим связный список для каждого набора записей. На рис. А.34 показана база данных с одиннадцатью клиентами, где для краткости показаны только поля НомерСчета и МаксимальныйКредит. К каждой записи добавлено поле ссылки. Предположим, что каждая запись в базе данных соответствует одной физической записи в фай- ле прямого доступа, использующем относительную адресацию записей. Относительный номер записи Ссылка Номер- Счета Максимальный- Кредит Прочие- данные 1 2 101 500 НАЧАЛО-500 = 1 НАЧАЛО-700 = 3 НАЧ А Л О-1000. = 4 2 7 301 500 3 5 203 700 4 6 004 1000 5 10 204 700 6 8 905 1000 7 0 705 500 8 9 207 1000 9 11 309 1000 10 0 409 700 11 0 210 1000 Рис А.34. Представление вторичного ключа МаксимальныйКредит с помощью связного списка Чтобы знать, где начинается каждый связный список, нужны три указателя. Каждый такой указатель называется оливой списка (head) и хранится отдельно отданных. Головой связного списка покупателей с максимальным кредитом $500 является запись с относительным номером 1. Запись 1 указывает на запись 2,
796 Приложение А. Структуры данных которая, в свою очередь, указывает па запись 7. Запись 7 имет нулевое значе нпе в поле ссылки, указывающее па то, чю это конец списка. Следовательно, множество записей клиентов с максимальным кредитом $500 состоит из записей с относительными номерами 1, 2 и 7. Аналогичным образом множество записей клиентов с максимальным кредитом $700 состоит из записей с относительными номерами 3, 5 и 10, а множество записей клиентов с максимальным кредитом $1000 состоит из записей с относительными номерами 4, 6, 8, 9 и И. Возьмем для примера запрос «Сколько счетов с максимальным кредитом $1000 имеют баланс, превышающий $900?». Чтобы ответить на подобный запрос, мож- но использовать связный список записей с максимальным кредитом $1000. При этом считывать из файла и обрабатывать нужно только те записи, которые при- надлежат множеству с максимальным кредитом $1000. Хотя преимущество это- го подхода не ощущается явно в этом небольшом примере, представьте, что есть 100 000 записей КЛИЕНТ, и только 100 из них принадлежат искомому множеству. Если бы связного списка не было, пришлось бы провести поиск по всем 100 000 записям; при наличии же связного списка требуется обработать только 100 запи- сей, а именно записи из множества с максимальным кредитом $1000. Таким об- разом, использование связного списка экономит 99 900 операций чтения. Подход с использованием связных списков для представления вторичных клю- чей не всегда эффективен. В частности, если записи в наборе обрабатываются не по порядку, связные списки оказываются неэффективными. Например, если час- то требуется найти 10-, 120- или и-ю запись в множестве с максимальным креди- том $500, обработка будет идти медленно. При прямом доступе связные списки неэффективны. Кроме того, если приложение требует, чтобы вторичные ключи создавались и разрушались динамически, использование связных списков нежелательно. Всякий раз, когда создается новый ключ, к каждой записи необходимо добавить поле ссылки, для чего зачастую необходимо реорганизовать всю базу данных, а это требует больших затрат времени и средств. Наконец, если вторичные ключи имеют уникальные значения, то длина каждого списка будет равна 1, и для каждой записи в базе данных будет иметься отдель- ный связный список. Поскольку работа в такой ситуации невозможна, связные списки нельзя использовать для представления уникальных ключей. Предполо- жим, например, что файл КЛИЕНТ содержит еще одно поле с уникальным значе- нием — например, НомерСоциальнойСтраховки. Если мы попытаемся представить этот уникальный вторичный ключ с помощью связного списка, то каждый номер социальной страховки будет отдельным связным списком. Более того, каждый связный список будет иметь всего одни элемент — запись, содержащую данный номер социальной страховки. Представление вторичных ключей с помощью индексов Второй способ представления вторичных ключей — это использование индексов. Для каждом ггоричного ключа создается своп индекс. Конкретная реализация этого подхода зависит от того, являются ли значения ключей уникальными.
Представление вторичных ключей 797 Случай уникальных вторичных ключей Предположим, что файл ЗАПИСЬ (см. рис. А.ЗЗ) помимо показанных на рисунке полей содержит поле НомерСоциальнойСтраховки, являющееся вторичным ключом. Чтобы обеспечить доступ к записям в файле по полю НомерСоциальнойСтраховки, нужно просто построить индекс по этому полю. Данные для примера показаны на рис. А.35, а, а соответствующий индекс — на рис. А.35, б. В этом индексе записи адресуются по их относительным номерам Можно было бы для этой цели ис- пользовать поле НомерСчета; в этом случае СУБД находила бы в индексе нужный номер социальной с траховки, получала бы соответствующий номер счета, а затем определяла бы по нему относительный адрес записи. Номер Относительный Номер- Максимальный- социальной номер записи 1 2 3 4 Счета Кредит страховки 101 500 000-01-0001 301 500 000-01-0005 203 700 000-01-0009 004 1000 000-01-0003 а Рис. А.35. Представление уникального вторичного ключа с помощью индексов: а — пример файла КЛИЕНТ (с номером социальной страховки); б — индекс для вторичного ключа НомерСоциальнойСтраховки Случай неуникальных вторичных ключей Индексы могут также использоваться для представления пеунпкальных вторич- ных ключей, но, поскольку каждое множество связанных записей может содер- жать неизвестное число элементов, записи в индексе имеют переменную длину. Например, на рис. А.36 показан индекс множеств с различным максимальным кредитом для файла КЛИЕНТ Каждое из множеств с максимальным кредитом $500 и $700 состоит из трех элементов, поэтому соответствующие записи в ин- дексе содержат ио три номера счета. Множество с максимальным кредитом $1000 состоит из пяти элементов,, поэтому запись индекса для этого множества содер- жит пять номеров < чеюв. В реальности представление и обработка пеунпкальных ключей представляют собой сложные задачи Коммерческие СУБД применяют для этих целей несколь- ко (Куличных схем В одном популярном методе используются таблица значений
798 Приложение А С <ру*>уры данных (values table) и таблица вхождении (occuneiue table) каждая mumt значений cwwur на двух полей, первое in которых содержи ( ятачение Ключ МаксимальныйКредит файла КЛИЕНТ имеет три нмчеция 500, 700 и 1000 Второе ноле записи в таблице значений предо виляет тобой укайте <ь Назаитич, в таблице вхож teuiui. Таблица вхождении содержи! адреса записей, и те из иии_ которые имеют одно и то же аиачеппе вторичною ключа, расположены и одной строке таблицы. На рис. А.37 изображены таблица значений и таблица в нпп для ключа МаксимальныйКредит. ,, , НомерСчета Максимапьный- Кредит <------------------- 500 101 301 705 700 203 204 409 1000 004 905 207 309 210 Рис. А.36. Индекс для ключа МаксимальныйКредит с рис А 33 <Я1 Таблица значений Таблица вхождений НомерСчета Рис. А.37. Таблица значений и таблица вхождений для ключа МаксимальныйКредит с рис. А.ЗЗ Для нахождения записей с заданным значением вторичного ключа произво- дится поиск этого значения в таблице значении. Когда нужное значение найде- но, по указателю в таблице вхождении находятся адреса записей, имеющих дан- ное значение ключа. Когда в файл добавляется новая запись, СУБД должна обновить индексы для каждого ноля вторичного ключа. В случае неуникальных ключей она должна сначала убедиться, что значение ключа новой записи присутствует в таблице значений. Если это так, СУБД добавляет адрес, новой записи в соответствующую строку таблицы вхождений. Если такого значения нет, СУБД должна добавить новую запись в таблицу значении и в таблицу вхождений. При удалении записи ее адрес должен быть удален пз таблицы вхождении. Если в строке таблицы вхождений не остается пн одного адреса, соответствующее значение вторичного ключа должно быть также удалено пз таблицы значении. Когда изменяется значение поля вторичного ключа записи, адрес згой записи должен быть удален из одной строки таблицы вхождений и добавлен в другую. Если изменение заключается в присваивании ключу нового значения, в та гшцу значении необходимо добавить соответствующую запись. Подход с использованием индексов для представления вторичных ключей преодолевает ограничения, которыми характеризуется подход с использованием Ре в» ла сот аш ТТЛ aoi оа <х» * -Ч
Резюме 799 связных списков. Во-первых, возможна непосредственная обработка множеств. Например, можно сразу получить третью запись из множества, не обрабатывая первую и вторую. Кроме того, можно динамически создавать и уничтожать вто- ричные ключи. Никаких изменений в самих записях не делается: вместо этого СУБД создает дополнительные таблицы — таблицу значений и таблицу вхожде- ний. Наконец, возможна эффективная обработка уникальных ключей. Недостатки этого подхода заключаются в том, что он требует большего объ- ема файлового пространства (на таблицы расходуется больше избыточного про- странства, чем на указатели), и в том, что программирование СУБД оказывается более сложным. Обратите внимание: прикладное программирование не обязатель- но будет в этом случае проще или сложнее; просто программное обеспечение для СУБД, обрабатывающее индексы, написать сложнее, чем программное обеспече- ние, обрабатывающее связные списки. Наконец, обработка обновлений обычно происходит медленно из-за операций чтения и записи, требуемых для доступа к значениям в таблице вхождений и пх поддержания. Резюме В этом приложении мы рассмотрели структуры данных, используемые в базах данных. Плоский файл — это файл, не содержащий повторяющихся групп. Пло- ские файлы могут быть упорядочены с использованием последовательных спи- сков (путем физического упорядочивания записей в необходимой последова- тельности), связных списков (путем добавления к каждой записи указателя на другую логически связанную с ней запись) и индексов (путем построения отдель- ной от данных таблицы, содержащей указатели на связанные записи). Бинарные деревья представляют собой специальное приложение индексов. Последовательные списки, связные списки и индексы (или инвертированные списки) являются фундаментальными структурами данных. (Хотя последова- тельные списки редко используются при обработке баз данных.) С помощью этих структур можно представлять связи между записями, а также вторичные ключи. Три основные структуры связей между записями — деревья, простые сети и сложные сети — могут быть представлены с помощью связных списков и ин- дексов. Простую сеть можно разбить па деревья и затем представить с помощью соответствующих структур данных; сложную сеть можно преобразовать в про- стую сеть, содержащую записи пересечения, и затем представить теми же спосо- бами, что и простую сеть. Вторичные ключи используются для доступа к данным по значениям некото- рых полей, отличных от поля первичного ключа. Вторичные ключи могут быть уникальными и неупикальпыми. Неунпкальпые вторичные ключи могут быть представлены с помощью связных списков или индексов. Уникальные вторич- ные ключи могут быть представлены только с помощью индексов.
800 Приложение А Струкгу| ы данных Вопросы группы I 1. Дайте определение плоского файла. Приведите пример (огличомй от лхм ного в тексте) плоского файла и файла, не яилякшито» я и к», ним 2. Покажите, как орг.ши юнать хранение данных в файле из вопроса I одно- временно в двух различных порядках с помощью нот тедовательных спи сков. 3. Покажите, как организовать храпение данных в файле из вопроса 1 одно* временно в двух различных порядках с помощью связных списков. 4. Покажите, как организовать храпение данных в файле из вопроса 1 одно- временно в двух различных порядках с помощью инвертированных спи- сков. 5. Дайте определение дерева и приведите пример этой структуры. 6. Изобразите экземпляр дерева со структурой, определенной в ответе на во- прос 5. 7. Представьте экземпляр дерева из ответа на вопрос 6 с помощью связных списков. 8. Представьте экземпляр дерева из ответа на вопрос 6 с помощью индексов. 9. Дайте определение простой сети и приведите пример этой структуры. 10. Изобразите экземпляр простой сети со структурой, определенной в ответе на вопрос 9. И. Представьте экземпляр простой сети из ответа на вопрос 10 с помощью связных списков. 12. Представьте экземпляр простой сети из ответа на вопрос 10 с помощью индексов. 13. Дайте определение сложной сети и приведите пример этой структуры. 14. Изобразите экземпляр сложной сети со структурой, определенной в ответе на вопрос 13. 15. Преобразуйте сложную сеть из ответа иа вопрос 14 в простую сеть и пред- ставьте экземпляр такой сети с использованием индексов. 16. Объясните разницу между первичным и вторичным ключами. 17. Объясните разницу между уникальным и неуникальным ключами. 18. Определите структуру файла с уникальным вторичным ключом. Представь- те экземпляр такого файла с помощью индекса по вторичному ключу. 19. Определите неуникальный вторичный ключ для файла из ответа на во- прос 18. Представьте экземпляр этого файла с помощью связного списка ио вторичному ключу. 20. Выполните то же самое, что и в вопросе 19, но с использованием индекса по вторичному ключу.
Вопросы группы II 801 Вопросы группы II 21. Разработайте алгоритм, создающий для каждого из предметов список идентификаторов всех студентов, занимающихся по данному предмету, используя структуру со связным списком, показанную па рис. А.4. 22. Разработайте алгоритм, добавляющий новые записи в структуру на рис. А.4. Результирующая структура должна быть похожа на ту, которая изображе- на на рпс. А.5. 23. Разработайте алгоритм, создающий для каждого из предметов список идентификаторов всех студентов, занимающихся по данному предмету, используя структуру с индексом, показанную на рис. А.8, а-в. 24. Разработайте алгоритм, добавляющий новые записи в структуру на рис. А.8, а, который модифицировал бы оба соответствующих индекса на рис. А.8, б и в. 25. Разработайте алгоритм, удаляющий записи из структуры на рис. А.34, где изображен вторичный ключ, представленный с помощью связного списка. Если будут удалены все записи для одной из кредитных категорий (на- пример, с максимальным кредитом $1000), следует ли также удалять голо- ву соответствующего списка? Обоснуйте свой ответ. 26. Разработайте алгоритм, добавляющий новую запись в структуру, показан- ную на рис. А.34. Предположим, что новая запись имеет иное значение максимального кредита, чем остальные записи. Следует ли добавить эту запись и создать новый связный список? Или следует отказать во вставке этой записи? Кто должен принимать это решение?
Приложение Б Семантическая объектная модель В этом приложении обсуждается семантическая объектная модель (semantic object model), которая, так же как и модель «сущность—связь», описанная в гла- вах 2 и 3, используется для моделирования данных. Как показано на рис. Б 1, команда разработчиков опрашивает пользователей, анализирует предостав- ленные ими отчеты, формы и запросы и на их основе сгроиг пользовател модель данных. Эта модель данных в дальнейшем воплощается в структуре базы данных. Конкретная форма модели данных зависит от конструкций, используемых для ее построения. Если используется модель «сущность—связь», конструируе- мая модель будет содержать сущности, связи и т. п. В случае использования се- мантической объектной модели конструируемая модель будет содержать семан- тические объекты и связанные с ними конструкции, которые описываются здесь. Модель «сущность—связь» и семантическая объектная модель подобны двум различным линзам, сквозь которые смотрят разработчики баз данных при изуче- нии и документировании пользовательских данных. Обе линзы действуют, и обе они в конечном счете воплощаются в определенной структуре базы данных. Од- нако, поскольку эти линзы не одинаковы и создают разные изображения, струк- туры баз данных, полученных с их помощью, могут несколько различаться. Раз- рабатывая базу данных, вы должны решить, какой подход применять, так же как фотографу приходится решать, какую использовать линзу. Каждый подход име- ет свои сильные и слабые стороны, которые мы обсудим в конце приложения. Семантическая объектная модель была впервые представлена в третьем изда- нии этой книги в 1988 году. Она основана на концепциях, разработанных и опуб- ликованных Коддом, Хаммером и Мак-Леодом1. Семантическая объектная мо- Д^-'1Ь это модель данных. Ее не следует путать с объектно-ориентированной о ра откол оаз данных, обсуждавшейся в главе 16. Вы узнаете, чем цели, свойст- ва и конструкции семантической объектной модели отличаются от объектно-ори- ентированных баз данных. R^ationa* Model to Capture More Meaning», ACM Transactions on Database wi l^DM A S t 3197~424= Michapl Ha""«er and Dennis McLeod, «Database Description p 351-386 cnian lc atabase Model», ACM Transactions on Database Systems, September 1981,
Семантические объекты 803 Семантическая объектная модель Рис. Б.1. Использование различных моделей при разработке баз данных Семантические объекты Задача приложения базы данных состоит в том, чтобы предоставлять формы, от- четы и запросы, с помощью которых пользователи могли бы отслеживать сущно- сти или объекты, представляющие интерес для их деятельности. Целью ранних стадий разработки базы данных является определение того, какие вещи должны быть представлены в базе данных, задание характеристик этих вещей и установ- ление связи между ними. В главах 2 и 3 мы называли эти вещи сущностями. В этой главе мы будем их называть семантическими объектами (semantic objects), а иногда просто объектами. Слово семантический означает «смысловой!», и семантический объект — это объект, который в определенной степени моделирует смысл пользовательских данных. Семантические объекты моделируют восприятие пользователя более точно, чем модель «сущность—связь». Мы испо п>зусм со словом объект прилагательное се- мантический, чтобы отличать объекты, о которых идет речь в этой главе, от объек- тов, которыми оперируют объектно-ориентированные языки программирования. Определение семантических объектов Сущности и объекты в некоторых oi ношениях схожи, по у них есть н различия Мы начнем со ходе тиа Ссмаптнчел кип объект — это представлен не некоторой вещи, идентифицируемой в рабочей среде пользователя Если выражаться более формально, семаитическин объект — это именованная совокупность атрибутов, которая в достаточной степени описывает отдельный феномен.
804 Приложение Б. Семантическая объектная модель Подобно сущностям, семантические объекты группируются л классы У объ- ектного класса есть имя, которое отличает его от других классов и соответствует именам вещей, представляемых этим классом. Так, в базе данных, содержащей информацию о студентах, имеется объектный класс под названием СТУДЕНТ Об- ратите внимание, что имена объектных классов, как и имена классов сущностей, пишутся прописными буквами. Отдельный семантический объект представляет собой экземпляр класса. Например, Уильям Джонс является экземпляром класса СТУДЕНТ, а Бухгалтерия является экземпляром класса ОТДЕЛ. Подобно сущностям, объект имеет набор атрибутов. Каждый атрибут описы- вает одну из характеристик представляемого феномена. Например, объект СТУДЕНТ может иметь атрибуты Имя, ДомашнийАдрес, МестныйАдрес, ДатаРождения, ДатаОкон- чанияШколы и Специальность. Этот набор атрибутов также является достаточным описанием (sufficient description), то есть он описывает все характеристики, необ- ходимые пользователям для работы. Как было указано нами в конце главы 3, каж- дая вещь в мире имеет бесконечное множество характеристик, и мы не в состоя- нии представить всю их совокупность. Вместо этого мы представляем только те из них, которые требуются для удовлетворения информационных потребностей пользователей в той степени, чтобы они могли успешно выполнять свои функ- ции. Достаточность описания означает также, что объекты являются самодоста- точными. Например, все требуемые данные о покупателе содержатся в объекте КЛИЕНТ так что нам не требуется больше нигде искать, чтобы найти эти данные. Объекты представляют отдельные феномены (distinct identity), то есть в вос- приятии пользователей они являются чем-то независимым и самостоятельным, что требует учета. Феномены — это вещи, о которых нужна информация. Чтобы лучше уяснить значение термина отдельный феномен, вспомните, что существу- ет разница между объектами и экземплярами объектов. КЛИЕНТ — это имя объек- та, а КЛИЕНТ 12345 — имя экземпляра объекта. Когда мы говорим, что объект представляет отдельный феномен, мы имеем в виду, что пользователи считают каждый экземпляр объекта уникальным и имеющим самостоятельное значение. Наконец, стоит отметить, что феномены, представляемые объектами, могут существовать физически, как, например, объекты класса СОТРУДНИК, а могут и не существовать, как объекты класса ЗАКАЗ. Заказ как таковой является моделью контрактного соглашения о поставке товаров или предоставлении услуг в установ- ленном порядке и па известных условиях. Он является не физическим предме- том, а представлением соглашения. Таким образом, чтобы нечто могло считаться ооъектом, ему не обязательно существовать физически — нужно лишь, чтобы это нечто имело самостоятельное значение в представлении пользователей. Атрибуты Семан 1 ические объекты имеют атрибуты, описывающие их характеристики. Есть три типа атрибутов. Простые атрибуты (simple attributes) состоят из одного эле- менга. Примерами могут быть атрибуты ДатаНайма, НомерНакладной и Итоговая- СуммаПродаж. Групповые атрибуты (group attributes) являют собой совокупности других атрибутов. В качестве примера можно привести атрибут Адрес, состоящий
Семантические объекты 805 из атрибутов {Улица, Город, Штат, Индекс}. Еще один пример — атрибут ПолноеИмя, включающий в себя атрибуты {Имя, Отчество, Фамилия}. Семантические объектные атрибуты (semantic object attributes) — это атрибуты, которые устанавливают связь между двумя семантическими объектами. Чтобы лучше понять эти определения, взгляните па рис. Ь.2, а, который пред- ставляет собой пример семантической объектной диаграммы (semantic object diagram), или просто объектной диаграммы (object diagram). Такие диаграммы используются командами разработчиков для описания и визуального представ- ления структуры объектов. Объекты изображаются в вертикальных прямоуголь- никах Имя объекта указывается вверху, а атрибуты записываются по порядку после имени объекта. Объект КАФЕДРА содержит пример каждого из трех типов атрибутов. Атрибу- ты НазваниеКафедры, НомерТелефона и НомерФакса являются простыми: каждый из них представляет один элемент данных. МестныйАдрес — групповой атри- бут, состоящий из простых атрибутов Корпус и НомерОфиса. Наконец, КОЛЛЕДЖ, ПРЕПОДАВАТЕЛЬ и СТУДЕНТ это семантические объектные атрибуты, то есть эти объекты связаны с объектом КАФЕДРА и логически содержатся в нем. Смысл этих объектных атрибутов, или объектных ссылок (object links), как их иногда называют, состоит в том, что когда пользователь думает об определенной кафедре, он имеет в виду не только название кафедры, ее местный адрес, номер телефона и номер факса, ио также колледж, в котором она находится, профес- соров, преподающих на ней, и студентов, занимающихся на ней. Поскольку КОЛЛЕДЖ, ПРЕПОДАВАТЕЛЬ и СТУДЕНТ также являются объектами, полная модель данных содержит диаграммы и для них. Объект КОЛЛЕДЖ несет в себе атрибуты колледжа, объект ПРЕПОДАВАТЕЛЬ — атрибуты членов профессорско-преподава- тельского состава, а объект СТУДЕНТ содержит атрибуты студентов. КАФЕДРА ID Название кафедры МестныйАдрес — Корпус НомерОфиса НомерТелефона НомерФакса КОЛЛЕДЖ [^подаватель] Q СТУДЕНТ КАФЕДРА ID Название кафедры МестныйАдрес — Корпус 1.1 НомерОфиса 1, _ 01 НомерТелефона 1.N НомерФакса 0.1 СТУДЕНТ |i.n Рис. В.2. Диаграмма объекта КАФЕДРА: а — объект КАФЕДРА; С - объект КАФЕДРА с кардинальными числами
806 Приложение Б. Семантическая объектная модель Кардинальное число атрибута Каждый атрибут семантического объекта имеет максимальное и минимальное кардинальные числа Минимальное кардинальное число показывает количество экземпляров атрибута, которые должны существовать, чтобы объект был допус тимым. Обычно это число равно 0 или 1. Если оно равно 0, атрибут не обязан иметь значение, а если 1, то обязан. Хотя это и необычно, минимальное кардиналь- ное число иногда может быть больше единицы. Например, атрибут Игрок в объекте под названием БАСКЕТБОЛЬНАЯ_КОМАНДА может иметь минимальное кардиналь- ное число, равное 5, поскольку таково наименьшее число игроков, требуемое для создания баскетбольной команды Максимальное кардинальное число показывает максимальное количество эк- земпляров атрибута, которое может иметь объект. Обычно оно равно 1 или N. Если оно равно 1, атрибут может иметь не более одного экземпляра; если оно равно N, атрибут может иметь много экземпляров, и предельное количество не задано. Иногда максимальное кардинальное число равно определенному числу, например 5, — это означает, что объект может иметь не более пяти экземпляров атрибута. Например, атрибут ИГРОК в объекте БАСКЕТБОЛЬНАЯ_КОМАНДА может иметь максимальное кардинальное число, равное 15, и это будет значить, что в состав команды может быть включено не более 15 игроков Кардинальность изображается в виде нижнего индекса атрибута в формате N.M, где N — минимальное кардинальное число, а М — максимальное. На рис. Б.2, б, минимальное кардинальное число для атрибута НазваниеКафедры равно 1, и мак- симальное — также 1; таким образом, требуется ровно один экземпляр этого атри- бута. Кардинальность атрибута НомерТелефона равна 1.N, то есть кафедра обязана иметь по крайней мере один номер телефона, но в принципе номеров у нее может быть много. Кардинальность 0.1 у атрибута НомерФакса означает, что кафедра может не иметь факса, а может и иметь, но только один. Кардинальные числа групп и атрибутов групп, как правило, невелики. Возь- мем атрибут МестныйАдрес. Его кардинальность 0.1, то есть кафедра не обязана иметь адрес, но если имеет, то только один. Теперь рассмотрим простые атрибуты, из которых состоит атрибут МестныйАдрес. Как Корпус, так и НомерОфиса имеют кардинальность 1.1. Вы можете удивиться, как группа может быть необязатель- ной, если атрибуты, составляющие эту группу, являются обязательными. Дело в гом, что кардинальные числа действуют только между атрибутом и его контей- нером (группой, содержащей этот атрибут). Минимальное кардинальное число атрибута МестныйАдрес показывает, что этот атрибут не обязан иметь значение, го есть кафедра не обязана иметь адрес. А минимальные кардинальные числа атрибутов Корпус и НомерОфиса показывают, что эти атрибуты должны сущест- вовать в группе МестныйАдрес. Таким образом, группа МестныйАдрес не обязана существовать, но если уж она существует, то составляющие ее атрибуты Корпус и НомерОфиса должны иметь значения. Экземпляры объектов Объектные диаграммы для кафедры, показанные на рис. Б.2, представляют собой просто формат, общую структуру, которую можно отнести к любой кафедре.
Семантические объекты 807 На рис. Б.З представлен экземпляр объекта КАФЕДРА. Здесь указаны значения каждого атрибута конкретной кафедры. Кафедра имеет название «Информаци- онные системы» и расположена в офисе № 213 корпуса социальных наук. Обра- тите внимание, что атрибут НомерТелефона имеет три значения: в офисе кафедры информационных систем имеются три телефонные линии. Другие кафедры могут иметь меньшее или большее количество телефонов, но у каждоЯ кафедры ес ь по крайней мере один телефон. Информационные системы Корпус социальных наук 213 493-0100 491-0099 491-1182 491-0098 Название кафедры МестныйАдрес НомерТелефона НомерФакса КОЛЛЕДЖ ПРЕПОДАВАТЕЛЬ СТУДЕНТ Рис. Б.З. Экземпляр объекта КАФЕДРА с рис. Б.2 Далее, имеется один экземпляр атрибута КОЛЛЕДЖ, со значением «Колледж биз- неса», и множество экземпляров объектных атрибутов ПРЕПОДАВАТЕЛЬ и СТУДЕНТ. Каждый из этих объектных атрибутов является полноценным объектом и имеет все атрибуты, определенные для объекта данного типа. Чтобы нс усложнять диа- грамму, мы указали на ней только имена экземпляров объектных атрибутов. Объектная диаграмма — это картина восприятия пользователем объекта в ра- бочей среде. Таким образом, в воображении пользователя объект КАФЕДРА содер- жит все эти данные. Кафедра логически содержит данные о колледже, которо- му она принадлежит, а также о профессорах и студентах, относящихся к этой кафедре. Парные атрибуты В семантической объектной модели пет однонаправленных связей между объек- тами Если один объект содержит в себе другой объект, то этот другой будет, в свою очередь, содержать в себе первый. Например, если объект КАФЕДРА содер- жит в себе объектный атрибут КОЛЛЕДЖ, го н объект КОЛЛЕДЖ будет содержать соответствующий объектный атрибут КАФЕДРА. Эти объектные атрибуты называ- ются иногда парными атрибутами (paired attributes), так как они всегда появля- ются но два
808 Приложени Б семантическая объектная модель Почему объектные атрибуты должны быть парными? Ответ ио ьтм способе каким человеческие сущее чиа предсгаиляюг себе связи между обьегга mi Если объект А имеет связь с объектом Б, то объект Б будет иметь связь с объ- ектом А Но крайней мере. Б связан с А как с «вещью, которая связана с 6. Если этот аргумент кажется неочевидным. попробуйте «юбразить однонаправленную связь между объектами. Это сделать невозможно. Объектные идентификаторы Объектный идентификатор (object identifier) - это один или несколько объект ных атрибутов, с помощью которых пользователи идентифицируют экземпляры объектов. Такие идентификаторы представляют собой потенциальные имена се- мантического объекта. Для объекта КЛИЕНТ возможными идентификаторами яв- ляются НомерКлиента н ИмяКлиента. Каждый из этих идентификаторов является атрибутом, рассматриваемым пользователями в качестве допустимого имени для экземпляров объектного класса КЛИЕНТ. Сравните эти идентификаторы с атрибу- тами ДатаПервогоЗаказа, КурсАкций или ЧислоСотрудников. Такие атрибуты не яв- ляются идентификаторами, потому что пользователи не думают о них как об име- нах экземпляров объектов класса КЛИЕНТ. Групповой идентификатор (group identifier) — это идентификатор, содержа- щий более одного атрибута. Примерами могут служить идентификаторы {Имя. Фамилия}, {Имя. НомерТелефона} и {Штат, НомерЛицензии}. Объектные идентификаторы могут быть уникальными или неуникальными, в зависимости от того, как пользователи представляют себе свои данные. Напри- мер, НомерСчета является уникальным идентификатором объекта ЗАКАЗ, но Имя- Студента не является уникальным идентификатором объекта СТУДЕНТ. Может быть два студента по имени, к примеру, Мэри Смит. В таком случае пользователи бу- дут идентифицировать с помощью атрибута ИмяСтудента группу из одного или более; студентов, и затем, если необходимо, использовать значения других атри- бутов для указания конкретного члена этого множества. В семантических объектных диаграммах объектные идентификаторы обозна- чаются с помощью букв ID перед атрибутом. Если идентификатор является уни- кальным, эти буквы подчеркнуты. На рис. Б.2, б, например, атрибут НазваниеКа- федры является уникальным идентификатором объекта КАФЕДРА. Обычно, если атрибут должен использоваться в качестве идентификатора, он обязан иметь значение. Кроме того, как правило, для данного объекта имеется не более одного идентифицирующего атрибута. Поэтому в большинстве случаев кардинальность атрибута-идентификатора равна 1.1, и это значение мы исполь- зуем по умолчанию. Есть однако, относительно небольшое число случаев, когда кардинальность идентификатора отличается от 1.1. Рассмотрим, например, атрибут Псевдоним се- мантического объекта ЧЕЛОВЕК. Человек не обязан иметь псевдоним, однако может иметь и несколько. Следовательно, кардинальность этого атрибута равна O.N. Указание нижних индексов всех атрибутов загромождает семантическую объ- ектную диаграмму. Для упрощения мы предположим, что кардинальность про- якеякп
Семанти еские объекты 809 стыл идентифицирующих атрибутов равна 1.1, а прочих идентифицирующих ат- рибутов — 0,1, Если кардинальность простого атрибута имеет другое значение, мы умажем ее на диаграмме. В противном случае нижние индексы простых атри- бутов будут опускаться Домены атрибутов Домен (domain) атрибута — это описание множества его значений. Характеристи- ки домена зависят от типа атрибута. Домен простого атрибута состоит из фи- зического и семантического описания. Физическое описание (physical description) показывает тип данных (например, число или строка), длину данных и другие ограничения (например, требование, чтобы первый символ был буквой или чтобы значение не превышало 9999.99). Семантическое описание (semantic description) указывает функцию, или назначение, данного атрибута- оно отличает этот атри- бут от других атрибутов с тем же физическим описанием. Например, домен атрибута НазваниеКафедры может быть определен как «на- бор строк длиной до 7 символов, представляющих наименования кафедр универ- ситета Highline». Фраза «набор строк длиной до 7 символов» представляет собой физическое описание домена, а «...представляющих имена кафедр университета Highline» — семантическое описание. Семантическое описание отличает строки из семи символов, представляющие названия кафедр, от строк такой же длины, которые представляют, скажем, названия учебных дисциплин, корпусов или ка- кие-то еще атрибуты. В некоторых случаях физическое описние домена простого атрибута представ- ляет собой нумерованный список — набор отдельных значений атрибутов. Доме- ном атрибута ЦветДетали может быть, например, нумерованный список {«Синий», «Желтый», «Кра ный»}. Домен группового атрибута также имеет физическое и семантическое описа- ние. Физическое описание — это список всех атрибутов в группе в порядке их ' ледовамия Семантическое описание — это описание функции, или назначения, данной группы Так, физическим описанием домена МестныйАдрес (см. рис. Б.2) является список {Корпус, НомерОфиса}; семантическим описанием является фраза местоположени офиса в университет Highline». Домен объектного атрибута — это набор экземпляров объектов данного типа. На рис. Б.2, например, доменом объектного атрибута ПРЕПОДАВАТЕЛЬ является совокупность всех экземпляров объектов класса ПРЕПОДАВАТЕЛЬ, представлен- ных в базе данных Доменом объекта КОЛЛЕДЖ явл «стся совокупность всех объ- ектов класса КОЛЛЕДЖ, представленных в базе данных В определенном смысле 1 я атрибута — это динамически нумеруемый список, который содержит все экземпляры объектов данного типа Представления семантических объектов Полъя«вате и имеют доступ к значениям объектных атрибутов Че|х?з прилоЖе* Имя баям данных, которые предоставляют формы для вйид<1 данных, отчеты »< за* ярггм Й болмминстве случаев такие фирмы, отчеты й заН|ЮсЫ не требуют Досгу-
810 Приложение Б. Семантическая ооъектная модель па ко всем атрибутам .объекта. Например, па рис. Б.4 показаны представления объекта КАФЕДРА для двух различных приложении. Некоторые атрибуты объекта КАФЕДРА (например. НазваниеКафедры) являются видимыми в обоих представ- лениях. Другие атрибуты видимы только в одном из представлений. Например, атрибут СТУДЕНТ является видимым только в представлении СписокСтудентов, а атри- бут ПРЕПОДАВАТЕЛЬ виден только в представлении Персонал. Часть объекта, видимая для конкретного приложения, называется представ пением семантического объекта (semantic object view) или просто представлени- ем (view). Представление состоит из имени объекта и списка всех атрибутов, видимых в этом представлении. Представления используются двояким образом. Когда вы разрабатываете базу данных, вы можете использовать их для построения модели данных. Взгляни- те снова на рис. Б.1. Как можно видеть, при разработке модели данных разрабо - чики базы данных и приложений двигаются в обратном направлении. То есть они начинают с форм отчетов и запросов, которые пользователи объявляют не- обходимыми, и двигаются назад, к структуре базы данных. Для этого команда выбирает требуемую форму, отчет или запрос и определяет, какое представление должно существовать, чтобы можно было создать такую форму, отчет или за- прос. Затем команда переходит к следующей форме, отчету или запросу и делает то же самое. Далее получившиеся два представления объединяются. Описанный процесс повторяется до тех пор, пока структура базы данных не будет полностью сформирована. Второй аспект использования представлений возникает, когда структура базы данных уже создана. В этом случае представления создаются для под- держки новых форм, отчетов и запросов на основе существующей структуры базы данных. Примеры этого второго подхода были приведены в части IV, где обсуждались SQL Server и Oracle. Рис. Б.4. Два представления семантического объекта КАФЕДРА — СписокСтудентов и Персонал
Типы объектов 811 Типы объектов В этом разделе описываются и демонстрируются семь типов объектов. Для каж- дого типа объектов мы исследуем отчет или форму и покажем, как их можно представить с помощью данного объекта. Далее мы трансформируем каждый из этих типов в соответствующую структуру базы данных. В данном разделе используются три новых термина. Однозначный атрибут (single-value attribute) — это атрибут с максимальным кардинальным числом 1. Многозначный атрибут (multi-value attribute) — это атрибут, имеющий максималь- ное кардинальное число больше 1. Необъектный атрибут (non-object attribute) — это простой или групповой атрибут. Простые объекты Простой объект (simple object) — это семантический объект, имеющий только од- нозначные, простые или групповые атрибуты. Пример такого объекта приведен на рис. Б.5. На рис. Б.5, а, представлены два экземпляра отчета под названием Инвентарный ярлык. Такие ярлыки, наклеиваемые на офисный инвентарь, помо- гают вести его учет. Их можно рассматривать как отчеты. На рис. Б.5, б, изображен простой объект ИНВЕНТАРЬ, с помощью которого мо- делируется ярлык для оборудования. Атрибуты объекта включают в себя то, что указано на ярлыке: ИнвентарныйНомер, Описание, ДатаПриобретения и Стоимость. Обратите внимание, что ни один из этих атрибутов не является многозначным, как ни один из них не является и объектным. Следовательно, объект ИНВЕНТАРЬ является простым объектом. ИНВЕНТАРНЫЙ ЯРЛЫК ИнвентарныйНомер: 100 Описание: Стол Дата: 2/27/2000 Стоимость: $350.00 ИНВЕНТАРЬ ID ИнвентарныйНомер Описание Дата Стоимость ИНВЕНТАРНЫЙ ЯРЛЫК ИнвентарныйНомер. 200 Описание: Лампа Дата 3/1/2000 Стоимость: $39.95 б а ИНВЕНТАРЬ (ИивошарныЙН.ЬМир, Описание, Дата, Стоимость) в Рис 6.5. Пример простого объекта а — отчеты, основанные на простом объекте, б простой Объект ИНВЕНТАРЬ, в - представление объекта ИНВЕНТАРЬ в виде отношения Рисунок Б 5 является примером простого объекта, который можно пред* ставить с помощью одиночною отношения, как показано на рис Б.5, в. Каждый атрибут объекта определен как атрибут отношения, а пдс'шпфнцнру ющнй атрн*
812 Приложений Б. Семантическая объемная моды», бут. ИнвентарныйНомер, стапоапия ключом о,ношении, ч.и обо.иа^кя КИ №ая1^м^фе«>браз«»ван11я щимиых объектов в юнони-кия показана Mt ППС Б 6 Оиьект ОБЪЕКТ! трансформируси-Я в отношение 01 .Ж.КМНЛЯры объ- ема ОБЪЕКТ! пдентифнт.руюня а-рнбу.ом А1; он с.-шниня ключом отиъ шенпя 01. Неключевые данные убозиачепы на .том и >ии .«дующих рисунках многоточием. Рис. Б.6. Общая схема преобразования простого объекта а отношение Поскольку ключ - это атрибут, однозначно идентифицирующий строку таб- лицы, только уникальные идентификаторы (обозначенные подчеркнутыми бук- вами 1D) могут быть преобразованы в ключи. Если у объекта нет уникального идентификатора, то такой идентификатор необходимо создать, объединив суще- ствующие атрибуты или введя суррогатный ключ. Композитные объекты Композитный объект (composite object) — это семантический объект, содержа- щий один или несколько многозначных, простых или групповых атрибутов, но не имеющий объектных атрибутов. Счет за услуги гостиницы, изображенный на рис. Б.7, а, демонстрирует потребность в композитном объекте. Этот счет содер- жит данные, относящиеся к счету в целом: НомерСчета, ДатаПрибытия, ИмяКлиента и СуммаКОплате. Кроме того, в нем имеется повторяющаяся группа атрибутов, ко- торая описывает предоставленные клиенту услуги. Каждая группа включает в се- бя атрибуты ДатаОказанияУслуги, ОписаниеУслуги и Стоимость. На рис. Б.7, б, показана диаграмма объекта ГОСТИНИЧНЫЙ_СЧЕТ. Атрибут Стро- каРасходов — это групповой атрибут, имеющий максимальное кардинальное чис- ло N, что означает, что группа {ДатаОказанияУслуги, ОписаниеУслуги, Стоимость} может появляться многократно в одном и том же экземпляре семантического объекта ГОСТИНИЧНЫЙ_СЧЕТ. Строка расходов не моделируется как самостоятельный семантический объект, а вводится как атрибут объекта ГОСТИНИЧНЫЙ_СЧЕТ. Такая организация оправ- дана тем, что гостиница не рассматривает каждую строку расходов в счете клиента как нечто отдельное и строки расходов не имеют собственных пдентпфикато ров. Служащие не вводят данные в строку расходов иначе как в контексте счета. начала служащий вводит данные для счета № 1234, а затем — суммы, указан- пые в конкретном счете. Бывает и так, что служащий берет уже существующий счет и вносш в него дополнительные расходы.
Типы объектов 813 ОТЕЛЬ ГРЭНДВЬЮ Си Блафс, Калифорния Номерсчета 1234 Имя клиента Мэри Джо Дата поселения 12 10 2003 нс 10/12/2001 Проживание $99.00 10/12/2001 Питание $37.55 10/12/2001 Телефон $2 50 10/12/2001 Налог $15 00 10/12/2001 Проживание $99.00 10/12/2001 Питание $37 55 10/12/2001 Налог $15 00 Итого $315.95 ГОСТИНИЧНЫЙ_СЧЕТ ID НомерСчета ДатаПоселения 11 ID ИмяКлиента СТРОКА_РАСХОДОВ “I ДатаОказанияУслуги, п ОписаниеУслуги 11 Цена 1ч 0.N ВсегоКОплате ,1 _______________________ б ГОСТИНИЧНЫЙ_СЧЕТ (ID НомерСчета, ДатаПоселения, ИмяКлиента, ВсегоКОплате) СТРОКА_РАСХОДОВ (НомерСчета. ДатаОказанияУслуги, ОписаниеУслуги, Цена) Ограничение ссылочной целостности Значение атрибута НомерСчета в отношении СТРОКА_РАСХОДОВ должно существовать среди значений атрибута НомерСчета в отношении ГОСТИНИЧНЫЙ СЧЕТ в Рис. Б.7. Пример композитного объект а — отчет, основанный на композитном объекте, б — композитный объект ГОСТИНИЧНЫЙ_СЧЕТ, в — реляционное представление Минимальное кардинальное число атрибута СтрокаРасходов равно 0, что означа- ет. что объект ГОСТИНИЧНЫЙ_СЧЕТ может существовать без единой строки расходов. Это позволяет открывать счет в тот момент, когда клиент вселяется в гостиницу, то есть до того, как появятся какие-либо расходы Если бы минимальное карди- нальное число равнялось 1, то нельзя было бы открыть счет, прежде чем будет начислена хотя бы одна сумма Решение об этом должно приниматься исходя из имеющихся бизнес правил Политика гостиницы может заключаться в том, чтобы ве открывать счет, пока нс будут начислены какие либо расходы В таком случае минимальное кардинальное число атрибута СтрокаРасходов должно равняться 1. Для представления этол» объекта создано дна отношения' одно — для базово и» объекта ГОСТИНИЧНЫЙ СЧЕТ, а другое - для повторяющегося ipynnonoro атри СуточнаяПлата Получившаяся структура показана на рис Б7,в, Атрибут НомерСчета в отпоив инн СУ1ОЧНАЯ_ПЛАТА подчеркнут, так как он яв- ои*т<я частью ключа, и выделен куренном, поскольку он одновременно является Миюиим ключом (ключом отношения ГОСТИНИЧНЫЙ СЧЕТ) Атрнбхт ДатаОка- зДмяяУелуги подчеркнут потому, что он является ключом отношения СУТОЧНАЯ^ ШИТА но не Пмделгн кущ ином. птеколт ку не является внешним ключом В </>,игм елучяК при преобразовании композитных объектов вводится «Дно •гпы для объект i кик тввового и по очному отношению 1Ш ка жл й много*
814 Приложение Б Семантическая объектная модель зцачный атрибут. На рис Б.8. а, объект ОБЪЕКТ! содержиi две группы мшю«нач ных атрибутов, каждая из которых иредсмимшил отношением в структуре базы ыниых Ключ каждой из этих таблиц представляет соГюй сочетание идеитифи’ катора объекта и идеитпфикатора группы Так. представлением объекта ОБЪЕКТ! является отношение 01 с ключом А1. отношение 02 с ключом (А1, Г!) и отноше ине 03 с ключом (А1, Г2). Ограничения ссылочной целостности: Значение атрибута А1 в отношении 02 должно существовать среди значений атрибута А1 в отношении О1 Значение атрибута А1 в отношении ОЗ должно существовать среди значений атрибута А1 в отношении О1 а 0БЪЕКТ1 !В А1 О1 Группа 1 ~ 10 Г1 Группа 2~ IB Г2 0.N ~1 N Ограничения ссылочной целостности: Значение атрибута А1 в отношении 02 должно существовать среди значении атрибута А1 в отношении 01 Значение комбинации (А1, Г1) отношении 03 должно существовать среди значении комбинации (А1, Г1) в отношении 02 б Рис. Б.8. Общая схема преобразования простого объекта в отношение: а —- композитный о ъект с раздельными группами, б — композитный объект с вложенными группами
Типы объектов 815 Минимальное кардинальное число связи в направлении от объекта к г руппе задается минимальным кардинальным числом группового атрибута. На рис. Б.8, « минимальное кардинальное число первой группы Группа1 равно 1, а группы Группа2 0. Эти кардинальные числа показаны на диаграмме структуры данных в виде перпендикулярной черты (в 02) и овала (в 03). Минимальное кардинальное число связи по направлению от группы к объекту по умолчанию всегда равно 1, поскольку группа не может существовать, если не существует объекта, который должен содержать эту группу. Эти минимальные кардинальные числа показаны перпендикулярными чертами на линиях связи, ведущих к 01. Группы могут быть вложенными. На рис. Б.8, б, показан объект, в котором од- на группа вложена в другую. В такой ситуации отношение, представляющее вло- женную группу, подчиняется отношению, представляющему внешнюю группу. На рис. Б.8, б, отношение 03 подчинено отношению 02. Ключом отношения 03 является ключ отношения 02, (А1, Г1) в сочетании с идентификатором второй группы, Г2; таким образом, ключом отношения 03 является комбинация (А1, Г1, Г2). Убедитесь, что вы понимаете, почему ключи на рис. Б.8, б, построены именно таким образом. Также обратите внимание на то, что некоторые атрибуты подчеркну ты и выделены курсивом, а некоторые просто подчеркнуты, так как первые являют- ся и локальными, и внешними ключами, а вторые — только локальными ключами. Составные объекты Составной объект (compound object) имеет по кранной мере один объектный ат- рибут. На рис. Б.9, а, показаны две формы для ввода данных. Одна из них исполь- зуется автомобильным парком компании для учета имеющихся транспортных средств. Во вторую форму вводятся данные о сотрудниках. Согласно этим формам, любое транспортное средство закрепляется ие более чем за одним сотрудником, и за любым сотрудником может быть закреплено не более одного автомобиля. Мы не можем определить из этих форм, должен ли каждый автомобиль за- крепляться за каким-либо сотрудником, и должен ли каждый сотрудник иметь автомобиль. Чтобы получить эту информацию, нам пришлось бы спросить об этом пользователей, работающих в автопарке или в отделе кадров Предполо- жим, мы выяснили, что сотрудник не обязан иметь транспортное средство, но каж- дое транспортное средство должно быть закреплено за каким-либо сотрудником. На рис. Б.9, б, представлены диаграммы объектов СОТРУДНИК и ТРАНСПО НОЕ_ СРЕДСТВО. Объект СОТРУДНИК содержит в качестве одного из атрибутов объект ТРАНСПОРТНОЕ_СРЕДСТВО, а ТРАНСПОРТНОЕ_СРЕДСТВО, в свою очередь, содержит в каче- стве одного из атрибутов объект СОТРУДНИК. Поскольку и СОТРУДНИК, и ТРАНСПОРТ- НОЕ_СРЕДСТВО имеют объектные атрибуты, оба они являются составными объекта- ми. Более того, гак как ни один из атрибутов ие является многозначным, связь между объектами СОТРУДНИК и ТРАНСПОРТНОЕ_СРЕДСТВО имеет вид «одни к одному» - 1:1. На рис. Б.9, а, формы ДАННЫЕ СОТРУДНИКА и ДАННЫЕ ТРАНСПОРТНОГО СРЕДСТВА включают одна другую. То есть в форме ДАННЫЕ ТРАНСПОРТНОГО СРЕДСТВА имеет- ся поле «Закреплено за со грудником», а в форме ДАННЫЕ СОТРУДНИКА имеется поле «Закреплен автомобиль». Но эго нс всегда гак: иногда (.вязь может каз«иься однонаправленной. Рассмотрим отчет п форму па рпс. Б. 10, д» в коюрых онпсыва-
816 Приложение Б. Семантическая объектная модель ются два объекта: ОБЩЕЖИТИЕ и СТУДЕНТ. Из отчета о танятоети общежития мы можем видеть, что в представлении нользонаюлей общежитие имеет атрибуты относящиеся как к самому общежитию - название общежития, имя ответе твеиио- го жильца, телефон (Общежитие, Ассистент по общежитию, Телефон), гак и к про жнвающим в нем студентам - нмя студента, помер студен га, группа (Имя студента, Номер студента, Группа). ДАННЫЕ ТРАНСПОРТНОГО СРЕДСТВА Номер лицензии Серийный номер Производитель Тип | Год выпуска | Цвет Закреплен за сотрудником ДАННЫЕ СОТРУДНИКА Имя сотрудника Номер сотрудника Почтовый ящик Отдел | Телефон ,, Код Кодоплаты квалификации Дата приема на работу Закреплен автомобиль а СОТРУДНИК то ИмяСотрудника id НомерСотрудника ПочтовыйЯщик Отдел Телефон КодОплаты КодКвалификации ДатаНайма ТРАНСПОРТНОЕСРЕДСТВО id НомерЛицензии id СерийныйНомер Производитель Тип Год выпуска Цвет ТРАНСПОРТНОЕ СРЕДСТВО 0.1 СОТРУДНИК 1 --1 1.1 б Рис. Б.9. Составные объекты со связью вида 1:1 между свойствами: а — примеры форм для ввода данных об автомобиле и сотруднике; б — составные объекты СОТРУДНИК и ТРАНСПОРТНОЕ СРЕДСТВО С другой стороны, форма с данными о студенте содержит информацию, касаю- щуюся исключительно самого студента, — никаких данных об общежитии в этой форме нет. (Местный адрес может быть адресом общежития, но, даже если и так, этот факт явно недостаточно важен, чтобы документировать его в форме. Прн разработке оазы данных возможность этого следует выяснить в ходе опроса пользователей. Здесь мы предположим, что форма с данными о студенте не со- держит информации об общежитии ) Как мы уже отметили ранее, объектные атрибуты всегда появляются парами. Даже если формы, отчеты и запросы демонстрируют только одну сторону связи, у связи всегда имеются две стороны. Связь можно сравнить с мостом, соединяю-
Типы объектов 817 щим два острова: мост соприкасается с обоими островами, и двигаться по нему можно в обоих направлениях, даже если по обычаю или закону этот мост являет- ся однонаправленным. ОТЧЕТ О ЗАНЯТОСТИ ОБЩЕЖИТИЯ Общежитие Ассистент по общежитию Телефон Ингерсол Сара и Аллен Френч 3-5567 Имя студента Номер студента Курс Адамс, Элизабет 710 С2 Бейкер, Рекс 104 С1 Бейкер, Брайди 744 СЗ Чарльз, Стюарт 319 С2 Скотт, Салли 447 С2 Тейлор, Линн 810 С1 а ОБЩЕЖИТИЕ ID НазваниеОбщежития ID АссистентПоОбщежитию Телефон СТУДЕНТ ID ИмяСтудента ID НомерСтудента Специализация Руководитель Курс Школа ПредыдущийКолледж МестныйАдрес МестныйТелефон б Рис Б. 10. Составные объекты со связью вида 1 N между свойствами- а - примеры форм Для ввода данных об общежитии и студенте, б — составные объекты ОБЩЕЖИТИЕ и СТУДЕН Если не удается iiaiiin ин одной формы или отчета, документирующих одну на сторон связи, команда разработчиков должна спросить пользователей о кардн- малый* ти этой свя ти В этом случае команде требуется выяснить, сколько оощежи-
818 Приложение Б. Семантическая объектная модель пш может быть у студента и должен ли студент бып, прикреплен к общежитию. Здесь мы допустим, что ответы па этот вопрос были следующими: студент может быть прикреплен максимум к одному общежитию, но может и не быть прик|>епл£и ным ни к одному. Так, на рис. Б.10, б, объект ОБЩЕЖИТИЕ содержит многознач- ный объектный атрибут СТУДЕНТ, а объект СТУДЕНТ имеет однозначный объект ный атрибут ОБЩЕЖИТИЕ. Таким образом, связь между объектами ОБЩЕЖИТИЕ и СТУДЕНТ имеет вид «одни ко многим», или 1:N. Еще один пример составных объектов показан на рис. Б.11, а. Из представ- ленных здесь форм мы можем заключить, что одна книга может быть написана несколькими авторами (форма Книга, содержащая данные об имеющихся в нали- чии книгах) и что один автор может написать много книг (форма Автор, содер- жащая данные об имеющихся в наличии книгах, отсортированные по авторам). Так, на рис. Б.11, б, объект КНИГА содержит многозначный объектный атрибут АВТОР, а объект АВТОР имеет многозначный объектный атрибут КНИГА. Следова- тельно, связь между объектами КНИГА и АВТОР имеет вид «многие ко многим», или N:M. Более того, книга обязана иметь автора, а автор, чтобы считаться тако- вым, должен написать минимум одну книгу. Поэтому оба эти объекта имеют минимальное кардинальное число 1. ив и ЙЭ Автор Н:амкс S3 Книга {13025б?Г"--------- [Прентис-Холл |ГЭ39..... ~ > |>||»»|д Касательство Дьтобыкаг, >«]_< I f ~н ажного мих,» е галич,., «ПЛ ГяидТи».. Книга 123457 TxL»Ui*J« -• Братья Карамазовы Униженные и оскорбленные 123456 > Преступление и наказа е 2| Идиот ............. :78883 ‘89899 лились: к | « |Г КНИГА ID Название [ АВТОР | 1.N U2ISBN Издательство ДатаВыхода АВТОР ID ИмяАвтора ГодыЖизни Г книга! ... H.N б Рис. Б.11. Составные объекты со связью вида N:M между свойствами: а — примеры форм для ввода данных книжного магазина; б — объекты КНИГА и АВТОР На рис. Б. 12 изображены все четыре типа составных объектов. Все эти связи сводятся к некоторому варианту связи «один к одному», «один ко многим» или «многие ко многим». В частности, связь в направлении от объекта ОБЪЕКТ! к объек-
Типы объектов 819 ту ОБЪЕКТ? может иметь вид 1:1, 1:N пли N:M, в то время как связь в направле- ннн от объекта ОБЪЕКТ? к объекту ОБЪЕКТ1 может иметь вид 1:1, 1:М или M:N. Любвдмэ этих святой прсдстадляегся одним из трех возможных типов. Объект 2 может содержать Объект 1 может содержать Один Много Один 1:1 1:N Много М:1 M:N Рис. Б. 12. Четыре типа составных объектов Представление составных объектов со связью 1:1 Рассмотрим связь между членом спортивного клуба (ЧЛЕН_КЛУБА) и шкафчиком в раздевалке (ШКАФЧИК). Каждый шкафчик закрепляется за одним членом спортивного клуба, и за каждым членом этого клуба может быть закреплен один и только один шкафчик. На рис. Б. 13, а, представлены объектные диаграммы. Чтобы представить эти объекты с помощью отношений, мы для каждого объекта введем отношение, а затем, как и в случае связи 1:1 между сущностями, поместим ключ одного из отношений в другое. В данном случае мы можем поместить ключ отношения ШКАФЧИК в отношение ЧЛЕН_КЛУБА или ключ отношения ЧЛЕН_КЛУБА в отношение ШКАФЧИК. На рис. Б. 13, б, изображен случай, когда ключ отношения ШКАФЧИК помещен в отношение ЧЛЕН_КЛУБА. Обратите внимание, что атрибут НомерШкафчика в отношении ШКАФЧИК подчеркнут, так как здесь он является ключом, а в отношении ЧЛЕН_КЛУБА — выделен курсивом, поскольку для данного отношения он является внешним ключом. ЧЛЕН_КЛУБА I ЛичныйНомер Имя Адрес Город Штат Индекс ШКАФЧИ J»1 ШКАФЧИК 1Р НомерШкафчика Тип Код Расположение ЧЛЕН-.КЛУБА с. ЧЛЕЯ^КЛУБА (ДичныиНомср, Имя, Адрес, Город. Штат, Индекс, НоыерШчлфмим) <ИК ИМ. ТИП. Код. Р.СПОЛЮК‘НИ I Oro»—11 «I» ссылочной целостности ЯЬмчание «гриву* НомерШкафчика в отношении ЧЛЕН КЛУБА должно сущее • ть среди знамений ггрибут НомерШкафчика а отношении ШКАФЧИК б ри« В 13 Пример реляционного пред тавления составных объектов ер самые вида 1 1 » - пример составных объектов со связью Г1; $ «. реляционное представление этих объектов
820 Приложение Б. Семантическая объектная модель В общем случае при связи 11 между объектами ОБЪЕКТ! и ОБЪЕКТ? мы вво- дим по одному отношению для каждого объекта- 01 и 02 (оответственио Затем мы помещаем ключ одного из отношений (А! или А2) и другое отношение, как показано на рис. Б.14. ОБЪЕКТ2 IQ А2 ОБЪЕКТ! 01 О1 Ограничение ссылочной целостности: Ограничение ссылочной целостности: Значение атрибута А2 в отношении 01 Значение атрибута А1 в отношении 02 должно существовать среди значений должно существовать среди значений атрибута А2 в отношении 02 атрибута А1 в отношении О1 Рис. Б. 14. Общая схема преобразования составных объектов со связью 1:1 Представление связей «один ко многим» и «многие к одному» Теперь рассмотрим связи 1:N и N:l. На рис. Б.15, а, приведен пример связи 1:N между объектами ОБОРУДОВАНИЕ и РЕМОНТ. Элемент оборудования .может ремон- тироваться много раз, но конкретный ремонт может относиться только к одному элементу оборудования. Объекты на рис. Б. 15, а, представлены отношениями на рис. Б. 15, б. Обратите внимание, что ключ родителя (объект на унарной стороне связи) помещается в дочернее отношение (объект на множественной стороне связи). На рис. Б.16 показана общая схема преобразования составных объектов со связью 1:N. Объект 0БЪЕКТ1 содержит много объектов ОБЪЕКТ?, а объект ОБЪЕКТ? содержит только один объект 0БЪЕКТ1. Чтобы представить эту структуру с по- мощью отношений, мы вводим по одному отношению для каждого из объектов и помещаем ключ родителя в потомок. Например, на рис. Б.16 атрибут А1 поме- щается в отношение О?. Если бы объект ОБЪЕКТ? содержал много объектов ОБЪЕКТ!, а объект ОБЪЕКТ! — только один объект ОБЪЕКТ?, мы бы использовали ту же стратегию, только от-
Типы объектов 821 ношения 01 и 02 поменялись бы ролями. То есть мы поместили бы атрибут А2 в отношение 01. ОБОРУДОВАНИЕ id СерийныйНомер Тип Модель ДатаПриобретения Стоимость Место РЕМОНТ id НомерСчета Дате Описание Стоимость 11 ОБОРУДОВАНИЕ (СерийныйНомер. Тип, Модель, ДатаПриобретения, Стоимость, Место) РЕМОНТ (НомерСчета Дата, Описание, Стоимость, СерийныйНомер) Ограничение ссылочной целостности: Значение атрибута СерийныйНомер в отношении РЕМОНТ должно существовать средт значений атрибута СерийныйНомер а отношении ОБОРУДОВАНИЕ Рис. Б. 15. Пример реляционного представления составных объектов со связью 1:N. а — пример составных объектов со связью 1 :N; б — их реляционное представл гние ОБЪЕКТ1 го А1 ОБЪЕКТ2 го А2 ОБЪЕКГг; 1.N -РБЪЕКТ! Ограничение ссылочной целостности: Значение атрибута А1 в отношении 02 должно существовать среди значений !трибута А1 а отношении О1 Рис. Б.16. Общая схема преобразования составных объектов со связью 1:N Минимальные кардинальные числа в обоих случаях определяются минималь- ными кардинальными числами объектных «ирпбутов. На рпс. Б.16 объем 0БЪЕКТ1 требует наличия но крайней мере одного объекта ОБЪЕКТ?, но 0БЪЕКТ2 не требует
822 Приложение Б. Семантическая объектная модель обязательного наличия объекта ОБЪЕКТ! Кардинальные числа показаны ма ЙИЛ' грамме структуры данных в виде овала на Той сгороле < пя«и, где paciiowm- ся 01, и перпендикулярной черты на гой стороне связи, где располагается 02 Эти значения приведены просто для примера: один из объектов или оба могли бы иметь кардинальное число 0, 1 или какое-либо другое. Представление связей «многие ко многим» Наконец, рассмотрим связи M:N. Как и в случае связей M:N между сущностя- ми. мы определяем три отношения: по одному отношению для каждого из объек- тов плюс отношение пересечения. Отношение пересечения представляет связь двух объектов и состоит из ключей обоих своих родителей. На рис. Б. 17, а, пока- зана связь M:N между объектами КНИГА и АВТОР. На рис. Б.17, б, изображены три отношения, представляющие эти объекты: КНИГА, АВТОР и КНИГА-АВТОР- С (отношение пересечения). Обратите внимание, что отношение КНИГА-АВТОР-ПСЧ не содержит неключевых данных. Оба атрибута — ISBN и НомерСоциаяьнойСтрахов- ки — подчеркнуты и выделены курсивом, поскольку они являются и локальными, и внешними ключами. КНИГА ID ISBN Название НомерДляВызова АВТОР ' 'I АВТОР ip НомерСоциальнойСтраховки Имя Телефон 'Л- КНИГА а КНИГА (ISBN. Название, НомерДляВызова) КНИГА-АВТОР-ПСЧ (ISBN. НоюсСоциыыг.Мщэхыки) Ограничения ссылочной целостности: Значение атрибута ISBN в отношении КНИГА-АВТОР-ПСЧ должно существовать среди значений атрибута ISBN в отношении КНИГА Значение атрибута НомерСоциальнойСтраховки в отношении КНИГА-АВТОР-ПСЧ должно существовать среди значений атрибута НомерСоциальнойСтраховки в отношении АВТОР б Рис. Б.17. Реляционное представление составных объектов со связью M:N: а — объекты КНИГА и АВТОР ; б — их реляционное представление. В общем случае, если два объекта имеют связь вида M:N, мы вводим три от- ношения: 01 для объекта 0БЪЕКТ1, 02 для объекта ОБЪЕКТ? и 03 — отношение пе- ресечения. Общая схема показана на рис. Б. 18. Заметьте, что атрибутами отно- шения 03 являются только А1 и А2. В случае составных объектов со связью MN
Типы объектов 823 отношение 03 никогда не содержит неключевых данных. Важность этого замеча- ния станет ясна, когда мы сравним связи M:N в составных объектах со связями этого вида в ассоциативных объектах. ОБЪЕКТ1 !В А! ОБЪЕКТ2 ID А2 ХЖЪЕКГЙ 1 N ОБЪЕКТ! 01 О! 02 Ограничения ссылочной целостности: Значение атрибута А1 в отношении ОЗ должно существовать среди значений атрибута А1 в отношении О1 Значение атрибута А2 в отношении 03 должно существовать среди значений атрибута А2 в отношении 02 Рис. Б. 18. Общая схема преобразования составных объектов со связью М N в отношения Что касается минимального кардинального числа, го родители отношения пе- ресечения являются обязательными. Минимальные кардинальные числа связен в направлении к отношению пересечения определяются минимальными кар- динальными числами связей между объектами. На рис. Б. 18, например, строка в отношении 01 требует наличия строки в отношении 03, поскольку мини- мальное кардинальное число объекта ОБЪЕКТ! в объекте ОБЪЕКТ? равно 1 Од- нако строка в отношении 02 не требует наличия строки в отношении 03, по- скольку минимальное кардинальное число объекта ОБЪЕКТ! в объекте 0БЪЕКТ2 равно 0. Гибридные объекты Гибридные объекты (hybrid objects) — это комоинацпп композитных и составных объектов. В частности, гибридный объект — это семам г шеский ооъекг. имеющий хотя бы одни многозначный групповой атрибут, в состав которого входит объект- ный атрибут. х Ла рис Б 19, а, изображена вторая версия отчета о занятости оощежпгпя, представленною на рис. Б. 10 а. Различие заключается в том что третий столбец данных студента содержит атрибут Плата вместо атрибута Группа. Эта разница
824 Приложение Б. Семантическая объектная модель является существенной, поскольку плата ла проживание в общежитии является атрибутом не студента, а общежития, и относится к комбинации об'м*ктов СТУДЕНТ и ОБЩЕЖИТИЕ. ОТЧЕТ О ЗАНЯТОСТИ ОБЩЕЖИТИЯ Общежитие Ассистент по общежитию Ингерсол Сара и Аллен Френч Телефон 3-5567 Имя студента Номер студента Плата Адамс, Элизабет 710 $ 175.00 Бейкер, Рекс 104 $ 225.00 Бейкер, Брайди 744 $ 175.00 Чарльз, Стюарт 319 $ 135.00 Скотт, Салли 447 $ 225.00 Тейлор, Линн 810 $ 175.00 ОБЩЕЖИТИЕ ID НазваниеОбщежития АссистентПоОбщежитию Телефон ПлатаСтудент СТУДЕНТ 1.1 Плата 01 in ОБЩЕЖИТИЕ fe ID НазваниеОбщежития АссистентПоОбщежитию Телефон студент' Плата 0.N СТУДЕНТ ID ИмяСтудента ID НомерСтудента ОБЩЕ> ИЕ ---.—.-•-- Q1 СТУДИТ ID ИмяСтудента ID НомерСтудента ______ ОБЩЕЖИТИЕ а б Рис. Б. Гибридный объект DORMITORY а — отчет об общежитии со свойством Плата; ° правильный вид объектов ОБЩЕЖИТИЕ и СТУДЕНТ; а — неправильный вид объектов ОБЩЕЖИТИЕ и СТУДЕНТ Рис- Б. 19, б, показана объектная диаграмма, моделирующая эту форму, ект ОБЩЕЖИТИЕ содержит многозначную группу, включающую в себя объект*
Типы объектов 825 ный атрибут СТУДЕНТ и необъектный атрибут Плата. Это означает, что атрибуты Плата и СТУДЕНТ являются спаренными в контексте объекта ОБЩЕЖИТИЕ. Рассмотрим теперь альтернативный вариант объекта ОБЩЕЖИТИЕ, представлен- ный на рис. Б.19, в. Это неправильная модель отчета, изображенного на рис. Б.19, а, так как она показывает, что атрибуты Плата и СТУДЕНТ являются многозначными независимо друг от друга, что неверно, потому что эти атрибуты являются мно- гозначными как пара. На рис. Б.20, а, изображена форма, основанная на другом гибридном объек- те. Эта форма под названием Заказ содержит данные о заказе (Номер заказа, Дата, Подитог, Налог, Итог), данные о покупателе (Имя клиента) и продавце (Имя продавца), а также многозначную группу, содержащую данные о заказанных товарах. Кроме того, в этой многозначной группе представлены данные о товаре — Код товара Описание, Цена, Количество и Стоимость. На рис. Б.20, б, показан семантический объект ЗАКАЗ. Он содержит пеобъект- ные атрибуты НомерЗаказа, Дата, Подитог, Налог и Итог. Кроме того, он содержит объектные атрибуты КЛИЕНТ и ПРОДАВЕЦ, а также многозначную группу, пред- ставляющую каждую позицию заказа. Группа содержит необъектные атрибуты Количество и Стоимость и объектный атрибут ТОВАР. Объектные диаграммы на рис. Б.20, б, неоднозначны в одном аспекте, кото- рый может быть важен или не важен, в зависимости от приложения. Согласно объектной диаграмме, товар может быть связан более чем с одним заказом. Но, поскольку многозначная группа СтрокаЗаказа инкапсулирована (вложена) в объект ЗАКАЗ, из этой диаграммы не ясно, может ли конкретный вид товара появляться один раз или многократно в одном и том же объекте ЗАКАЗ. В общем, есть четыре интерпретации максимального кардинального числа для спаренных атрибутов гибридного объекта ЗАКАЗ. 1. Любой товар может появляться только в одном заказе и только в одной строке данного заказа. 2. Любой товар может появляться только в одном заказе, но во многих его строках. 3. Любой товар может появляться во многих заказах, но в каждом заказе — только в одной строке. 4. Любой товар может появляться во многих заказах, а в рамках заказа — во многих строках. Когда важно различать эти случаи, нужно использовать следующую запись, в случаях 1 и 2 максимальное кардинальное число гибридного объектного атрибу- та следует установить равным 1. Так, для данного примера максимальное кар- динальное число атрибута ЗАКАЗ объекта ТОВАР установлено равным 1. Если конкретный товар может появляться только в одной строке заказа (случай 1), он должен быть помечен как имеющий уникальный идентификатор в данной группе. Если нет (случай 2), то помечать его не требуется. Эти два случая изображены на рис. Ь 21, а и 6.
826 Приложение Б. Семитическая объектная модель К Заказ [Книжный магазин Carbon Riva Й<*> Описанм»- Гь.миОдгь ZZ-Z» r~wq <пь ющ Адрее Г<ххх, щхцзииа [Анна Дедсеорт i Ксл»чсстой[КодТ<|;1ара| Цен?____ __ ‘...... ' ’ 78 4959 00 Стол для руководителя $959 00 79 $1750 00 Стол для переговоров $1750 00 80 $99 00 Боковой стул$396 00 Псих»ог [171(7500 | Налег |ib'4»j | Йтсг [HI 34 4€] ЗАКАЗ ID НомерЗаказа Дата КЛИЕНТ г ПРОДАВЕЦ 1,111.1л СтрокаЗаказа — Количество 1t ТОВАР ------------ и___ Стоимость^ 1.N Подитог Налог 1 Итог, 1 ТОВАР ID КодТовара ОписаниеТовара Ценат.1 ' ЗАКАЗ Д| .. 0 N КЛИЕНТ ID Имя Адрес Город Штат Индекс Телефон 0N 4 а ПРОДАВЕЦ ID ИмяПродавца КодПродавца 11 КЗАКРИ |?------ 0N б Рис. Б.20. Гибридный объект SALES-ORDER и связанные с ним объекты; а — форма заказа; б — объекты, моделирующие форму заказа В случаях 3 и 4 максимальное кардинальное число гибридного объектного ат- рибута устанавливается равным N. Так, для данного примера максимальное кар- динальное число атрибута ЗАКАЗ в объекте ТОВАР устанавливается ранным N. Далее, если конкретный товар может появляться только в одной строке заказа
Типы объектов 827 (случай 3), он должен быть помечен как имеющий уникальный идентификатор в данной группе. Если нет (случай 4), то помечать его не требуется. Эти два случая изображены на рис. Б.21, в и г. ЗАКАЗ ID НомерЗаказа Дата КЛИЕНТ ПРОДАВЕЦ | СтрокаЗаказа _ Количество,, |р| ТОВАР Стоимость ,, J, N Подитог,, Налог,, Итог!, ЗАКАЗ ID НомерЗаказа Дата________ F КЛИЕНТ ] 1 ' ..1-311 I ПРОДАВЕЦ I I---------------ц ( СтрокаЗаказа Количество,, »О | ТОВАР 1,, Стоимость ц J, N Псдитог,, Налог,, Итог 1, ЗАКАЗ ID КодТовара ОписаниеТовара Цена,, |>s ЗАКАЗ ЗАКАЗ ID НомерЗаказа Дата |||# КЛИЕНТ J .............J11 | продавец""] .. ——— -* 1 , ! СтрокаЗаказа ~| Количество ,, | ТОВАР ;.|.. Стоимость 1.1 J1N Подитог , 1 Налог, , Итог б ТОВАР ID КодТовара ОписаниеТовара Цена,, Г ЗАКАЗ ] ТОВАР 1D КодТовара ОписаниеТовара Цена , 1 Г~7ЗАКАЗ "! -->01 ЗАКАЗ ID НомерЗаказа Дата КЛИЕНТ Т~| I ПРОДАВЕЦ | СтрокаЗаказа Количествоt, I ТОВАР J, Стоимость , 1J 1.N Подитог 1 1 Налог,, Итог,, ТОВАР ID КодТовара ОписаниеТовара Цена и ЗАКАЗ I t............—Ion в Рис. Б.21. Примеры четырех случаев максимальной кардинальности в гибридном объекте: а — один товар в одном заказе; б — один товар (возможно) во многих строках одного и того же заказа; в — один товар в одной строке (возможно) многих заказов; г — один товар (возможно) во многих строках (возможно) многих заказов Представление гибридных связей Общее описание этих четырех случаев приведено в табл. Б.1. Случаи 3 и 4 встре- чаются чаще, чем случаи 1 и 2, полому их мы рассмотрим в первую очередь. Объ- ект ОБЪЕКТ! па рис. Б 22 содержит две группы: Группа! иллюстрирует случай 3, а Группа? — случай 4 Группа! имеет максимальное кардина льное число N. что означает, что ОБЪЕКТ! Может содержать много жимпляров Группы Группа! Кроме того, поскольку ОБЪЕКТ? помечен как уникальный идентификатор, конкретный экземпляр объек Тв ОБЪЕКТ? может пояплягы я только в одном из экземпляров группы Группа!, со- дгржащгйся в объекте ОБЪЕКТ! Таким образом. ОБЪЕКТ! действует как идентн фимгтор Группы Группа! п объекте ОБЪЕКТ!
828 Приложение Б емантичеекая объектная модель Таблица 6.1, Общая характерноin*a четырех случаев кардинальности гибридны* Случаи Опис ние 1 ОБЪЕКТ2 связан с одним экземпляром ОББЕКТ1 и может появиться только в одном экземпляре группы. принадлежащей этому объекту 2 ОБЪЕКТ? связан с одним экземпляром ОБЪЕКТ1 и может появиться в нескольких экземплярах группы, принадлежащей этому объекту 3 ОБЪЕКТ2 может быть связан с несколькими экземплярами ОБЪЕКТ 1 и может появиться только в одном экземпляре группы, принадлежащей этому объекту 4 ОБЪЕКТ2 может быть связан с несколькими экземплярами ОБЪЕКТ1 и может появиться в нескольких экземплярах группы, при надлежащей этому объекту Пример Объект ТОВАР связан в одним объектом ЗАКАЗ и может появиться только в одной строке этого заказа Объект ТОВАР связан с одним объектом ЗАКАЗ и молвт ломмтцг;* в нескольких строках этого » >«аза Объект ТОВАР связан с несколькими объектами ЗАКАЗ, но в каждом из заказов может появиться только в одной строке Объект ТОВАР связан с несколькими объектами ЗАКАЗ и может появиться в нвскольких строках каждого из заказов Рассмотрим реляционное представление группы Группа! на рис. Б 22. Отно- шение 01 представляет ОБЪЕКТ!, а отношение 02 представляет 0БЪЕКТ2. Кроме того, для группы Группа! быдр создано третье отношение, 0-Г1. Связь между 01 и 0-Г1 имеет вид 1:N, поэтому мы помещаем ключ отношения 02 (атрибут А2) в отношение 0-Г1. Поскольку 0БЪЕКТ2 может появ^ яться с конкретным значением атрибута ОБЪЕКТ! только один раз, комбинация (Al, А2) в отношении 0-Г1 явля- ется уникальной и может быть сделана ключом данного отношения. Теперь рассмотрим группу Группа2. ОБЪЕКТЗ не определяет группу Группа2, поэтому он может появляться в различных экземплярах этой группы внутри од- ного экземпляра объекта ОБЪЕКТ!. Так как ОБЪЕКТЗ не является идентификато- ром группы Группа2, мы предполагаем, что идентификатором является какой-то другой атрибут, Г2. На рис. Б.22 показано созданное нами для объекта ОБЪЕКТЗ отношение 03, а также отношение 0-Г2, представляющее группу Группа2. Связь между 01 и 0Т2 имеет вид 1:N, поэтому мы помещаем ключ отношения 01 (атрибут А!) в отно- шение 0-Г2. Связь между 03 и 0-Г2 имеет вид 1:N, поэтому мы помещаем ключ отношения 03 (атрибут АЗ) в отношение 0-Г2. Теперь, однако, в отличие от случая с группой Группа!, комбинация (А1, АЗ) не может быть ключом 0-Г2, поскольку атрибут АЗ может быть спарен с данным атрибутом А1 много раз. То есть комбинация (А1, АЗ) не является уникальной в 0-Г2, поэтому ключом этого отношения должна быть комбинация (А1, Г2). Случай 1 аналогичен случаю 3, с тем только ограничением, что ОБЪЕКТ? может быть связан только с одним экземпляром ОБЪЕКТ!. Отношения, изобра- женные на рис. Б.22, годятся и здесь, ио мы должны добавить ключ отноше- ния 01 (атрибут А!) в отношение 02 и установить ограничение, состоящее и том, что комбин ня (Al, А2) в отношении 0-Г1 должна совпадать с комбинацией (Al, А2) в отношении 02.
Типы объектов 829 Случай 2 аналогичен случаю 4, но с тем ограничением, что объект ОБЪЕКТЗ может быть связан только с одним экземпляром объекта ОБЪЕКТ!. Опять-таки отношения на рис. Б.22 остаются годными и для этого случая, но мы должны добавить ключ отношения 01 (атрибут А1) в отношение 03 и установить сле- дующее ограничение: комбинация (А1, АЗ) в отношении 0-Г2 является под- множеством комбинации (А1, АЗ) в отношении 03 (см. вопросы 21 и 22 в конце приложения Б). Ограничения ссылочной целостности: Значение атрибута А1 в отношении О-Г1 должно существовать среди значений атрибута А1 в отношении О1 Значение атрибута А2 в отношении О-Г1 должно существовать среди значений атрибута А2 в отношении 02 Значение атрибута А1 в отношении О-Г2 должно существовать среди значений атрибута А1 в отношении О1 Значение атрибута АЗ в отношении О-Г2 должно существовать среди значений атрибута АЗ в отношении 03 Рис. Б.22. Общая схема преобразования гибридных объектов в отношения Ассоциативные объекты Ассоциативный объект (association object) - это объект, который связывает два или более объекта и содержит данные, относящиеся к этой связи. На рис. Б.23, а, показаны отчет и две формы для ввода данных, для моделирования которых не- обходим ассоциативный объект. Отчет содержит данные об авиарейсе, о самоле те, выполняющем этот рейс, и о пилоте, назначенном на этот рейс. Формы для ввода данных содержат данные о нилоте п о самолете.
830 Приложение Б. Семантическая объектная модель МЕЖДУНАРОДНАЯ ДИСКОНТНАЯ АВИАКОМПАНИЯ Полетный план нг>МЕР РЕЙСА FC 17 ДАТА 30 07.2001 ИСХОДНЫЙ ПУНКТ Сиэтл ПУНКТ НАЗНАЧЕНИЯ Гонконг ТОПЛИВО НА ВЗЛЕТЕ ВЕС НА ВЗЛЕТЕ__________________________________________ САМОЛЁТ Хвостовой номер N1234FI Тип 747-SP Вместимость 148____________________________________ ПИЛОТ Имя Майкл Нильсон Идент. номер 32887 Часов налета 18348 РЕЙС ID Рейса НомерРейса Дата _ ИсходныйПункт ПунктНазначения ТопливоНаВзлете ВесНаВзлете САМОЛЕТ ПИЛОТ ' -I ! а САМОЛЕТ ID ХвостовойНомер Производитель Боинг Тип ОбщаяНаработкаПланера ОбщаяНаработкаДвигателя НарДвигПослеКапрем ТекущаяВместимость ДальностьПолета РЕЙС ------- 0.N ПИЛОТ ID НомерПилота ID Имя ID НомерСоциальнойСтраховки Адрес Город Штат Индекс Телефон ЭкстрТелефон ДатаПоследнегоВылета ЧасовНалета ДатаПоследнегоОсмотра ;>ЕйБ^ .... б Рис. Б.23. Пример ассоциативного объекта: а — отчеты и формы, касающиеся полета: б — объекты РЕЙС, ПИЛОТ и САМОЛЕТ
Типы объектов 831 На рис. Б.23, б, объект РЕЙС это ассоциативный объект, который связывает объекты САМОЛЕТ и ПИЛОТ и хранит данные об их связи. Объект РЕЙС содержит в себе по одному объектному атрибуту САМОЛЕТ и ПИЛОТ, но объекты САМОЛЕТ и ПИЛОТ содержат множество объектных атрибутов РЕЙС. Такого рода связь двух пли более объектов возникает часто, особенно в приложениях, где требуется назначить друг другу две вещи или более. В качестве других примеров можно привести объект РАБОТА, связывающий объекты АРХИТЕКТОР и КЛИЕНТ, объект ЗАДАЧА, связывающий объекты СОТРУДНИК и ПРОЕКТ, и объект ЗАКАЗ, связываю- щий объекты ПОСТАВЩИК и УСЛУГА. В примере, изображенном на рис. Б.23, ассоциативный объект РЕЙС имеет собственный идентификатор — группу {НомерРейса, Дата} (номер рейса, дата). Часто ассоциативные объекты не имеют собственных идентификаторов, и тогда идентификатор представляет собой комбинацию идентификаторов объектов, ко- торые связаны в ассоциативном объекте. Отчет о назначении на проект Название проекта Дом Абернати Менеджер проекта Дж. Смит Началопроекта 11/11/1999 Окончание проекта Архитектор Б. Джексон Телефон 232-8878 Номерофиса J-1133 Начало работы по назначению 12/15/2001 Окончание работы по назначению 3/15/2002 Максимальное количество часов в бюджете 345 Максимальная стоимость труда $ 27,500 Максимальная стоимость материалов $ 17,500 НАЗНАЧЕНИЕ ю НомерНазначения ПРОЕКТ ----------:----, АРХИТЕКТОР I ----------——--- 1Д НачалоНазначения ПРОЕКТ ip НазваниеПроекта МенеджврПроекта НачалоПроекта ОкончаниеПроекта АРХИТЕКТОР КонецНазначения МаксимумЧасов МаксСтоимостьТруда МаксСтоимостьМатериалов ю ИмяАрхитектора Телефон НомерОфиса б Рио Б 24 Ассоциативный объект НАЗНАЧЕНИЕ а - пример отчета о назначении, б — объект НАЗНАЧЕНИЕ с сементическим объектным идентификатором Чтобы Лучше попять .но, рассмотрим рис Б.24. а, ча котором пзооражен от- чет о на и.ачсиии архитекторов на проект. Хотя само назначение ие имеет явного
832 Приложение Семантическая объектная модель идентификатора, в деисгвителыикти идеи шфикаюром является комбинация {НазваниеПроекта, ИмяАрхитектора }, Эш aipn6yti.i, однако, принадлежат объектам ПРОЕКТ н АРХИТЕКТОР coo rue rci пенно, а не объекту НАЗНАЧЕНИЕ. Идентификаъо- ром назначения является, таким образом, комбинация ид<*итификаго|хщ вещгй, которые назначаются друг другу. На рис. Б.24, б, показаны объектные диаграммы для .ною случая. И ПРОЕКТ н АРХИТЕКТОР являются объектными атрибутами объекта НАЗНАЧЕНИЕ, а группа {ПРОЕКТ, АРХИТЕКТОР} является идентификатором объекта НАЗНАЧЕНИЕ. Это «и . чает, что комбинация экземпляра объекта ПРОЕКТ и экземпляра объекта АРХИТЕКТОР идентифицирует конкретное назначение. Обратите внимание, что идентификатор НомерНазначения на рис. Б 24, б, не является уникальным; тем самым указывается, что архитектор может быть назна- чен на один и тот же проект несколько раз. Если это не так, идентификатор должен быть объявлен уникальным. Далее, если сотрудник может быть назначен на один и тот же проект более одного раза и если по какой-то причине важно иметь уни- кальный идентификатор для назначения, к группе следует добавить атрибут да- ты или какой-нибудь еще атрибут, указывающий время (неделя, квартал и т д.). В общем случае при преобразовании ассоциативных объектов в реляционные конструкции мы определяем по одному отношению на каждый объект, участвующий в связи. На рис. Б.25 объект ОБЪЕКТЗ связывает объекты ОБЪЕКТ! и ОБЪЕКТ2. Для этих объектов мы определяем отношения 01, 02 и 03, как показано на рисунке Клю- чи обоих родительских отношений, 01 и 02, фигурируют в качестве внешних ключей в отношении 03, представляющем ассоциативный объект. Если бы ассоциативный объект не имел уникального идентифицирующего атрибута, для создания уникаль- ного идентификатора использовалась бы комбинация атрибутов отношений 01 и 02. Обратите внимание на различие между ассоциативным отношением на рис. Б.25 и отношением пересечения на рис. Б. 18. Принципиальная разница состоит в том, что в ассоциативной таблице хранятся данные, представляющие некоторый аспект комбинации объектов; отношение же пересечения не содержит данных и сущест- вует лишь для того, чтобы указать, какие объекты связаны друг с другом. Объекты вида родитель—подтип Чтобы понять, что представляют собой объекты вида родитель—подтип (parent subtype objects), рассмотрим объект СОТРУДНИК на рис. Б.26, а. Некоторые атри- буты объекта СОТРУДНИК относятся ко всем сотрудникам, а некоторые — только к тем сотрудникам, которые являются менеджерами. Объект па рис. Б.26, а, не слишком точно отражает действительность, поскольку атрибуты, свойственные менеджерам, не подходят для сотрудников, не являющихся менеджерами. Более удачная модель показана на рис. Б.26, б. Здесь объект СОТРУДНИК содер- жит объект подтипа МЕНЕДЖЕР. Все атрибуты, относящиеся к менеджерам, перене- сены в ооъект МЕНЕДЖЕР. Сотрудники, не являющиеся менеджерами, имеют один экземпляр объекта СОТРУДНИК и ни одного экземпляра объекта МЕНЕДЖЕР. Сотруд- ники-менеджеры имеют но одному экземпляру объектов СОТРУДНИК и МЕНЕДЖЕР В этом примере объект СОТРУДНИК называется родительским объектом (parent
Типы объектов 833 object), или объектом надтипа (supertype object), а объект МЕНЕДЖЕР называется объектом подтипа (subtype object). ОББЕКТ1 ID А1 0БЪЕКТ2 ID А2 ОБЪЕКТЗ ON ОБЪЕКТЗ ON Ограничения ссылочной целостности: Значение атрибута А1 в отношении ОЗ должно существовать среди значений атрибута А1 в отношении 01 Значение атрибута А2 в отношении 03 должно существовать среди значений атрибута А2 в отношении 02 Рис. Б.25. Общая схема преобразования ассоциативных объектов в отношения СОТРУДНИК ip НомерСотрудника ,, ю ИмяСотрудника,, ДатаНайма Зарплата ДолжностьМенеджера УровеньМенеджмента НачисленнаяПремия ВыплаченнаяПремия Данные сотрудника Данные менеджера СОТРУДНИК 1Q НомерСотрудника id ИмяСотрудника ДатаНайма Зарплате менеджер"1 МЕНЕДЖЕР СОТРУДНИК ' ДолжностьМенеджера УровеньМенеджмента НачисленнаяПремия ВыплаченнаяПремия б Рис Б 26. Необходимость введения подтипа МЕНЕДЖЕР: а без подтипа; б - объект СОТРУДНИК с подтипом - объект СОТРУДНИК МЕНЕДЖЕР
834 Приложение Б. Семитическая объектная^модель Первым атрибутом подтипа является родительский объект, обозначенный ин- дексом Р. Указание родительского атрибута является обя тагелт>ным всегда Иден- тификаторы у подтипа тс же, что и у родителя. На рис Ь.26 атрибуты Номер- Сотрудника и ИмяСотрудника являются идентификаторами как объекта СОТРУДНИК, так и объекта МЕНЕДЖЕР. Атрибуты подтипа показываются с помощью индексов 0.ST или 1.ST. Первая цифра (0 или t) — это минимальное кардинальное число подтипа. Если оно равно О, подтип является необязательным, а если 1, то подтип является обязательным. (Обязательный подтип не имеет смысла для этого примера, но необходимость в нем появится в последующих, более сложных случаях.) Буквы ST (sub/ype — подтип) указывают на то, что атрибут является подтипом, или атрибутом типа «ЕСТЬ». Объекты вида родитель-подтип обладают важной характеристикой, называе- мой наследованием. Подтип приобретает, или наследует, все атрибуты своего ро- дителя. и поэтому объект МЕНЕДЖЕР наследует все атрибуты объекта СОТРУДНИК. Вдобавок родитель приобретает все атрибуты своих подтипов, и сотрудник, являющийся менеджером, приобретает все атрибуты менеджера. Семантический объект может содержать более одного атрибута подтипа. На рис. Б.27 показан второй вариант объекта СОТРУДНИК, который имеет два атрибу- та подтипа — МЕНЕДЖЕР и ПРОГРАММИСТ. Поскольку' оба этих атрибута являются необязательными, объект СОТРУДНИК может не иметь ни одного, иметь один или оба эти подтипа. Это означает, что некоторые сотрудники не являются ни менед- жерами, ни программистами, некоторые являются менеджерами, но не являются программистами, некоторые являются программистами, но не являются менед- жерами, а некоторые одновременно являются программистами и менеджерами. МЕНЕДЖЕР СОТРУДНИК СОТРУДНИК ТВ НомерСотрудника id ИмяСотрудника ДатаНайма Зарплата ДолжностьМенеджера УровеньМенеджмента НачисленнаяПремия ВыплаченнаяПремия ПРОГРАММИСТ СОТРУДНИК 1—~--------——Jp Язык о.ы ОперационнаяСистема0 N Рис. Б.27. Объект EMPLOYEE с двумя подтипами потда подпиты исключают друг друга. То есть транспортное средство может тыгь летковым автомобилем или грузовиком, но не тем и другим одновременно, лиент может быть индивидуальным клиентом, товариществом или корпораци- ей, ио только одним из этих грех типов. Когда подтипы исключают друг друга,
Типы объектов 835 они помещаются в группу подтипов, и группе присваивается индекс в формате X Y Z. X — эго минимальное кардинальное число, равное 0 или 1, в зависимости от того, является ли группа подтипов обязательной. Y н Z указываю! количество атрибутов в группе, которым разрешается иметь значение: Y — минимальное количество, Z — максимальное. КЛИЕНТ щ НомерКлиента ю ИмяКлиента ФИЗИЧЕСКОЕ ЛИЦО . * КЛИЕНТ • = НомерСоциальнойСтраховки СовокупнаяСтоимость ТОВАРИЩЕСТВО КЛИЕНТ t-iSaaStstf,------|р НалоговыйНомер УправляющийПартнер КОРПОРАЦИЯ КЛИЕНТ ----------------р НалоговыйНомер Баланс ИмяДоверенногоЛица ТелефонДоверенно гоЛица ФИЗИЧЕСКОЕ_ЛИЦО ;<::У"кЛИЕЖ ' L-----...........J,. НалоговыйНомер Баланс ИмяДоверенногоЛица Телефо нДоверенногоЛица Налогооблагаемая корЬ _------ <" ... о ST рНАЛОГО^ЛАГАЕМдОоРП --------&— .... '....о ST О 1 1 НАЛОГООБЛАГАЕМАЯ_КОРП Здрйоадия , “—*—--------Jp НалоговаяСтавка НЕНАЛОГООБЛАГАЕМАЯ_КОРП КОРПОРАЦИЯ ----.... ----ip ! 1омерОсвобождения ПРАВИТЕЛЬСТВЕННОЕJ^TEHTCTBO ... ............ — у ST ШКОЛА ПРАВИТЕЛЬСТВЕ ИНОЕ. АГЕНТСТВО ^ёйалогоовдаТае^мая корп] ФедеральныиНомер ШКОЛА_________________ 7зЕНАЛОГООБЛАГАЁмАЯ...КОРП ----------—•-----—•—— ....р ШкольныйОкруг б рис Б 2В. Взаимоисключающие (а) и вложенные (б) подтипы
836 Приложение Б. Семан тческая объектная модель На рис. Б.28, а, три типа клиентов изображены как iруина подтипов Индею труппы, 0.1.1, означает, что подтип не требуется, ио, если он существует, в труппе должен существовать минимум один и максимум один подтип (иначе творя, ровно один). Заметьте, что каждый на подтипов имеет индекс 0.ST, то есть все они являются необязательными, как и должно быть. Если бы все они были обязательными, максимальное количество атрибутов было бы 3, а не 1. Эта тя- нись достаточно надежна, чтобы предусмотреть ситуации, когда обязательными являются три из пяти или семь пз десяти подтипов. Можно смоделировать и более сложные ограничения, если ввести вложенные подтипы. Группа подтипов на рис. Б.28, б, моделирует ситуацию, когда корпора- ция может быть либо налогооблагаемой, либо не налогооблагаемой. Если корпо- рация не является налогооблагаемой, это должна быть либо правительственная организация, либо школа. В этом примере показано только несколько необъ- ектных атрибутов. В реальности, если бы требовалась такая сложная структура, в ней, скорее всего, было бы больше атрибутов. Общая схема представления подтипов показана на рис. Б.29. Одно отношение создается для родителя и по одному — для каждого из подтипов. Ключом всех отношений является идентификатор родителя. Все связи между родителем и под- типами имеют вид 1:1. Обратите внимание на длинную черту, пересекающую ли- нии связи, и на кардинальность группы подтипов. Кардинальность 0.1.1 говорит о том, что ни один из подтипов не является обязательным, но, если он присутст- вует, допустимо не более одного подтипа. ОБЪЕКТ! Щ А! ПОДТИП! ОБЪЕКТ! р V подтип!1 ______ 0.ST подтипа"] Ограничения ссылочной целостности: Значение атрибута А1 в отношении 02 должно существовать среди значений атрибута А1 в отношении О1 Значение атрибута А1 в отношении ОЗ должно существовать среди значений атрибута А1 в отношении 02 Рис. Б.29. Общая схема преобразования объектов вида родитель/подтип в отношения
Сравнение семантической объектной модели и модели «сущность—связь’ 837 Объекты вида архетип-версия Последний тип объектов — это объекты вида архетип версия (archetypc/version objects). Объект-архетип (archetype object) - это семантический объект, порож- дающий другие семантические объекты, которые представляют версии (version objects), выпуски или издания архетипа. Например, на рис. Б.ЗО объект-архетип УЧЕБНИК порождает объекты-версии ИЗДАНИЕ. Согласно этой модели, атрибуты Название, Автор и Издательство принадлежат объекту УЧЕБНИК, а атрибуты Поряд- ковыйНомерИздания, ДатаВыхода и КоличествоСтраниц — объекту ИЗДАНИЕ. УЧЕБНИК id ISBN Название Автор Издательство s ИЗДАНИЕU .........'.....й..,. N ИЗДАНИЕ ip ИдентификаторИздания УЧЕБНИК П ............. J j 1 ПорядковыйНомерИздания11 ДатаВыхода -I КоличествоСтраниц Рис. Б.ЗО. Пример объекта вида архетип-версия Идентификационная группа объекта ИЗДАНИЕ состоит из двух частей: УЧЕБНИК и ПорядковыйНомерИздания. Это типичный образец идентификатора объекта-вер- сии. Одна часть идентификагора содержит объект-архетип, а вторая часть — это простой атрибут, идентифицирующий версию архетипа. Па рис. Б.31 изображен еще один пример объектов вида архетип-версия. На рис. Б.32 показана общая схема преобразования объектов вида архетип-версия в отношения. Атрибут А1 отношения 02 является и локальным, и внешним ключом, а атрибут А2 является только локальным ключом. ЗДАНИЕ id Название Адрес Город Штат Индекс КоличествоЭтажей Ж квартираас: '"Ч,-*'_'_'_ \. -| м КВАРТИРА ip ИдентификаторКвартиры ЗДАНИЕ ----------------j,, НомерКвартиры,, КоличествоКомнат ,, Площадь Рис. Б.31. Еще один пример объекта вида архетип версия Сравнение семантической объектной модели и модели «сущность связь> Модель «сущношь < ства, гак и различия вязы> н семантическая объектная модель имеют как гход- Опп похожи гем, что обе являются инструментами для
838 Приложение Б Семантическая объектная модель уяснения и документирования структуры пользовательских данных Обе «>ин имеют своей целью моделирование структуры вещей и связей между ними • мире пользователей. ОБЪЕКТ! 10 А! ОБЪЕКТ2 10 ИдОбъвкта? | ОБЪЕКТ? А2„ 1 ОБЪЕКТ? [ 0N О1 Ограничения ссылочной целостности: Значение атрибута А1 в отношении 02 должно существовать среди значений атрибута А1 в отношении О1 Рис. Б.32. Общая схема преобразования объектов вида архетип-версия в отношения Принципиальное различие между двумя моделями заключается в ориентации Модель «сущность—связь» в качестве базовой рассматривает концепцию сущно- сти. Сущности и их связи выступают, если хотите, как атомы модели данных. Эти атомы могут быть организованы в структуры, которые модель «сущность- связь» называет пользовательскими представлениями (user views). Пользователь- ские представления — это комбинации сущностей, строение которых напомина- ет строение семантических объектов. Базовое понятие семантической объектной модели — семантический < ю&е*", Набор семантических объектов в модели данных — это карта структуры вещей, которые пользователи считают существенными. Эти объекты являются атомами мира пользователей и представляют собой наименьшие различимые единицы, которыми пользователи желают оперировать. Они могут разбиваться на более мелкие части внутри СУБД (или в приложении), но эти более мелкие части не представляют интереса для пользователей. С точки зрения семантической объектной модели сущности, в том виде как они определены в модели «сущность—связь», не существуют. Они являются лишь фрагментами, кусками реальных сущностей. Фактически единственные сущности, которые имеют смысл для пользователей, — это семантические объекты. По-другому можно выразить это, сказав, что семантические объекты являютс^
Сравнение семантической объектной модели и модели «сущность-связь. 839 семантически самодостаточными, или семантически завершенными. Рассмотрим пример. На рис. Б.3.3 представлены четыре семантических объекта: ЗАКАЗ, КЛИЕНТ, РОДАВЕЦ и ТОВАР. Когда пользователь говорит «Покажите мне заказ № 2000», он имеет в виду, что следует показать объект ЗАКАЗ гак, как он смоделирован' на рис. Б.33. Сюда входят, среди прочего, данные о покупателе. Поскольку информация о покупателе является частью заказа, объект ЗАКАЗ содержит объ- ект КЛИЕНТ. ЗАКАЗ ip НомерЗаказа Дата КЛИЕНТ ..........~ 11 С ПРОДАВЕЦ --------------1 Стрикалзказа Количество ' ТОВАР .А Стоимость ПромежуточныйИтог Налог “и Итог КЛИЕНТ |р НомерКлиента id ИмяКлиента Адрес i Улица Город Штат Индекс ,, ЗАКАЗ ----------0 N ТОВАР ю КодТовара Название Описание ПРОДАВЕЦ id ИмяПродавца id КодПродавца ЗАКАЗ ЗАКАЗ ---—----:-г к Рис. Б.33. Объект ЗАКАЗ и связанные с ним семантические объекты На рис. Б.34 изображена модель «сущность—связь» для тех же данных, которая содержит сущности ЗАКАЗ, КЛИЕНТ, ПРОДАВЕЦ, ТОВАР п СКЛАД. Сущность ЗАКАЗ имеет атрибуты НомерЗаказа, Дата, ПромежуточныйИтог Налог и Итог. Теперь, если пользователь носироит «Покажите мие заказ № 2000», он оудет разочарован и, скорее всего, задаст вопрос: «А где же остальные данные?». 1о есть сущность ЗАКАЗ не соответствует пользовательскому представлению о заказе как об отдель- ном феномене. Эта сущность является лишь частью реального заказа. В то же время, когда пользователь (возможно, даже тот же самый) попросит «Покажите мне покупателя № 12 345», он будет иметь в виду, чго следует пока- зать все данные, которые па рис. Б.ЗЗ опюсятся к покупателю, включая имя кли- ента, все составляющие адреса и все закаты этого покупателя. Сущность КЛИЕНТ на рис Б.34 имеет только атрибуты ИмяКлиента, Улица. Город, Штат и Индекс Если бы пользователю, который попросил: «Покажите мне покупателя УВС». предо- ставили только тти данные, он был бы снова разочарован: «Пег. эго только часть ТОГО, ЧТО мие нужно».
840 Приложение 6. Семантическая объектная модель Рис. Б.34. Модель «сущность—связь» для объекта ЗАКАЗ и КЛИЕНТ С точки зрения семантической объектной модели в сущностях, как они пред- ставлены в модели «сущность—связь», нет необходимости. Семантические объекты можно сразу преобразовывать в структуру базы данных, никак не рассматривая ER-сущности. Они являют собой, так сказать, недостроенные дома, воздвигну- тые в процессе ухода от парадигмы компьютерных структур данных к парадигме пользователей. Еще одно различие состоит в том, что семантические объекты содержат в себе больше метаданных, чем сущности. В семантической объектной модели на рис. Б.ЗЗ отражено то, что НомерКлиента является уникальным идентификато- ром в представлении пользователей. Он может использоваться или не исполь- зоваться в качестве идентификатора в соответствующей таблице, но данный факт не существенен для модели данных. Мы также можем видеть, что Но- мерКлиента является для пользователей неунпкальным идентификатором. Более того, семантическая объектная диаграмма указывает на тот факт, что сущест- вует семантическая группа атрибутов под названием Адрес, Эта группа содер- жит другие атрибуты, составляющие вместе адрес. Существование этой группы станет для нас важным при разработке форм и отчетов. Наконец, семантиче- ская объектная диаграмма показывает, что конкретный ТОВАР может быть вклю- чен более чем в один ЗАКАЗ, но в каждом заказе этот товар может появиться только в одной строке. Этот факт невозможно указать на диаграмме «сущность- связь». В конечном счете следует решить, какой из рисунков — Б.ЗЗ пли Б.34 — дает лучшее представление о том, что должно содержаться в базе данных. Многие находят, что рамки, очерченные вокруг семантических объектов, и скобки, заклю- чающие в себе групповые атрибуты, помогают более четко представить общую картину модели данных.
Вопросы группы I 841 Вопросы группы I 1. Объясните, почему модель «сущность—связь» и семантическая объектная модель похожи на линзы. 2. Дайте определение семантического объекта. 3. Объясните разницу между именем класса объекта и именем экземпляра объекта. Приведите примеры для обоих случаев. 4. Что требуется для того, чтобы набор атрибутов был достаточным описанием? 5 Объясните, что понимается под словосочетанием отдельный феномен в опре- делении семантического объекта. 6. Объясните, почему отдельная строка заказа не является семантическим объектом. 7. Назовите три типа атрибутов. 8. Приведите примеры атрибутов следующих типов: 1) простой однозначный атрибут; 2) групповой однозначный атрибут; 3) простой многозначный атрибут; 4) групповой многозначный атрибут; 5) простой объектный атрибут; 6) многозначный объектный атрибут. 9 Что такое минимальное кардинальное число? Как оно используется? Какие типы атрибутов имеют минимальное кардинальное число? 10. Что такое максимальное кардинальное число? Как оно используется? Какие типы атрибутов имеют максимальное кардинальное число? 11. Что такое парные атрибуты? Для чего они нужны? 12. Что такое идентификатор объекта? Приведите пример простого и группо- вого атрибутов, идентифицирующих объект. 13. Дайте определение домена атрибута. Какие бывают типы доменов атри- бутов? Почему необходимо семантическое описание? 14. Что такое представление семантического объекта? Приведите пример объ- екта и двух его представлений, отличный от того, который дан в тексте. 15. Приведите пример простого объекта, отличный от того, который дан в при- ложении Б. 16 Приведите пример композитного объекта, отличный от того, который дан в приложении Б. Покажите, как представить этот объект с помощью отно- шений 17 Приведите пример составного объекта со связью 1:1, отлпчнын от того, ко- торый дан в приложении Б. Покажите, как представить этот объект с по- мощью отношений.
842 Приложение Б. Семантическая объектная модель 18. Приведите пример составного объекта си связью 1:N, отличный от юю, который дан в приложении Б. Покажите, как представить .hoi объект с по- мощью отношений. 19. Приведите пример составного объекта со связью М:1, отличный от того, который дан в приложении Б. Покажите, как представить этот объект с по- мощью отношений. 20. Приведите пример составного объекта со связью M:N, отличный от того, который дан в приложении Б. Покажите, как представит ь этот объект с по- мощью отношений. 21. Приведите пример гибридною объекта (случай 1 в табл. Б 1), отличный от того, который дан в приложении Б. Покажите, как представить этот объект с помощью отношений. 22. Приведите пример гибридного объекта (случай 2 в табл. Б.1), отличный от того, который дан в этой главе. Покажите, как представить этот объект с помощью отношений. 23. Приведите пример одного ассоциированного объекта и связанных с ним объектов, отличный от тех примеров, которые даны в этой главе. Покажи- те, как представить эти объекты с помощью отношений. Считайте, что ас- социированный объект имеет свой собственный идентификатор. 24. Ответьте на предыдущий вопрос, по уже в предположении, что у ассоции- рованного объекта нет собственного идентификатора. 25. Приведите пример родительского объекта, имеющего по меньшей мере два взаимоисключающих подтипа. Покажите, как представить эти объекты с помощью отношений. Используйте атрибут-указатель типа. 26. Приведите пример родительскою объекта, имеющего по меньшей мере два подтипа, не исключающих друг друга. Покажите, как представить эти объ- екты с помощью отношений. Используйте атрибут-указатель типа. 27. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена простым объектом. Покажите, как пред- ставить этот объект с помощью отношения. 28. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена композитным объектом. Покажите, как представить этот объект с помощью отношений. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена одной из форм составного объекта. Пока- жите, как представи ть эти объекты с помощью отношений. 30. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена гибридным объектом. Классифицируйте получившийся объект в соответствии с табл. Б 1 и покажите, как предста- вить его с помощью отношений.
Вопросы к проекту FiredUp 843 31. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена ассоциативными объектами Покажите, как представить эти объекты с помощью отношений. 32. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена объектами вида родитель-подтип Пока- жите, как представить эти объекты с помощью отношений. 33. Приведите пример формы с данными о вашем общежитии, которая могла бы быть адекватно представлена объектами вида архетип—версия. Покажи- те, как представить эти объекты с помощью отношений. 34. Укажите сходства модели «сущность—связь» и семантической объектной модели. 35. Укажите основные различия между моделью «сущность—связь» и семаи тической объектной моделью. 36. Объясните, почему сущности, как они определены в модели «сущность— связь», не существуют в действительности. 37. Покажите, как модель «сущность—связь» и семантическая объектная мо- дель будут интерпретировать данные, содержащиеся в форме SALES-ORDER на рис. Б.20, а, и укажите основные различия. Вопросы к проекту FiredUp Рассмотрим ситуацию, обсуждаемую в конце главы 1. Предположим, что фирма FiredUp разработала линию из трех горелок: FiredNow, FiredAlways и Fired At Camp. Предположим далее, что фирма продает запасные части для каждого типа горелок, а также производит их ремонт В одних случаях ремонт является бесплатным, по- скольку выполняется в течение гарантийного срока, в других случаях взимается только стоимость деталей, в третьих взимается стоимость деталей н работы. Фирма FiredUp желает вести учет всех этих данных. Когда владельцев фирмы спросили о подробностях, они составили следующий список: КЛИЕНТ- Имя, Улица, Дом, Квартира, Город, Штат, Индекс. Страна, АдресЭлПочты, Телефон ГОРЕЛКА: СерийныйНомер, Тип, ДатаИзготовления, ИнициалыПроверяющего СЧЕТ-ФАКТУРА: НомерСчета, Дата, Клиент (со списком проданных товаров п ука- занием их стоимости), Сумма РЕМОНТ: НомерРемонта, Клиент, Горелка, Описание (со списком деталей, использо- ванных при ремонте, и указанием их стоимости, если таковая взимается). Сумма ДЕТАЛЬ: Номер, Описание, Стоимость, Цена 1 Создайте набор соматических объектов для базы данных фирмы FiredUp. Задайте на свое усмотрение минимальное н максимальное кардинальные числа для всех атрибутов. Обоснуйте каждое кардинальное число. Исполь- зуйте столько типов семантических объектов, сколько ечтаеге н\ иным, по не и< ноль (уте нодпшы.
844 Приложение Б. Семантическая объектная модель 2. Преобразуйте семантическую объектную диаграмму, созданную нами при ответе на вопрос 1, в набор отношений, находящихся в доменно-ключевой нормальной форме. Для каждого отношения укажите первичный ключ, ключи-кандидаты, если такие есть, и внешние ключи. Укажите ограниче- ния ссылочной целостности. Если необходимо, сделайте (и обоснуйте) свои предположения относительно семантики приложения. 3. Модифицируйте свой ответ на вопрос 2, допустив наличие ненормали- зованных отношений, если вы считаете, что такие отношения в каких-то случаях представляют более удачное решение. В каждом случае обос- нуйте свой выбор в пользу ненормализованного отношения. Если необхо- димо, сделайте (и обоснуйте) своп предположения относительно семанти- ки приложения. ?*** 1.1 8® & г® -ч же я ат у. ЖЕ 19! А isntu as.’jtxi «М
Алфавитный указатель #, символ UML, 99 &, в SQL, 569 , в Oracle, 441 -, символ UML, 99 /, в Oracle, 441 +, символ UML, 99 INF, 184 2NE 184 3NF, 186 4NF, 190 5NF, 191 А abstract data type, 760 abstraction, 553 ACID, 409 Active Data Objects, 558 active repository, 427 adChar, константа, 563 ADO, 546,558 adParamlnput, константа, 563 ADT, 760 after-images, 422 alternate key, 217 ANSI, 60 Apache Tomcat, 664 Append, метод, 563 applet, 652 application failure, 484 application program, 39 archetype object, 836 archcfypc/version object, 836 ARCIHVELOG, режим, 484 AS, ключевое слово, 459 association object, 829 atomic, 398 attribute, 68, 739 AU 1 O INCREMENT, ключевое слово 662, 680 axe, 706 В before-image, 422 binary' relationship, 69 BK/NF, 188 Boycc-Codd normal form, 188 bulk-logged recovery, 533 c callable statement, 656 callback, 744 candidate key, 187 candidate keys, 177 cascade deletions, 223 cascading updates, 223 categorization clusters, 87 categorization relationships, 87 category entity, 87 checkpoint, 423 circular list, 779 class attribute, 98 class library, 740 client, 692 client-server system, 692 collection, 555 column object, 751 COLUMN, ключевое слово, 450 Command, объект, 559, 563 CommandText, свойство, 563
846 Алфавитный указатель Command, объект (продолжение) Execute, метод, 563 Parameters, коллекция, 563 Append, метод, 563 CommandText, свойство, 563 complete backup, 533 complete category cluster, 88 composite attribute, 68 composite identifier, 69 composite key, 177 composite object, 812 compound object, 815 conceptual schema, 61 concurrent transactions, 399 concurrent update problem, 401 connection relationship, 83 Connection, объект, 559 Open, метод, 561 consistent backup, 485 constraint, 192 constructor, 740 control files, 484 correlated subquery, 356 Count, свойство, 562 CREATE TABLE, оператор, 497 CreateObject, метод, 560 cube, 706 CurrVal, метод, 446 cursor concurrency, 525 cursor variable, 459 CursorType, свойство, 561 D data administration, 395, 724 data administrator, 724 data consumer, 555 data definition language, 267 data dictionary, 126 data manipulation language, 267 data mart, 722 data owner, 728 data proponent, 727 data provider, 555 data reader, 623 data repository, 426 data source, 547 data sublanguage, 266 data warehouse, 714 database administration, 395 database save, 421 datafiles, 483 dataset, 622, 623 DDL, 267 dead transactions, 485 deadlock, 404 deadly embrace, 404 DECLARE CURSOR, оператор, 526 deletion anomaly, 180 dependency graph, 365 Description, свойство, 563 destructor, 740 determinant, 178 DICT таблица, 472 differential backup, 533 dimension, 706 dirty read, 410 discriminator, 88 distinct identity. 804 distributed database system, 696 distributed system. 696 Distributed Transaction Service, 700 distributed update conflict, 699 DKNF, 183. 191 DML, 267 Document Type Declaration, 593 DOM, 643 domain, 80, 91, 192, 809 domain experts, 119 domain/key normal form, 183, 191 drill down, 717 driver, 548 driver manager, 548 DriverManagcr, класс, 654 getConneciion, метод, 654 DROP, оператор, 449 DTD, 593 DTS, 700 dynamic cursor, 412 в J I l
Алфавитный указатель 847 Е encapsulated structure, 739 Enterprise Oracle, 486 entity, 67 entity class, 67, 94 entity instance, 67 entity-relationship diagram, 71 entity-relationship model, 65 E-R model, 65 ER-diagram, 71 Error, объект Description, свойство, 563 Errors, коллекция, 559, 562 exclusive lock, 403 Execute, метод, 563 executeQuery', метод, 655 executeUpdate, метод, 655 exit, команда, 442 explicit lock, 402 extended E-R model, 65 extensible Style Language for Transformations, 595 extent, 768 external schema, 61 F Fagin, R., 183 FETCH, оператор, 511 field, 555 Field, объект, 559 Name, свойство, 562 Value, свойство, 562 Fields, колекция Count, свойство, 562 Ficlds(O), свойство, 562 Fields, коллекция, 559, 562 fifth normal form, 191 file data south. 551 file sharing, 693 first normal form, 184 flat file, 775 foreign key, 82, 221 form, 39 FOHM.tef, 571 formal interface, 119 forward eng neering, 384 forward only cursor, 411 fourth normal form, 190 full recovery; 533 G generic entity, 87 get, метод HTML, 572 getCohimnCount, метод, 655 gclCoIumnName, метод, 655 getConnection, метод, 654 getMetaData, метод, 655 group attribute, 804 group identifier, 808 growing phase, 404 H HAS-A relationship, 71 head, 795 horizontal fragment, 696 horizontal pai tition, 696 HttpScrvlet, класс, 663 hybrid object, 823 hypercube, 706 1 I Accessor, интерфейс, 557 1 Columns] nfo, интерфейс, 557 ID-dependent entity, 73 IDEF1X, 66 identifier, 69 identifying connection relationships. 84 identity seed, 257 IF, 66 ILS, 558 immutable, 767 implementation, 556, 739 implicit lock, 402 IN ОПТ, ключевое слово, 458 IN, ключевое e юно. 457 inconsistent backup, 485 inconsistent lead problem, 101 m> icmcnt, 25
848 Алфавитный указатель index, 777 index set, 781 INDEX, ключевое слово, 450 indexes, 780 information engineering, 66 inheritance, 78, 740 insertion anomaly, 180 instance failure, 484 intei face, 556, 739 internal schema, 61 Internet Information Server, 558 intersection record, 792 intersection table, 236 inverted list, 780 IRowSet, интерфейс, 557 IsObject, функция, 566 J Jakarta, 664 Java, 651 Java bean, класс, 669 Java Server Pages, 663 Java virtual machine, 652 JDBC, 651 join, 288 JSP, 663 К key, 176, 192 keyset cursor, 412 L left outer join, 294 level, 708 linked list, 777 LIST, команда, 439 localhost в MySQL, 682 lock granularity, 403 LOCK TABLES, оператор, 682 locking hints, 526 LockType, свойство, 561 log, 421 logical model, 362 logical unit of work, 398 lost uptime problem, 401 LUW. 398 M maintenance plan, 534 many-to-many relationship, 201 many-to-one relationship, 201 materialized view, 699 maximum cardinality, 71 measure, 706 media failure, 484 member, 706 method, 554, 739 Microsoft, 546 Microsoft Transaction Server, 556 minimum cardinality, 71 mixed partition, 697 mixed security, 527 modification anomaly, 180 MODIFY, оператор, 450 MoveFirst, метод, 566 MovcNcxt, метод, 566 MTS, 556 multiplexing, 484 multi-tier driver, 549 multi-value attribute, 811 ti multi-value dependency, 189 multi-valued attribute, 68 mutable, 767 MySQL, 652,678 N Name, свойство, 562 nested table, 751 NextVal, метод, 446 NOARCHIVELOG, режим, 484 NOLOCK, блокировочная подсказка, 527 non-object attribute, 811 nonrcpeatable read, 410 non-specific relationship, 85 nonunique, 69 non-unique key, 1 f6 normal form, 183
Алфавитный указатель 849 not-type valid XML document, 594 null value 256 О object, 740 object class, 554, 740 object diagram, 805 object identifier, 808 object instance, 740 object link, 805 Object Management Group, 94 object-oriented DBMS, 738 object-oriented programming, 739 object-relational DBMS 738 occurrence table, 798 ODBC, 544 ODBC conformance level, 549 offline ReDo files, 484 OID, 761 OLAP, 706 OLAP cube, 706 OLE, 553 OLEDB, 544,553 OMG, 94 On Error Resume Next, оператор, 566 one-to-one relationship, 198 on-line analytic processing, 706 online ReDo files, 484 OODBMS, 738 OOP, 739 Open Database Connectivity standard, 543 Open, метод, 561 OPTIMISTIC, поведение курсора, 526 optimistic locking, 405 optimizing, 426 Oracle, 435 Oracle Database Confignialion Assistant, мастер, 436 Oracle Loader, 486 Oracle Recovery Manager, 486 OUT ключевое слово, 458 outer join, 293 P paired attributes 807 Parameter, объект, 563 Parameters, коллекция, 559, 563 Append, ме год, 563 parent object, 832 parent/subtype object, 832 parsing, 643 passive repository, 427 persistent, 740 pessimistic locking, 406 phantom read, 410 physical description, 809 physical model, 365 PL/SQL, 329 polymorphism, 740 post, метод HTML, 572 prepared statement, 656 primary key, 177, 187 private, 99 processing rights and responsibilities, 413 project scope, 116 property, 68, 554 protected, 99 public, 99 Q Query Analyzer, 498 R read committed, 410 READ COMMITTED, уровень изоляции, 525 read only, 474 read uncommitted, 410 READ UNCOMMITTED, уровень изоляции, 525 READ ONLY, поведение курсора, 525 recordset, 554 RecordSet. объект, 559, 561 CursorType, свойство, 561 Lock Гуре, cnoiicTuo, 561 MovcI'irst, метод. 566 MoveNext. метод, 566 Update, метод. 579
850 Алфавитный указатель recovery model, 533 recursive relationship, 249 recursive relationships, 72 ReDo files, 484 referential integrity actions, 223 referential integrity constraint, 182 relation, 172 relationship, 69 relationship class, 69 relationship degree, 69 relationship instance, 69 REPEATABLE READ, уровень изоляции, 525 repeatable reads, 410 replication, 535 report, 39 resource locking, 402 Response, объект, 579 Write, метод, 579 ResultSet, объект getMetaData, метод, 655 reverse engineered data model, 362 reverse engineering, 119,362 right outer join, 294 ring, 779 RMAN, 486 rollback, 421 rollback segment, 474 roll forward, 421 row identifier, 764 row object, 751 rowset, 554, 557 rsMeta, объект, 655 getColumnCount, метод, 655 getColumnName, метод, 655 s SAX, 643 schema, 60 SCN, 474 SCROLL LOCK, поведение курсора, 526 scrollable cursor, 412 second normal form, 184 semantic description, 809 semantic object, 803 semantic object al tribute, 805 semantic object diagram, 805 semantic object model, 62, 802 semantic object view, 810 sequence, 446 sequence set, 781 sequential list, 776 serializable, 404,410 SERIALIZABLE, уровень изоляции, 525 server, 692 Server, объект CreateObject, метод, 560 service provider, 557 servlet, 652 shared lock, 403 shrinking phase, 404 simple attribute, 804 simple object, 811 simple recovery, 533 single-tier driver, 548 single-value attribute, 811 slice, 706 snapshot, 699 snowflake schema, 710 SPARC, 60 SQL Access Group, 547 SQL conformance level, 550 SQL injection attack, 419 SQL view, 316 SQDPIus, 437 SQL-представлеиие, 316 star schema, 710 statement level consistency, 409 Statement, объект, 655 executeQuery, метод, 655 executeUpdate, метод, 655 static cursor, 412 stored procedure, 338 strong entity, 73 stylesheet, 596 subquery, 287 subtype, 76 subtype object, 832 Sun,’ 651 supertable, 765 supertype, 78 Я IS gf £7*7
Алфавитный указатель 851 supertype object, 832 surrogate key, 219 swizzling, 745 System Change Number, 474 system data source, 551 system requirements, 117 T table data provider, 556 teleprocessing, 691 teleprocessing system, 691 ternary relationship, 251 third normal form, 186 Tomcat, 664 transaction isolation level, 410 transaction level consistency, 409 transactions, 398 transient, 740 transitive dependency, 186 trigger, 329 T-SQL, 329 tuning, 426 two-phase commit, 700 two-phase locking, 404 two-way linked list, 779 type domain, 93 type-valid XML document, 594 u UML, 66,94 unique, 69 unique key, 176 UNIQUE, ключевое слово, 450 UNLOCK TABLES, оператор, 682 Update, метод, 579 user data source, 552 user group. 414 user view, 61,838 USER^SOURCE, 1а6лнца, 473 USER, I ABLES, таблица, 473 USER TRIGGERS, ыблнца, 473 V Vahit, ret /It' tho ,62 vartahle length array 751 version object, 837 vertical fragment, 696 vertical partition, 696 view, 316,810 w wait-for graph, 476 weak entity, 73 Write, метод, 579 X X/Open, 547 XML-документ допустимый по типу, 594 недопустимый по типу, 594 XPath, 642 XQuery, 643 XSLT, 595 Y Year, тип данных, 680 A абстрактный тип данных, 760 абстракция, 553 администратор данных, 724 алм111Шсгрн|х>ва1П1е базы данных, 395 администрирование данных, 395, 724 альтернативный ключ, 217 амперсанд, 569 аномалия вставки, 180 модификации, 180 удаления, 180 апплет, 652 архитектура с совместным использованием файлов. 693 ассоциативный сх'тьекг, 829 <нака со пеганкой SQ1 кода, 419 атрибут. 68.739 з.1кры1ып. 99 занипцеппып. 99 ккта, 98
852 Алфавитный указатель а 1 рибут (продо. i.wemte) композитный, 68 многозначный, 68,811 пообъектный, 811 однозначный, 811 открытый, 99 семантического объекта групповой, 804 объектный, 805 простой, 804 атрибуты парные, 807 Б база данных безопасность, 413 для рабочей группы, 44 много! юльзовательская, 4 0 однопользовательская, 40 организационная, 43, 44 персональная, 44 базовый домен, 93 безопасность базы данных, 413 библиотека классов, 740 бинарная связь, 69 бинарное дерево, 781 блокировочные подсказки, 526 В вертикальный раздел, 696 вертикальный фрагмент, 696 виртуальная машина Java, 652 владелец данных, 728 вложенная таблица, 751 вложенный запрос, 287 внешнее соединение, 293 внешний ключ, 82,221 внешняя схема, 61 внутренняя схема, 61 восстановление, 483 вторая нормальная форма, 184 выборочная модель восстановления, 533 вызываемый оператор, 656 Г гибридный обьекц 823 гиперкуб, 706 горизонтальный раздел, 696 горизонтальный фрагмеш, 696 готовый опера гор, 656 граф зависимостей, 365 график ожидания, 476 группа вложенная, 815 групповой атрибут, 804 групповой идентификатор, 808 д данные администрирование, 724 двусвязиый список, 779 двухфазная фиксация, 700 дерево бинарное, 781 деструктор, 740 детерминант, 178 диаграмма объектная, 805 диаграмма сущность—связь, 71 динамический курсор, 412 дискриминатор, 88 диспетчер драйвера, 548 дифференциальная резервная копия, 533 документ XML допустимый по типу, 594 недопустимый по типу, 594 домен, 80, 91, 192 базовый, 93 семантическое описание, 809 типовой, 93 физическое описание, 809 домен, 809 доменно-ключевая нормальная форма, 183, 191 домены, 152 драйвер, 548 JDBC, 652 многоуровневый, 549 одноуровневый, 548 ааа
Алфавитный указапгль 853 Ж журипл, 421 3 lanepinaioiniiii ipniicp, 329,465 J.HIH! ИМО! 1Ь мпо><> тачная, 189 iран инициал, 186 шкрысый атрибут, 99 iJMenialoiHiin ipiinep, 329,465 ынрос вложенный, 287 •ащищепный aipuGyr, 99 И пдстификасор, 69 групповой, 808 KOMiio.iiiiiibiii, 69 neyiniiwiiaibiii, 69 семантического объект, 808 уника ii.iii.iii, 69 нлеИ1Ифпка1ор строки, 764 ндс11111фнкациопно lanin имая сутпосп», 73 идентифицирующие спя ih нрипадлежиосш, 84, 132 нзм< 1 тем ы и < >б ьск ।, 767 и 1М< реп ис, 706 HiHiepiiipoiiainihiO список, 780 индекс, 507, 777, 780 класкри юпанпый, 508 1 К'клас г<| iHBOiiai н । ы й, 08 И11дг|« иый набор, 781 индексы, 449 инкапсулированная с ipyiciypa, 739 ишсрфсйс, 556 объекта, 739 формальный, 119 информационная иная не рпя, 66 информа1Н1о||11.1>1 лапка, 722 информационно! хранилище, 714 информационный р< по in Юрий, 118 исключения обработка, 659 нс ючпик данных, .547, .5.51 ноль юна 1слы кий, 552 с ш и'мный, 551 файловый, 551 К кардинальное чпе ло максимальное, 71,806 Кардинальны н„ 806 максимальная, 71 мпппмальМя, 71 кас кадиос обповле ине, 221 каскадное улАцсчше, 223 ка1с|ор|ылы1ыс класн'ры, 87 KaiiHopibuibiibii' спя т, 87 капчориальпый класс ср полпыи, 88 icaieropnn, 141 класс, 554 обьсшпыи, 554 < । язей, 69 <ем,>н нечеткою объекта, 804 сущнос ич1, 67 кла< с сущнос । <41, 94 клпеш, 692 КЛШЧН ы рш'рпая щи н*ма, 692 ключ, 176, 192 .ми lepiiaiiiiiiibiii 217 iiiieiiniiiii, 82,221 комно.ипный, 177 ||еувпк<1ЛЫ1ь»1 176 н< рвичнып, 177, 187 cyppoi.iiiibin, 219 уникальимн, 176 ключечюй курс ор, 4 12 ключ Кандида), 177, 187 коллекция, 555 кольцепон синеок, 779 кольцо, 779 команда, 559 компоiniiii.iH aipiKiyi, (> komho.iii।in.iii ключ, 177 комно.ипный обьеш, 812 Копс ipyiciop, 740 коп I рольные файлы, 48И копфлпм р.п пред! 'кчшьхх обновлений, 699
854 Алфавитнь|иука4йгель концептуальная схема, 61 коррелированный подзапрос, 356 куб. 706 куб OLAP, 706 курсор динамический, 412 ключевой, 412 последовательный, 411 статический, 412 Л левое внешнее соединение, 294 логическая модель, 362 локальная сеть, 41 м максимальное кардинальное число, 71 максимальная кардинальность, 71 Мартин, Джеймс, 66 массив переменной длины, 751 материализованное представление, 699 мера, 706 мертвые транзакции, 485 метаданные, 35 метка транзакции, 532 метод, 554, 739 минимальная кардинальность, 71 многозначная зависимость, 189 многозначный атрибут, 68, 811 многоуровневый драйвер, 549 моделирование данных описание процесса, 116 модель ANSI/SPARC, 60 логическая, 362 сущность-связь, 65 физическая, 365 модель восстановления, 533 выборочная, 533 полная, 533 простая, 533 модель данных реконструированная, 362 модель сущность—связь расширенная, 65 моментальны!! снимок, 699 мультиплексирование, 484 н набор индексный, 781 11 ос л едова-i е л ы i ы й, 781 набор данных, 622, 623 набор записей, 554, 559 набор строк, 554, 557 надтаблица, 765 надтип, 78 наследование, 78, 740 настройка по адресам, 745 пеидентифицнрующие связи принадлежности, 83, 134 неизменяемый объект, 767 пообъектный атрибут, 811 несогласованная резервная копня, 485 неспецифические связи, 85, 137 неуникальпый ключ, 176 нормальная форма, 183 вторая, 184 доменно-ключевая, 183, 191 первая, 184 пятая, 191 третья, 186 четвертая, 190 нормальная форма Бойса-Кодда, 188 О обработка исключений, 659 обратный вызов, 744 объект ассоциативный. 829 вида архетип-версия, 836 вида родитель-подтип, 832 временный, 740 ///////*> в 1И li в И ч HlViAXXXxvw гибридный, 823 изменяемый, 767 композитный, 812 надтипа, 832 неизменяемы и, 767 ООП, 740
Алфавитный указатель 855 объект (продолжение) полтина, 832 постоянный, 740 простой, 811 родительский, 832 семантический, 803 составной, 815 объект-архетип, 836 объект-версия, 837 объект-столбец, 751 объектная ссылка, 805 объектно-ориентированная СУБД, 738 объект! lo-opnei 1TI 1рова| и юс программирование, 739 объектно-реляционная СУБД, 738 объектный идентификатор, 808 объектный класс, 554, 740 ограничение, 192 ограничения ссылочной целостности, 182 однозначный атрибут, 811 одноуровневый драйвер, 548 ООП, 739 ООСУБД, 738 оперативная аналитическая обработка данных, 706 оператор вызываемый, 656 готовый, 656 ось, 706 отдельный феномен, 804 открытый атрибут, 99 отношение, 172 пересечения, 822 отчет, 39 отчеты, 118 охват проекта, 116 п параметр, 559 параметрическое разбиение, 717 парные атрибуты, 807 первая нормальная форма, 184 первичный ключ 177, 187 п> |в мт иная кур< <>р 459 "им кий файл, 775 поведение курсора, 525 оптимистическая блокировка, 526 пессимистическая блокировка, 526 только чтение, 525 подзапрос коррел и рова 1 н 1 ы i ।, 356 подтаблица, 765 под inn, 76 подтипы, 141 подъязык данных, 266 поле, 555, 559 полиморфизм, 740 полная модель воссшповлеппя, 533 полная резервная копня, 533 полный катет орнальнып кластер, 88 пользовательский источник данных, 552 пользовательское представление, 61 838 порождающая сущность, 87 порт 80, 664 8080, 664 последовательное! ь, 446 последовательный курсор, 411 последовательный набор, 781 последовательный список, 776 поставщик данных табличных, 556 услуг, 557 поставщик данных, 555 поставщик табличных данных, 556 hoiрсби(ель данных, 555 прана п обязанное in по обработке, 413 правое внешнее соединение, 294 предваряющий rpinrep, 329,465 предметные специалисты, 119 представление, 316, 810 материализованное. 699 иользон.нельское, 61 соматического объекта, 810 iipoi рамма прикладная. 39 простая модель not становления. 533 lipin 1ой aipnOvi 804 нрос юн обьект, 811
8S6 Апфаеи ный указатель процедуры обеспечения ссылочной целостности, 223 пустое значение, 256 пятая нормальная форма, 191 Р раздел вертикальный. 696 горизонтальный. 696 смешанный, 697 распорядитель данных, 727 распределенная система, 696 реализация, 556, 739 резервная копия дифференциальная, 533 несогласованная, 485 полная, 533 согласованная, 485 резервное копирование, 483 реконструированная модель данных, 362 реконструкция, 119,362 рекурсивная связь, 72, 249 репликация, 535 родительский объект, 832 роль, 415 С сбой носителя, 484 приложения, 484 экземпляра, 484 свойство, 68,554 связный список, 777 связь, 69 бинарная, 69 категориальная, 87 «многие к одному», 201, 820 «многие ко многим», 70, 201, 822 неспецифическая, 85 «один к одному», 70, 198, 819 «один ко многим», 70, 820 принадлежности, 71, 83 идентифицирующая, 84 неидеитифици рукмцая, 83 свя 11» (n/MMlOJIDT,llUf) рекурсивная, 72, 249 lepnapibiB, 251 шиа «ИМЕЕТ», 71 сшменг откша, 474 семантическая обьектиая диаграмма, 805 семантическая обьектиая модель, 62,802 ссмашичсский обьект, 803 представление, 810 семантический обьектпый атрибут, 805 семантическое описание домена, 809 сервер, 692 сервлег, 652, 653 сериализуемость. 404, 410 сеть локальная, 41 сильная сущность, 73 сильный пароль, 417 синтаксический анализ, 643 система распределенная, 696 распределенных баз данных, 696 система удаленной обработки, 691 системные требования, 117 системный источник данных, 551 слабая сущность, 73, 85 словарь данных, 126 словарь метаданных, 472 слой, 706 смертельное объятие, 404 смешанная безопасность, 527 смешанный раздел, 697 снимок моментальный, 699 согласованная резервная копия, 485 соединение, 288 внешнее, 293 левое внешнее, 294 правое внешнее, 294 составной объект, 815 список двусвязный, 779 инвертированный, 780 кольцевой, 779 последовательный, 776 связный, 777
Алфавитный указатель 857 805 62 802 805 Ю9 ссылка объектная, 805 ссылочная целостность ограничения, 182 статический курсор, 412 степень связи, 69 СУБД объектно-opiicin прошитая, 738 суррогатный ключ, 219 «сущность—связь» диаграмма, 71 сущность, 67 в IDEF1X, 80 идентификационно зависимая, 73 порождающая, 87 сильная, 73 слабая, 73 сущность-категория, 87 схема, 60 внешняя, 61 внутренняя, 61 концептуальная, 61 схема звезда, 710 схема снежинка, 710 считыватель данных, 623 т таблица пересечения, 236 таблица стилей, 596 тернарная связь, 251 тип данных абстрактный, 760 типовой домен, 93 транзакции мертвые, 485 трап «акция устойчивая, 409 транзитивная зависимость, 186 третья нормальная форма, 186 триггер, 329 AFTER, 329 BEFORE, 329 INSTEAD OI, 329 завершающий, 329, 465 триггер (продолжение) замещающий, 329, 465 предваряющий, 329, 465 триггер AFTER, 465 Гринер BEFORE, 465 триггер INSTEAD OF 465 тройственная схематическая модель, 60 У удаленная обработка, 691 уникальный ключ, 176 уровень, 708 уровень изоляции воспроизводимое чтение, 410, 525 завершенное чтение, 410, 475, 525 незавершенное теине, 410, 525 сериализуемость, 410,476, 525 только чтение, 474 477 уровень изоляции транзакции, 524 уровень соотве гс I вия ODBC, 549 SQL, 550 Ф Фаги и, R, 183 фаза проектирования, 46 реализации, 47 формулирования требований, 45 файл плоский, 775 файловый источник данных, 551 файлы данных, 483 файлы отката, 484 архивные, 484 онлайновые, 484 оффлайновые, 484 ткущие, 484 физическая модель, 365 физическое описание домена, 809 фиксация двухфазная, 700 форма, 39 форма и...и интерфейс, 119
858 Алфавитный указатель <|х>рмы, 118 фрагмент вертикал ы п>1 й, ,696 ropii3Oiпал ьны н. 696 X хранимая процедура, 338 Чен, Питер, 65 четвертая нормальная форма, 190 число изменений в системе, 474 член, 706 чтение воспроизводимое, 410 незавершенное, 410 • iTCi । нс (продолжение) завершенное, 410 э экземпляр объекта ООП, 740 связи, 69 семантического объекта, 804 сущности, 67 экстент, 768 Я язык манипулирования данными, 267 определения данных, 267 8 л-