ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ ИНДУСТРИАЛЬНЫЙ УНИВЕРСИТЕТ В.Ю. Радыгин Базы данных и СУБД Учебно-методическое пособие Москва 2011 УДК 004.65 ББК 32.81 Р15 Рецензенты: Е.А. Роганов, кандидат физико-математических наук, доцент, зав. каф. информационных систем и технологий Московского государственного индустриального университета; И.М. Белова, кандидат физико-математических наук, доцент Московского государственного индустриального университета Р15 Радыгин В.Ю. Базы данных и СУБД: учебно-методическое — М.: МГИУ, 2011. — 72 c. ISBN 978-5-2760-1960-4 пособие. Содержит изложение ряда теоретических понятий учебного кур са «Базы данных и СУБД», краткое описание языка SQL, общих принципов проектирования баз данных и информационных систем, примеры решения задач на построение запросов к реляционным ба зам данных, рекомендуемые к решению домашние задачи, несколько вариантов заданий на модификацию эталонного проекта и подроб ный разбор одного из них. Предназначено для студентов направлений «Прикладная математика и информатика», «Информатика и вычис лительная техника» и специальности «Математическое обеспечение и администрирование информационных систем». УДК 004.65 ББК 32.81 ISBN 978-5-2760-1960-4 © МГИУ, 2011 © Радыгин В.Ю., 2011 Оглавление Предисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Введение в теорию баз данных . . . . . . . . . . . . . . . . . . 1.1. Понятие баз данных . . . . . . . . . . . . . . . . . . . . . . . 1.2. История развития моделей и баз данных . . . . . . . . . . . 5 5 8 2. Иерархическая и сетевая модели данных . . . . . . . . . . . . 11 3. Реляционная модель данных . . . . . . . . . . . . . . . . . . . 3.1. Проектирование реляционных баз данных . . . . . . . . . . 3.2. Язык SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 25 44 4. Объектная модель данных . . . . . . . . . . . . . . . . . . . . . 4.1. Язык ODL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 62 5. Примеры решения задач . . . . . . . . . . . . . . . . . . . . . . 5.1. Задачи для самостоятельного решения . . . . . . . . . . . . 65 67 . . . . . . . . . . . . . 71 Список литературы и интернет-ресурсов Предисловие Учебное пособие подготовлено автором на основе многолетнего опыта чтения курсов «Базы данных и СУБД» и «Базы данных и экспертные си стемы» студентам Московского государственного индустриального универ ситета (направления «Прикладная математика и информатика» и «Инфор матика и вычислительная техника», а также специальности «Математиче ское обеспечение и администрирование информационных систем»). Кроме того, автор лично посвятил много лет деятельности, направленной на раз работку различных прикладных баз данных и построенных на их основе информационных систем. При разработке данного курса было использовано только свободное программное обеспечение. Его же рекомендуется применять и в процессе обучения. 1. Введение в теорию баз данных 1.1. Понятие баз данных. На сегодняшний день точного понятия базы данных не существует. В различных ситуациях под этим термином подразумевают разные вещи. Мы попробуем дать следующее абстрактное определение. Определение 1.1. База данных (БД) — это набор порций инфор мации, существующий в течение длительного времени. Данное определение очень обширно, поэтому в нашем случае этот тер мин будет немного усложнен. Мы будем работать лишь с компьютерными базами данных, то есть с такими, взаимодействие с которыми осуществля ется посредством специального управляющего программного обеспечения (в дальнейшем которое мы будем называть СУБД). Для создания полноценной компьютерной базы данных нужны три ос новные составляющие: сами данные; аппаратное обеспечение; программное обеспечение. Под программным обеспечением мы будем подразумевать все те сред ства, которые позволяют конечным пользователям получать доступ к дан ным и редактировать их. Кроме того, это программное обеспечение может решать и другие задачи, такие как, например: обеспечение безопасности данных, одновременный доступ и так далее. Весь этот комплекс программ обычно называют системой управления базами данных — СУБД. По мере развития баз данных количество решаемых системами управ ления задач постоянно увеличивается. На сегодняшний день СУБД — это сложный набор программного обеспечения, включающий в себя большое количество компонент. Требования, предъявляемые к ним, можно разде лить на три основных составляющих, а именно, современная СУБД долж на позволять пользователю работать: на ЭВМ разной архитектуры с установленными на них различными операционными системами; в компьютерных сетях разных типов, работающих по различным про токолам; с различными графическими и символьными системами представле ния информации. Основные функциональные возможности, предоставляемые конечному пользователю, современными СУБД включают в себя: поддержку логической модели данных (определение данных и опери рование с ними); 6 Введение в теорию баз данных восстановление данных (транзакции, журналирование, контрольные точки); управление одновременным доступом; конфиденциальность данных (безопасность с точки зрения несанкци онированного доступа); самостоятельную оптимизацию выполнения операции; другие функции (администрирование, статистика, распределение дан ных и т.д.). Поддержка логической модели данных подразумевает способы логи ческого представления информации в компьютерном хранилище, а также средства для поиска, добавления, редактирования и удаления необходимых порций данных. Восстановление данных подразумевает собой средства защиты базы данных от физических повреждений, вызванных чаще всего сбоями в ра боте аппаратного обеспечения. В частности, механизм транзакций позво ляет избежать ситуации, когда прерывается выполнения логически связан ной последовательности действий. При журналировании ведется запись всех выполняемых с хранящимися данными изменений, что позволяет в случае сбоя повторить или отменить выполнение незавершившихся опера ций. Контрольные точки позволяют вернуться к состоянию информации на определенный момент в прошлом. Данные механизмы будут рассмотрены подробно в последующих главах пособия. Управление одновременным доступом подразумевает возможность ра боты различных пользователей над одними и теми же (или разными) дан ными одновременно. Причем работа может состоять не только в просмотре этих данных, но и в их изменении. Конфиденциальность данных подразумевает наличие механимов рас пределения между всеми пользователями прав доступа к хранящейся в базе данных информации. Используемый для построения запросов к информации, хранящейся в базе данных, язык обычно не настолько тривиален, чтобы любой пользова тель всегда применял идеальные по производительности команды. Поэтому нормальная СУБД должна в той или иной мере уметь самостоятельно оп тимизировать все выполняемые пользователем операции. Причем наравне с автоматическими средствами оптимизации должны присутствовать и по луавтоматические (например, индексные структуры). Подробнее об этом будет говориться в последующих главах пособия. Прежде чем мы перейдем непосредственно к самим базам данных и системам их управления, важно понять, что не существует возможности сохранить всю информацию о том или ином предмете или явлении. Боль Понятие баз данных 7 шинство объектов физического мира неимоверно сложны по своей орга низации. Когда мы пытаемся описать какой-либо из таких объектов, мы на самом деле придумываем модель, соответствующую ему в нашем пони мании. Если объекты можно поделить на некоторые группы, удовлетворя ющие одинаковым моделям, то мы получаем ситуацию, когда внутри базы данных хранятся две группы сущностей: описания моделей объектов; записи, удовлетворяющие какой-либо из моделей и соответствующие различным представителям объектов. Но бывают ситуации, когда объекты настолько различны, что их нельзя классифицировать. Тогда база данных представляет собой набор из одних лишь моделей. Кроме того, говоря о моделях данных, мы должны понимать, что нуж но уметь хранить не только сами объекты, но и взаимосвязи между ними. Чтобы понять, для чего нужны взаимосвязи между объектами, представим, что мы придумали тот или иной способ хранить информацию о следующих вещах: о личных данных сотрудников некоторой фирмы и о существующих в этой же фирме отделах. Но что делать, если нам понадобится знать, какие сотрудники в каком из отделов работают? Для этого нам придется придумать способ хранения информации о соответствии каждого челове ка тому или иному подразделению. Причем зачастую люди могут занимать несколько должностей в разных отделах. Такие зависимости между объек тами будем называть взаимосвязями между ними. Существует несколько видов взаимосвязей: один к одному — 1:1; один ко многим — 1:M; многие ко многим — М:М. Поясним разницу. Если в нашей фирме в каждом отделе работает всего один человек и при этом каждый сотрудник занимает только одну долж ность, то сотрудник с отделом связаны как один к одному. Если каждый сотрудник по прежнему занимает только одну должность, но в отделе мо жет быть много сотрудников, то отдел с человеком находятся в связи один ко многим. И, наконец, если в отделе работает много людей и, вдобавок, каждый сотрудник может занимать много должностей в разных отделах (или в одном и том же отделе), то мы видим связь многие ко многим. Теперь мы можем дать более формальное определение модели. Определение 1.2. Модель данных — это абстрактное, самодо статочное, логическое определение объектов, связей между ними, применимых к ним действий (операторов) и прочих элементов, в совокупности составляющих абстрактную машину, с которой вза имодействует пользователь. 8 Введение в теорию баз данных За долгую историю развития баз данных было разработано много ва риантов организации информации. Основными являются: 1) иерархическая модель; 2) сетевая модель; 3) реляционная модель; 4) объектная модель. На сегодняшний день актуальны в основном реляционная и объектная модели. Причем, хотя наибольшее распространение получила первая из них, обе модели имеют широкие области применения в современном про граммном обеспечении. Подробнее о моделях данных будет рассказано в параграфах 2– 4. 1.2. История развития моделей и баз данных. В обычной жизни под базой данных можно понимать что угодно. Простейшим приме ром может служить любое упорядоченное книгохранилище. Поэтому имеет смысл обсуждать только этап истории человечества, связанный с появле нием компьютеров. Предшественником современных баз данных являлась файловая систе ма. Первые файловые системы появились в составе операционных систем (ОС) в 60-х годах. Со временем большинство файловых систем стало са мостоятельной единицей (с собственным названием). Многие современные файловые системы имеют иерархическую организацию и все они могут быть смело рассмотрены как предшественники баз данных. Действитель но, файловая система представляет возможность пользователю создавать последовательное хранилище для информации. Таким образом, мы имеем частичную реализацию первой из функций СУБД. Тем не менее, даже при рассмотрении задачи поиска информации становится ясно, что в серьез ных ситуациях файловая система не может быть хорошим решением для создания хранилища данных. История развития баз данных также начинается в 60-х годах прошло го века. Первая промышленная СУБД была разработана фирмой IBM в 1968 году и носила название IMS. Первые СУБД во многом унаследовали особенности файловых систем и в своей основе содержали сетевую или иерархическую модель представления данных. 70-е годы прошлого века стали временем бурного развития теоретических аспектов баз данных. В 1975 году был сформулирован стандарт сетевых баз данных, получивший название CODASYL в честь образованного в 1959 году одноименного кон сорциума. Стандарт включал в себя спецификации двух основных языков: языка описания данных (DDL) и языка манипуляции данными (DML). На основе данной спецификации было разработано большое количество сете вых СУБД, например, IDS/2, IDMS, DBMS32, db_Vista и другие. История развития моделей и баз данных 9 Все СУБД, базирующиеся на сетевых и иерархических моделях дан ных, имели большие недостатки в плане удобства построения запросов к ним. По этой причине в начале 80-х годов прошлого века в мире баз дан ных власть захватили реляционные системы. Их историю можно начать с опубликованной в 1970 году статьи Э.Ф. Кодда, предлагающей описывать данные при помощи таблиц, называемых отношениями (relations). Можно даже вернуться еще на год назад в 1969, когда тот же Эдгар Кодд сформу лировал свои 12 правил реляционных СУБД. Кстати, Эдгар Франк Кодд в это время работал в IBM. В 1979 году в свет вышла первая версия знаменитой СУБД Oracle (правда, уже носившая номер 2). Она еще не поддерживала транзакций и многих других механизмов современных баз данных, но зато стала пер вой коммерческой реляционной СУБД. Производитель Oracle компания RSI (раньше называющаяся SDL) смогла опередить в этом вопросе да же фирму IBM, в которой зародилась теория реляционных баз данных и у которой уже был разработан прототип реляционной СУБД System R. Зато в своей СУБД фирма IBM заложила основы будущего общеприня того языка запросов к реляционным базам данных — SQL (Structured Query Language). Правда, изначально он назывался SEQUEL (Structured English QUEry Language), но позднее был переименован по юридическим соображениям. В 1986 году институтом ANSI был принят первый стандарт языка SQL. В 1987 году он был одобрен ISO. В 1989 году доработанный вариант SQL/86 был принят как полноценный первый международный стандарт языка запросов к реляционным базам данных SQL. Он получил назва ние SQL/89. К сожалению, у него был ряд недостатков, важнейшими из которых были следующие два: во-первых, многие аспекты были описаны в языке как зависящие от реализации и, во-вторых, многие практически важные вещи просто отсутствовали. Поэтому в конце 1992 года был при нят новый международный стандарт языка SQL — SQL/92. В 1999 году стандарт языка SQL/92 был дополнен поддержкой регулярных выраже ний, рекурсивных запросов, триггеров, базовых процедурных расширений, нескалярных типов данных и некоторыми другими объектно-ориентирован ными возможностями. Тем самым был получен стандарт SQL:1999. Позд нее были приняты еще три стандарта: SQL:2003, SQL:2006, SQL:2008, расширяющие язык новыми возможностями. В 1987 году была показана первая демоверсия СУБД PostgreSQL (то гда еще просто POSTGRES), разработанная в департаменте Беркли, Ка лифорнийского университета, а в 1989 году вышла ее первая официальная версия. Параллельно с реляционными СУБД в середине 80-х годов начали 10 Введение в теорию баз данных развиваться объектные (объектно-ориентированные) СУБД. Их появле ние связано с развитием объектно-ориентированного программирования (ООП) и соответствующих языков. Как известно, первым объектно-ори ентированным языком программирования был разработанный в 1967 году язык Симула. Первоначально объектные СУБД разрабатывались только как поддержка различных систем САПР. В 90-х годах разработчики объ ектных баз данных стали обращать внимание и на другие области приме нения. В 1989 году был опубликован манифест систем объектно-ориенти рованных баз данных, в котором была предпринята попытка дать опреде ление системы объектно-ориентированных баз данных [4] . В 1993 году в сотрудничестве с OMG, ANSI, ISO и другими организациями был создан стандарт ODMG-93. Этот стандарт включает в себя средства для постро ения законченного приложения, которое будет работать (после перекомпи ляции) в любой совместимой с этой спецификацией объектной СУБД. В стандарт ODMG-93 вошли следующие разделы: язык определения объектов (ODL); язык объектных запросов (OQL); связывание с языком C++; связывание с языком Smalltalk. Тем не менее, смелые предсказания о вытеснении реляционных СУБД объектными не осуществились. Реляционные СУБД очень быстро были дополнены различными элементами ООП, что позволило им занять мно гие ниши, изначально рассматриваемые как вотчина объектных СУБД. На сегодняшний день большое распространение получили объектно-реляци онные технологии, основная идея которых заключается в автоматическом переходе от реляционной СУБД к объектам и наоборот. 2. Иерархическая и сетевая модели данных Первые базы данных были потомками файловых систем. Как следствие, они унаследовали и их иерархическую структуру, на основе которой была сформулирована иерархическая модель представления данных. Иерархическая модель представляет собой неоднородное дерево (груп пу деревьев), каждый узел которого обозначает некоторую сущность. Узел может иметь только одного родителя и ноль или более порожденных уз лов. Каждая связь «родитель-ребенок» означает наличие отношения один ко многим между соответствующими сущностями. Рассмотрим в качестве примера все те же отделы и сотрудников неко торой фирмы. Пусть в нашей фирме в отделе может работать много сотруд ников, но у каждого из них может быть только одна должность (во всей ор ганизации). Тогда такая модель данных легко описывается трехуровневой древовидной структурой (рис. 1–2). Вершина — это псевдоузел, соответ ствующий самой фирме. У вершины много узлов-детей, соответствующих отделам, у которых, в свою очередь, много листовых узлов-детей, описыва ющих сотрудников организации. Каждая ветка дерева образует одну связь между отделом и сотрудником. А каждое поддерево, начинающееся с от дела, — связь вида один ко многим между данным отделом и всеми его сотрудниками. Прежде чем говорить о преимуществах и недостатках иерархической модели данных, введем некоторые определения. Определение 2.1. Пусть какой-то класс объектов из жизни может быть представлен набором свойств (A1 , A2 . . . An). Тогда набор значений, описывающий определенного представителя дан ного класса, мы будем называть записью, а каждое из свойств A1 , A2 . . . An — атрибутом. Рассмотрим данное определение на примере. Пусть нашим объектом для хранения будет информация о собаках. Будем считать, что для дости жения поставленных перед базой данных целей достаточно знать кличку, породу, возраст и хозяина пса. Тогда кличка, порода, возраст и хозяин — это атрибуты, а, например, набор значений (Бобик, Дворняжка, 10, Дядя Федя) — это запись. Определение 2.2. Говорят, что атрибут (набор атрибутов) А функционально зависит от атрибута (набора атрибутов) B, если по заданному значению атрибута (набора атрибутов) B можно однозначно определить значение атрибута (набора атрибутов) A. Поясним данное определение на примере. Пусть у каждого хозяина бу дет только одна собака и при этом описание хозяев таково, что одного 12 Иерархическая и сетевая модели данных Рис. 1. Описание базы данных сотрудников-отделов с помощью иерархической модели: структура хозяина всегда можно отличить от другого. Говоря другим языком, описа ния хозяев не повторяются. Тогда если у нас есть база данных, содержащая записи указанного ранее вида, то одному хозяину всегда соответствует од на и та же собака. Если мы нашли запись вида: хозяин — «a», собака — «б», то мы никогда не найдем другой записи, где хозяину «a» соответствует собака не «б». Поэтому если известно, что в базе есть хозяин с каким-то именем, то мы точно знаем, что сможем однозначно назвать кличку его собаки. Это и означает, что атрибут «кличка» функционально зависит от атрибута «хозяин». Определение 2.3. Атрибут или набор атрибутов, от которого функционально зависят все остальные атрибуты записи, называ ется ключом. Если в предыдущем примере для каждой собаки возраст и порода все гда одни и те же, то можно сказать, что ключом является атрибут «хозяин», так как по нему мы сможем определить кличку собаки, её возраст и породу. Определение 2.4. Если атрибут (набор атрибутов) B функцио нально зависит от набора атрибутов (A1 , A2 . . . An), но не зависит Иерархическая и сетевая модели данных 13 Рис. 2. Описание базы данных сотрудников-отделов с помощью иерархической модели: пример заполнения функционально от каждого из них в отдельности, то атрибуты A1 , A2 , . . . An образуют составной ключ. Вернемся к примеру с отделами и сотрудниками. Предположим, что необходимо расширить базу данных для хранения информации о выпол няемых проектах. У каждого проекта имеется набор технических заданий, соответствующих его отдельным частям. С одним техническим заданием могут работать несколько сотрудников. У одного сотрудника может быть только одно техническое задание. Таким образом, имеется два набора свя зей вида один ко многим. Для описания каждого проекта введём новое де рево. Вершина дерева будет хранить описание полного проекта. У проекта будет множество дочерних узлов, соответствующих техническим заданиям. Причем у каждого технического задания, в свою очередь, будет множество дочерних узлов (листовых вершин), описывающих сотрудников (рис. 3). Рассмотренный пример демонстрирует основные преимущества и недо статки иерархической модели данных. Древовидная модель иерархической структуры данных определяет ос новные её преимущества. Наиболее значимые среди них — это простота и функциональная зависимость неключевых атрибутов от пути в дереве. 14 Иерархическая и сетевая модели данных Рис. 3. Структура поддерева проектов Недостатки модели также определяются её древовидной формой. Преж де всего, полная база данных сотрудников-отделов-проектов содержит два поддерева: отделы-сотрудники и проекты-сотрудники. Причем информа ция о сотрудниках хранится в каждом из них. Такое искусственное дубли рование возникает из-за неадекватности представления в иерархической модели данных взаимосвязей между объектами. Видно, что сотрудник на ходится в отношении многие к одному сразу с двумя сущностями: с от делами и с техническими заданиями. Подобная ситуация стала причиной необходимости дублирования. Кроме того, очевидно, что данная неадекват ность приведет и к другим проблемам. Например, несложно представить, насколько труднее обычного поиска по отделу будет поиск сотрудников, работающих в отделе «A» и над проектом «B». Дублирование потребуется и при возникновении связей вида многие ко многим. Также для иерар хической модели характерен такой недостаток древовидных структур, как сложность поиска в обратном направлении (снизу-вверх). Обобщая вышесказанное, можно заключить, что основными недостат Иерархическая и сетевая модели данных 15 ками иерархической модели являются: неадекватность представления взаимосвязей между объектами; необходимость частого дублирования информации; проблематичность поиска снизу-вверх. Данные проблемы отчасти решены в сетевой модели данных. Она под чиняется следующим правилам: 1) один и тот же объект может находиться с другими объектами более чем в одной связи; 2) допускаются отношения многие ко многим (M:M); 3) нет иерархии; 4) у объекта может не быть ни одной связи с другими объектами. В общем случае сетевая модель данных представляет собой произволь но ориентированный граф, возможно с петлями, узлы которого обозначают типы объектов, а дуги связи между ними. Как говорилось ранее, в начале 70-х годов прошлого столетия были сформулированы основные правила построения сетевых баз данных. Эти правила включали в себя стандарт языка определения данных DDL. Со гласно данному стандарту в сетевой СУБД различают следующие состав ляющие: элементы данных, агрегаты данных, записи и наборы. Элемент данных (ЭД) — наименьшая поименованная единица данных (аналог поля), с помощью которой осуществляется построение всех осталь ных структур. Имя элемента данных используется для его идентификации в схеме структуры данных более высокого уровня. Значение элемента дан ных может быть одного из встроенных типов: числовым (целым, веществен ным) или нечисловым (символьным, логическим). В некоторых приложе ниях может использоваться «неопределенное» значение элемента данных, которое говорит о том, что значение соответствующего свойства объекта не определено в БД. Агрегат данных — поименованная совокупность элементов данных внутри записи, которую можно рассматривать как единое целое. Имя агре гата используется для его идентификации в схеме структуры данного более высокого уровня. Агрегат данных может быть простым (рис. 4), если со стоит только из элементов данных, и составным (рис. 5), если включает в свой состав другие агрегаты. Запись — это поименованная совокупность элементов данных и/или аг регатов. Иными словами, запись — это агрегат, который не входит в состав никакого другого агрегата и может иметь сложную иерархическую структу ру, поскольку допускается многократное применение агрегации. Имя запи си используется для идентификации типа записи в схемах типов структур 16 Иерархическая и сетевая модели данных Рис. 4. Простой агрегат данных Рис. 5. Составной агрегат данных более высокого уровня. Экземпляр записи — это набор конкретных зна чений, которые принимают все входящие в запись агрегаты и элементы данных. Запись можно сравнить с узлами графа. Набор записей — это поименованная совокупность записей, образую щая двухуровневую иерархическую структуру подчинения: каждый тип на бора представляет собой отношение (связь) между двумя или несколькими типами записей. В силу иерархичности набора для каждого его типа одна запись объявляется «владельцем», а остальные записи —«членами», т.е. имеют место «запись-владелец» и «запись-член» (набора). Каждый экзем пляр набора должен содержать только один экземпляр «записи-владель ца» и любое количество экземпляров «записей-членов». Причем один и тот же экземпляр «записи-владельца» или «записи-члена» может входить только в один экземпляр данного набора. Таким образом, набор реализует отношение один ко многим или один к одному среди разных видов записей. Различают сингулярные, двутипные и множественные наборы. Сингу лярный набор (рис. 6) содержит только «запись-член». «Записью-вла дельцем» выступает система. Двутипный набор подразумевает одну «за пись-владельца» и много «записей-членов» одного типа. Множественный набор подразумевает несколько типов «записей-членов» набора. Тогда эк земпляр набора включает в себя один экземпляр «записи-владельца» и все связанные с ним экземпляры «записей-членов» заданных типов. На пример, множественный набор «Руководитель-Подчинённые» (рис. 7) со держит «запись-владельца» «Персона», играющую роль начальника, и Иерархическая и сетевая модели данных 17 «записи-члены» двух типов: «Персона» и «Должность», соответствующие описаниям подчинённых. Рис. 6. Сингулярный набор «Система-Константа» Сетевая модель во многом унаследовала недостатки иерархической мо дели. Наиболее существенным среди них является «жесткость». Поиск данных, доступ к ним возможен только по тем связям, которые реаль но существуют в данной конкретной модели. Рассмотрим пример. Пусть у нас есть следующие записи: кинокомпания, фильм, роль, актёр. Кино компания и фильм образуют первую пару наборов: «что снимала» и «кем снят». Фильм и роль образуют вторую пару наборов: «какие есть роли» и «из какого фильма». Роль и актёр образуют третью пару наборов: «кто играл» и «в какой роли снимался». Таким образом у нас получается сле дующая схема связей: кинокомпания ↔ фильм ↔ роль ↔ актер. Тогда если требуется найти все фильмы кинокомпании «Коламбиа пикчерс», то задача решается просто. Но представим, что нам нужно найти все компа нии, в фильмах которых снимался Арнольд Шварцнегер. Эта задача уже не так проста! Её можно упростить, добавив набор, связующий актёра и кинокомпанию, но это, в свою очередь, усложнит логическую схему базы данных и увеличит количество существующих в ней единиц. Второй важный недостаток сетевой модели данных — это её большая сложность. Реализация СУБД для сетевой модели — задача алгоритми чески и математически очень сложная, что, в свою очередь, понижает эф фективность работы с данным способом представления информации. 18 Иерархическая и сетевая модели данных Рис. 7. Множественный набор «Руководитель-Подчинённые» Всё это со временем привело к тому, что сетевые СУБД постепенно были вытеснены реляционными. Хотя некоторые из них существуют до сих пор. 3. Реляционная модель данных В реляционной модели каждый вид объектов описывается при помощи таблицы. Таблицы в реляционной модели принято называть отношениями (отсюда и название: отношение по английски — relation). Каждая строка таблицы соответствует одному экземпляру объектов данного вида. Стро ки принято называть кортежами или записями. Столбцы таблицы — это атрибуты объектов. Таким образом, реляционная база данных состоит из набора таблиц. Описание таблиц — это описание типов объектов, а строки в таблицах — это конкретные представители данных сущностей. Введём некоторые дополнительные определения. Определение 3.1. Кардинальность отношения — это количество кортежей (записей), удовлетворяющих данному отношению. Определение 3.2. Степень отношения — это количество атри бутов отношения. Определение 3.3. Домен, которому принадлежит атрибут, — это совокупность допустимых значений, которые может прини мать данный атрибут. Работа с отношениями (таблицами) в идеале должна осуществляться посредством операций реляционной алгебры. Рассмотрим их подробнее. Выборка Пусть задано отношение A(X, Y, . . .) и операция Θ : (X, Y) → {T |F}. Тогда Θ − выборкой из отношения A по атрибутам X, Y называется новое от ношение B с тем же набором атрибутов, содержащее все такие кортежи отношения A, для значений атрибутов X, Y которых выполняется условие Θ(X, Y) = T . Проекция Пусть задано отношение A(X, Y, . . .). Тогда проекцией отношения A по атрибутам X, Y называется новое отношение B, состоящее только из ат рибутов X, Y и содержащее все кортежи вида {X : x, Y : y}, такие, что множество кортежей отношения A содержит хотя бы один кортеж вида {X : x, Y : y, . . .}. Произведение Пусть заданы отношения A(A1 , A2 , . . . An) и B(B1 , B2 , . . . Bm). Тогда про изведением отношения A и отношения B называется новое отношение C, состоящее из множества атрибутов A1 , A2 , . . . An , B1 , B2 , . . . Bm и содержа щее все кортежи, полученные путём дописывания к каждому кортежу от ношения A каждого кортежа отношения B. Объединение Пусть заданы отношения A(X1 , X2 , . . . Xn) и B(X1 , X2 , . . . Xn). Тогда объеди 20 Реляционная модель данных нением отношений A и B называется новое отношение C, состоящее из тех же атрибутов X1 , X2 , . . . Xn и содержащее все такие кортежи k, для которых верно: k ∈ {A} или k ∈ {B}, где {A} — множество кортежей отношения A, {B} — множество кортежей отношения B. Пересечение Пусть заданы отношения A(X1 , X2 , . . . Xn) и B(X1 , X2 , . . . Xn). Тогда пересе чением отношений A и B называется новое отношение C, состоящее из тех же атрибутов X1 , X2 , . . . Xn и содержащее все такие кортежи k, для которых верно: k ∈ {A} и k ∈ {B}, где {A} — множество кортежей отношения A, {B} — множество кортежей отношения B. Разность Пусть заданы отношения A(X1 , X2 , . . . Xn) и B(X1 , X2 , . . . Xn). Тогда пересе чением отношений A и B называется новое отношение C, состоящее из тех же атрибутов X1 , X2 , . . . Xn и содержащее все такие кортежи k, для которых верно: k ∈ {A} и k ∈ / {B}, где {A} — множество кортежей отношения A, {B} — множество кортежей отношения B. Естественное соединение Пусть заданы два пересекающихся отношения A(A1 , A2 , . . . An , X1 , X2 , . . . Xk) и B(X1 , X2 , . . . Xk , B1 , B2 , . . . Bm). То гда естественным соединением отношения A и отношения B на зывается новое отношение C, состоящее из множества атрибутов A1 , A2 , . . . An , X1 , X2 , . . . Xk , B1 , B2 , . . . Bm и содержащее все кортежи, полученные путём дописывания к каждому кортежу отношения A вида (A1 : a1 , A2 : a2 , . . . An : an , X1 : x1 , X2 : x2 , . . . Xk : xk) недостающей части вида (B1 : b1 , B2 : b2 , . . . Bn : bm) каждого кортежа отношения B, для которого атрибуты X1 , X2 , . . . Xk принимают те же самые значения x1 , x2 , . . . xk . Θ-соединение Пусть заданы отношения A(A1 , A2 , . . . An) и B(B1 , B2 , . . . Bm), а также опе рация Θ : A1 ×A2 ×. . .×An ×B1 ×B2 ×. . .×Bm → {T kF}. Тогда соединением отношений A и B по операции Θ называется новое отношение, содержа щее все кортежи, получаемые путем декартова соединения кортежей из исходных A и B и удовлетворяющие условию Θ(A : B) = T . Пример. Пусть даны два отношения: Заказы и Клиенты (рис. 8). Резуль тат Θ-соединения отношений Заказы и Клиенты, а также сама операция Θ показаны на рис. 9. Эквисоединение Эквисоединением двух отношений называется частный случай Θ-соединения, когда операция Θ представляет собой сравнение на равенство двух (или нескольких пар) полей. Реляционная модель данных Id_Клиента 1 1 2 Id 1 2 21 Заказы Товар Картошка Огурцы Помидоры Статус Доставлено На складе На складе Клиенты Имя Вася Пупкин Петя Васечкин Рис. 8. Исходные отношения Θ : Заказы.Id_Клиента = Клиенты.Id AND Заказы.Статус ! = ′ Доставлено′ Заказы Θ Клиенты Id_Клиента Товар Статус Id Имя 1 Огурцы На складе 1 Вася Пупкин 2 Помидоры На складе 1 Петя Васечкин Рис. 9. Результат соединения отношений Если в предыдущем примере заменить операцию Θ на Θ′ : Заказы.Id_Клиента = Клиенты.Id, то как раз получится эквисоединение. Может показаться, что эквисоеди нение совпадает с естественным соединением. Но это не так! Во-первых, в эквисоединении поля могут не совпадать по названию. Во-вторых, при эквисоединении в результирующее отношение попадают оба поля и из пер вого отношения, и из второго, а при естественном соединении дубликаты отбрасываются. Деление Пусть заданы отношения A(A1 , A2 , . . . An), B(B1 , B2 , . . . Bm) и C(A1 , A2 , . . . An , B1 , B2 , . . . Bm). Результатом деления отношения A на отношение B по отношению C называется новое отношение, содержащее все такие кор тежи x из отношения A, для которых выполняется следующее условие: ∀y ∈ B ′ ∃(x : y) ∈ C ′ , где B ′ — множество кортежей отношения B, C ′ — множество кортежей отношения C, а y и (x : y) — кортежи из этих мно жеств. 22 Реляционная модель данных A называется делимым, B — делителем, а C — посредником. A Field1 1 2 B Field2 2 3 Field3 1 2 Field4 1 2 Field3 1 2 1 1 4 Field4 1 2 1 2 5 C Field1 1 1 2 2 1 Field2 2 2 3 3 2 A\B:C Field1 Field2 1 2 Рис. 10. Пример деления отношения A на отношение B посредством отношения C Теперь мы можем ввести понятие реляционной базы данных и реляци онной СУБД. Определение 3.4. Реляционная БД — это набор реляционных от ношений (таблиц) и только их. Никаким другим образом (перемен ными, массивами или чем то еще другим) данные не представлены. Определение 3.5. Реляционная СУБД — это система управления реляционной БД, в которой все действия представляются в виде комбинации операций реляционной алгебры. Данные определения не являются формальными. Более точно опреде ление для реляционной СУБД дал в виде двенадцати (а на самом деле тринадцати) правил Э. Кодд. 0. Основное (подразумеваемое правило). Система, которая реклами руется или провозглашается поставщиком как реляционная СУБД, должна управлять базами данных исключительно способами, соот ветствующими реляционной модели. 1. Информационное правило. Вся информация, хранимая в реляцион ной базе данных, должна быть явно, на логическом уровне, представ Реляционная модель данных 2. 3. 4. 5. 23 лена единственным образом: в виде значений в реляционных табли цах. Правило гарантированного логического доступа. К каждому имеюще муся в реляционной базе атомарному значению должен быть гаран тирован доступ с помощью указания имени реляционной таблицы, значения первичного ключа и имени столбца. Правило 2 указывает на роль первичного ключа при поиске информации в базе данных. Имя таблицы позволяет найти требуемую таблицу, имя столбца поз воляет найти требуемый столбец, а первичный ключ позволяет найти строку, содержащую искомый элемент данных. Правило наличия значения. В полностью реляционной СУБД долж ны иметься специальные индикаторы (отличные от пустой символь ной строки или строки из одних пробелов и отличные от нуля или какого-либо другого числового значения) для выражения (на логиче ском уровне, систематично и независимо от типа данных) того факта, что значение отсутствует по меньшей мере по двум различным причи нам: его действительно нет, либо оно неприменимо к данной позиции. СУБД должна не только отражать этот факт, но и распространять на такие индикаторы свои функции манипулирования данными неза висимо от их типа. Обычно такие индикаторы носят название NULL. Правило динамического диалогового реляционного каталога. Описа ние базы данных выглядит логически как обычные данные, так что авторизованные пользователи и прикладные программы могут упо треблять для работы с этим описанием тот же реляционный язык, что и при работе с обычными данными. Правило исчерпывающего подъязыка данных. Реляционная система может поддерживать различные языки и режимы взаимодействия с пользователем (например, режим вопросов и ответов). Однако дол жен существовать по крайней мере один язык, операторы которого можно представить в виде строк символов в соответствии с неко торым четко определенным синтаксисом и который в полной мере поддерживает следующие элементы: – определение данных; – определение представлений; – обработку данных (интерактивную и программную); – условия целостности; – идентификация прав доступа; – границы транзакций (начало, завершение и отмена). Правило 5 требует, чтобы СУБД использовала язык реляционной ба зы данных. Такой язык должен поддерживать все основные функции 24 Реляционная модель данных 6. 7. 8. 9. 10. 11. СУБД — создание базы данных, чтение и ввод данных, реализацию защиты базы данных и т.д. Правило модификации таблиц. В СУБД должен существовать кор ректный алгоритм, позволяющий автоматически для каждой табли цы определять во время ее создания, может ли она использоваться для вставки и удаления строк и какие из столбцов допускают мо дификацию, и заносящий полученную таким образом информацию в системный каталог. Это правило также называют правилом мо дификации представлений. Говоря простым языком оно гласит, что все представления подлежащие обновлению должны быть доступны для этого. Представлениями в реляционных СУБД называют такие виртуальные таблицы, которые формируются на основе запроса к реальным таблицам. Правило множественности операций. Операции вставки, удаления и изменения данных должны быть применимы как к одной строке, так и ко множеству строк или всем кортежам таблицы в целом. Правило 7 акцентирует внимание на том, что базы данных по своей природе ориентированы на множества. Оно требует, чтобы операции добавле ния, удаления и обновления можно было выполнять над множествами строк. Правило физической независимости. Диалоговые операторы и при кладные программы на логическом уровне не должны не должны за висеть от используемых способов хранения данных на носителях и методов обращения к ним. Правило логической независимости. Диалоговые операторы и при кладные программы должны на логическом уровне оставаться нетро нутыми при внесении в базовые таблицы любых изменений, кото рые теоретически позволяют сохранить нетронутыми содержащиеся в этих таблицах данные. Правила 8 и 9 означают отделение пользо вателя и прикладной программы от низкоуровневой реализации базы данных. Правило независимости условий целостности. Должна существовать возможность определить условия целостности, специфические для конкретной реляционной базы данных, на подъязыке реляционной базы данных и хранить их в каталоге, а не в прикладной программе. Правило 10 гласит, что язык базы данных должен поддерживать огра ничительные условия, налагаемые на вводимые данные и действия, которые могут быть выполнены над данными. Правило независимости от распределенности. Диалоговые операто ры и прикладные программы на логическом уровне не должны стра Проектирование реляционных баз данных 25 дать от совершаемого физического разнесения данных (если перво начально СУБД работала с нераспределенными данными) или пере распределения (если СУБД действительно распределенная). 12. Правило ненарушения реляционного языка. Если в реляционной СУБД имеется язык низкого уровня (для работы с отдельными стро ками), он не должен позволять нарушать или «обходить» правила, сформулированные на языке высокого уровня (множественном) и за несенные в системный каталог. 3.1. Проектирование реляционных баз данных Терминология Определение 3.6. Пусть Х и У — произвольные подмножества атрибутов отношения R. Говорят, что Y функционально зависит (ФЗ) от X (X → Y) тогда и только тогда, когда по значению ат рибутов Х кортежа можно однозначно определить значения ат рибутов Y . Или, говоря другими словами, для любого допустимого значения отношения R, если два кортежа совпадают по значениям атрибутов X, то они совпадают и по значениям атрибутов Y . Замечание: в этом определении не говорится, что кортежей с одной и той же парой {x, y} не может быть несколько. Определение 3.7. В записи функциональной зависимости X → Y множество X называется детерминантом, а Y — зависимой ча стью Определение 3.8. Функциональная зависимость называется три виальной, если Y является подмножеством X. Замечание: подмножество Y может быть и несобственным по отноше нию к X. Несложно заметить, что некоторые функциональные зависимости под разумевают существование других функциональных зависимостей. Напри мер, если существует зависимость вида {S, P} → {X, Y}, то очевидно, что существует и пара функциональных зависимостей вида {S, P} → X и {S, P} → Y . Сформулируем основные правила вывода функциональных зависимостей из уже существующих. 1. Правило рефлексивности: B ⊆ A ⇒ A → B. 2. Правило дополнения: A → B ⇒ {A, C} → {B, C}. 3. Правило транзитивности: (A → B) ∧ (B → C) ⇒ A → C. 4. Правило самоопределения: A → A. 5. Правило декомпозиции: A → {B, C} ⇒ (A → B) ∧ (A → C). 6. Правило объединения: (A → B) ∧ (A → C) ⇒ A → {B, C}. 26 Реляционная модель данных 7. Правило композиции: (A → B) ∧ (С → D) ⇒ {A, C} → {B, D}. 8. (A → B) ∧ (C → D) ⇒ A ∪ (C \ B) → {B, D}. На самом деле достаточно только первых трех правил (они носят на звание аксиом Армстронга). Остальные пять выводятся из первых трех. Но удобнее пользоваться полным набором. Далее под названием «аксио мы Армстронга» будет подразумеваться набор именно из восьми правил, а не из необходимых трёх. Определение 3.9. Пусть для некоторого отношения R зада но множество функциональных зависимостей S. Тогда замыканием множества S (обозначается S+) называется множество всех функ циональных зависимостей, которые можно вывести из S по прави лам вывода. Определение 3.10. Функциональная зависимость называется неприводимой слева, если ни один атрибут из детерминанта не может быть опущен без изменения замыкания множества функ циональных зависимостей, определяемого ей. Определение 3.11. Множество функциональных зависимостей S называется неприводимым, если выполняются три условия: 1) правая часть всех функциональных зависимостей содержит только один атрибут; 2) каждый детерминант является неприводимым слева; 3) ни одна функциональная зависимость не может быть удалена из S без изменения замыкания S+. Теория нормализации Большинство проблем решаемых при помощи баз данных имеет несколько возможных схем разработки набора отношений для представ ления предметной области. Очень часто, сравнивая схемы таблиц, приду манные для решения одной и той же задачи разными разработчиками, мы можем на подсознательном уровне сказать что некоторые из них лучше, а некоторые хуже. Более формально вопрос выбора оптимальной структу ры таблиц базы данных в реляционной модели решает теория нормализа ции [2, 1] . Определение 3.12. Нормализация данных — это разложение от ношений на большее количество более простых таблиц. Исторически теория нормализации данных была придумана прежде все го для одной цели — экономии места на жестком диске. Сегодня данная проблема уже не настолько актуальна, поэтому цели нормализации данных на сегодняшний день более широки. В них входят: 1) экономия занимаемого базой данных пространства; Проектирование реляционных баз данных 27 2) стремление минимизировать количество мест, в которых необходимо вносить физические изменения, при редактировании или удалении логически одиночной порции информации; 3) группировка данных по содержимому; 4) поддержка принципа модульности. Для пояснения второй цели рассмотрим пример на рисунке 11. Из него видно, что могут быть ситуации, когда для изменения логически единичной информации требуется провести редактирование во многих местах. Рас смотрим сколько записей надо изменить, если потребуется указать, что группа 1311 теперь учится не по специальность 3515, а по специальности 2204. Количество таких записей будет совпадать с количеством студентов в группе. Очевидно, что это не хорошо! Именно исправление подобных ситуаций и есть вторая цель нормализации данных. Группы Специальность Группа 3515 1311 3515 1311 3515 1311 2204 1362 2204 1362 ... ... Студент Козлов К.К. Баранов Б.Б. Ослова О.О. Овцова О.О. Хряков X.X. ... Рис. 11. Неудачно спроектированная структура для хранения информа ции о списках групп, соответствующих специальностям, и студентах, соответствующих группам Из этого же примера можно понять и третью с четвертой цели тео рии нормализации. Очевидно, что логично поделить данную информацию на две сущности: соответствие групп специальностям и соответствие сту дентов группам. Если этого не сделать, то мы попадаем в ситуацию, когда нет никакой возможности хранить информацию о соответствии группы спе циальности, если пока не известны фамилии студентов. На решение этой проблемы направлена третья цель нормализации. Если же разделить отношение на два боле простых, то мы можем по ручить организовать работу с одним из них одному программисту с другим из них другому. Например, соответствие групп специальностям пусть за полняет учебный отдел вуза. Интерфейс для них разработает, к примеру, Пупкин В.А. Соответствие же студентов группам пусть заполняет прием ная комиссия и интерфейс разработает Пупочкина А.И. Каждый из них 28 Реляционная модель данных будет работать со своей таблицей, что позволяет говорить о достижении принципа модульности. Как же понять какие таблицы хорошие, а какие плохие? Рассмотрим для этого понятия нормальных форм. Определение 3.13. Отношение R находится в первой нормаль ной форме (1НФ) тогда и только тогда, когда значения всех его атрибутов атомарны. Это определение говорит, что для любой из строк таблицы каждый ее атрибут должен содержать не более одного значения. Некоторые совре менные реляционные СУБД позволяют нарушить данное определение и использовать в качестве домена поля массивы или другие множественные типы. В таком случае таблица не будет находиться в первой нормальной форме. Данное определение проиллюстрировано на рисунках 12-13. Преподаватели-Предметы Преподаватель Предмет Иванов Физика Иванов Химия Петров Физ-ра Петров Ин-яз Рис. 12. Отношение, удовлетворяющее 1НФ Преподаватели-Предметы Преподаватель Предмет Иванов Физика Химия Петров Физ-ра Ин-яз Рис. 13. Отношение, не удовлетворяющее 1НФ Основой для перехода к более высоким нормальным формам является процесс разбиения, или декомпозиции. Причем нас будет интересовать не просто процесс декомпозиции, а процесс декомпозиции без потерь. Определение 3.14. Процесс декомпозиции будем называть деком позицией без потерь, если из полученных отношений можно полно стью восстановить исходное отношение. Проектирование реляционных баз данных 29 Пояснение: под фразой «восстановить исходной отношение» мы будем подразумевать, что какой бы набор записей не содержался в исходном отношении, после его декомпозиции из наборов записей полученных отно шений можно путем обратной композиции получить тот же самый набор записей и ни какой иной. По своей сути декомпозиция представляет собой проекцию. А обратное преобразование — операция естественного соеди нения. Теорема 3.1: о достаточном условии декомпозиции без потерь (теорема Хита) Пусть дано отношение R(A, B, C), где A, B и C — непересекаю щиеся подмножества множества атрибутов R. Причем множество атрибутов R равно объединению подмножеств A, B, C (A ∪ B ∪ C = = R). Если R удовлетворяет функциональной зависимости A → B, то R равно соединению его проекций {A, B} и {A, C}. Доказательство. Обозначим проекцию {A, B} отношения R как R1 , проекцию {A, C} как R2 , множество кортежей отношения R как {R}, мно жество кортежей естественного соединения R1 и R2 как {R12 }. Доказательство разделим на два шага: доказательство того, что есте ственное соединение R1 и R2 содержит все кортежи отношения R, и до казательство того, что среди результата данного естественного соединения нет лишних кортежей. Шаг 1. Пусть кортеж {a, b, c} ∈ {R}. Тогда по определению операции взятия проекции кортеж {a, b} ∈ {A, B} и кортеж {a, с} ∈ {A, С}. Следова тельно, по определению естественного соединения кортеж {a, b, c} ∈ {R12 }. Шаг 2. Надо доказать, что если кортеж {a, b, c} ∈ {R12 }, то кор теж {a, b, c} ∈ {R}. Если кортеж {a, b, c} ∈ {R12 }, то существуют кортеж {a, b} ∈ {A, B} и кортеж {a, с} ∈ {A, С}. Может ли оказаться, что {a, b} со единится с неправильной парой {a, с}? Последнее условие ({a, с} ∈ {A, С}) может выполняться в том и только в том случае, когда существует кортеж a, b2 , c ∈ R. Но поскольку отношение R удовлетворяет функциональной зависимости A → B, то b = b2 и, следовательно, {a, b, c} = {a, b2 , c}. Теорема доказана. Рассмотрим пример. Пусть у нас есть некоторое отношение R (рис. 14), описывающее названия студенческих групп (атрибут «Группа»), количе ство обучающихся в них студентов (атрибут «Кол-во») и номер специаль ности, на которой студенты обучаются (атрибут «Специальность»). Будем считать, что все студенты группы обучаются только на одной и той же 30 Реляционная модель данных специальности. Таким образом, мы можем сказать, что отношение R удо влетворяет функциональной зависимости Группа → Специальность. Группа 4311 4361 2311 R Кол-во 15 15 21 Специальность 5201 3515 5201 Рис. 14. Отношение R Рассмотрим примеры декомпозиции без потерь и декомпозиции с поте рями. Декомпозиция без потерь получается по теореме Хита разбиением на две проекции: {Группа, Кол-во} и {Группа, Специальность} (рис. 15). При мером декомпозиции с потерями может служить разбиение на проекции {Группа, Кол-во} и {Кол-во, Специальность} (рис. 16). Группы-Кол-во Группа Кол-во 4311 15 4361 15 2311 21 Группы-Специальности Группа Специальность 4311 5201 4361 3515 2311 5201 Рис. 15. Декомпозиция без потерь Группы-Кол-во Группа Кол-во 4311 15 4361 15 2311 21 Кол-во-Специальности Кол-во Специальность 15 5201 15 3515 21 5201 Рис. 16. Декомпозиция с потерями Теперь можно рассмотреть недостатки первой нормальной формы. Для их осознания рассмотрим пример отношения «Персональное расписание» (рис. 17). Предположим, что все студенты внутри одной группы учатся на одной и той же специальности. В одно и то же время у одной и той же груп пы не может быть более одного предмета (про числитель и знаменатель Проектирование реляционных баз данных 31 забудем). Будем считать, что не может быть однофамильцев. Студент мо жет одновременно получать два образования в разных группах по разным специальностям. Студент Иванов Иванов Иванов Иванов Петров Петров ... Персональное расписание Спец-ность Группа Предмет 5102 1311 БД и СУБД 5102 1311 Физика 5102 1311 Обед 5102 1311 Ин. язык 3515 1361 БД и СУБД 3515 1361 Ин. язык ... ... ... Время Пон. 10:40 Пон. 12:25 Пон. 14:10 Пон. 15:55 Пон. 10:40 Пон. 12:25 ... Рис. 17. Таблица «Персональное расписание» находится в 1НФ У рассмотренной таблицы легко заметить ряд проблем. 1. Проблема добавления: нельзя сделать запись о том, что студент учит ся на какой-либо специальности, не добавив информации о каком либо предмете. 2. Проблема удаления: если мы удаляем расписание какого-либо сту дента, то и сам студент удаляется тоже. 3. Проблема изменения: если у студента поменялась группа, но не из менилось расписание, то всё равно надо внести столько изменений, сколько предметов на неделе у студента. Можно ли улучшить данную ситуацию? Вполне очевидна (хотя, может, и не оптимальна) декомпозиция отношения «Персональное расписание» на два более простых (рис. 18). Видно, что в новых отношениях некоторые из проблем решены. Но как же понять, когда нужно делать декомпозицию, а когда нет? Для это введём понятние второй нормальной формы. Определение 3.15. Атрибут называется неключевым, если он не входит в состав ни одного возможного ключа. Иначе он называется ключевым. Определение 3.16. Отношение находится во второй нормальной форме (2НФ) тогда и только тогда, когда оно находится в первой нормальной форме и каждый неключевой атрибут неприводимо за висит от первичного ключа. Замечание: определение второй нормальной формы было дано для от ношений с одним возможным ключом. Теперь дадим более формальное 32 Реляционная модель данных Студент Иванов Иванов Иванов Иванов Петров Петров Расписание Предмет БД и СУБД Физика Обед Ин. язык БД и СУБД Ин. язык Студент Иванов Петров Студенты Специальность 5102 3515 Время Пон. 10:40 Пон. 12:25 Пон. 14:10 Пон. 15:55 Пон. 10:40 Пон. 12:25 Группа 1311 1361 Рис. 18. Декомпозиция отношения «Персональное расписание» определение для отношений с произвольным количеством ключей. Определение 3.17. Отношение находится во второй нормаль ной форме тогда и только тогда, когда оно находится в первой нормальной форме и каждый неключевой атрибут неприводимо за висит от любого возможного ключа. Говоря неформальным языком, определение второй нормальной формы может быть трактовано следующим образом: если для каждой функцио нальной зависимости вида ключ → неключевой(вые) атрибут(ы) в левой части (детерминанте) нельзя опустить ни один атрибут без потери части смысла, то отношение находится во второй нормальной форме. Теперь легко можно понять, зачем была сделана такая декомпозиция от ношения «Персональной расписание». Для начала определим в нём ключи. Зная, что в одно и то же время у одного и того же студента не может быть разных предметов по расписанию, что нет однофамильцев, что студент мо жет учиться на двух специальностях и что в одной и той же группе все сту денты учатся по одной и той же специальности, можно точно сказать, что ключом отношения является тройка атрибутов {Студент, Группа, Время}. Это также значит, что все остальные атрибуты функционально зависят от данного ключа: {Студент, Группа, Время} → {Специальность, Предмет}. Очевидно, что студент не может одновременно два раза учиться на одной и той же специальности. Тогда, исходя из фразы «однофамильцев Проектирование реляционных баз данных 33 нет», находим альтернативный ключ: {Студент, Специальность, Время} → {Группа, Предмет}. Делаем для себя вывод: есть только один неключевой атрибут — Пред мет. Мы можем найти и другие функциональные зависимости в данном от ношении. В частности, из фразы «в одной и той же группе все студенты учатся по одной и той же специальности» мы получаем зависимость: Группа → Специальность. Специальность — ключевой атрибут. Определение второй нормальной формы не нарушается. Как уже говорилось, студент не может одновремен но два раза учиться на одной и той же специальности. Тогда исходя из фразы «однофамильцев нет» находим еще зависимость: {Студент, Специальность} → Группа. Группа — ключевой атрибут. Определение второй нормальной формы не нарушается. Из фраз «однофамильцев нет» и «в одно и то же время у одного и того же студента не может быть разных предметов по расписа нию» находим еще зависимость: {Студент, Время} → Предмет. Определение второй нормальной формы нарушено! Предмет — неклю чевой атрибут, а {Студент, Время} — лишь часть ключа, а не весь ключ целиком! Поэтому мы и провели декомпозицию, оставив в первом отно шении все составляющие проблемной функциональной зависимости, а во втором всё, что нужно для декомпозиции без потерь. Замечание: для исследования на соответствие отношений нормальным формам достаточно рассмотреть только неприводимые слева функциональ ные зависимости. Выводимые зависимости рассматривать не обязательно. Рассмотрим еще один пример. Пусть у нас есть отношение «Налого плательщики», хранящее информацию о гражданах РФ, выплачивающих налоги (рис. 19). У данного отношения пять атрибутов: «ИНН» налого плательщика, «ФИО» налогоплательщика,«Номер паспорта» налогопла тельщика,«Город» проживания налогоплательщика и «Регион». Будем счи тать,что ИНН и номер паспорта уникальны для каждого гражданина. Бы вают однофамильцы. В одном и том же городе могут проживать несколько налогоплательщиков. Регион определяется городом проживания. 34 ИНН 1234567890 1234567891 5465654664 ... Реляционная модель данных Налогоплательщики ФИО Номер паспорта Пупкин Василий Алексеевич 44-04 123456 Пупкина Василиса Алексеевна 44-04 123457 Козлодоев Антон Борисович 34-06 123456 ... ... Город Москва Москва Брянск ... Регион 77 77 32 ... Рис. 19. Отношение «Налогоплательщики» Определим возможные ключи отношения. Из указанных выше пред положений очевидно, что у отношения два возможных ключа: «ИНН» и «Номер паспорта». Тогда мы автоматически получаем следующие функци ональные зависимости: ИНН → Номер паспорта, Номер паспорта → ИНН, ИНН → {ФИО, Город, Регион}, Номер паспорта → {ФИО, Город, Регион}. Так как регион зависит только от города проживания, то мы получаем еще одну функциональную зависимость: Город → Регион. Исследуем данное отношение на соответствие нормальным формам. Все атрибуты атомарны. Поэтому отношение «Налогоплательщики» на ходится в первой нормальной форме. Замечание: если все ключи отношения не являются составными, то из нахождения отношения в первой нормальной форме автоматически следует нахождение во второй нормальной форме. Таким образом, отношение «Налогоплательщики» находится во второй нормальной форме. Но данное отношение по прежнему сохраняет некоторые недостатки. 1. Проблема добавления: нельзя сделать запись о том, что городу Яро славль соответствует 76 регион, не добавив информации о каком либо налогоплательщике из Ярославля. 2. Проблема удаления: если мы удаляем всех налогоплательщиков из Москвы, то теряем информацию о соответствии Москве 77 номера региона. Проектирование реляционных баз данных 35 3. Проблема изменения: если у Москвы поменяется номер региона (на пример, 77 номер заменят на 99), то придётся вносить изменения столько раз, сколько налогоплательщиков живёт в Москве. Для того чтобы находить такие проблемы, введём понятие третьей нор мальной формы. Определение 3.18. Отношение находится в третьей нормальной форме тогда и только тогда, когда оно находится во второй нор мальной форме и отсутствуют транзитивные зависимости неклю чевых атрибутов от ключевых. Определение 3.19. Транзитивной зависимостью неключевых ат рибутов от ключевых называется пара зависимостей вида A → B, B → C, где A — набор ключевых атрибутов (или ключ целиком), а B и С — различные подмножества неключевых атрибутов. Замечание: учитывая, что любое реляционное отношение содержит хотя бы один ключ, для наличия транзитивной зависимости достаточно найти за висимость между подмножествами неключевых атрибутов. Вторая (левая) составляющая получается автоматически из зависимости любого подмно жества атрибутов от ключа. Отношение «Налогоплательщики» содержит зависимость между неключевыми атрибутами: Город → Регион. Определение третьей нормальной формы нарушено, так как всегда можно найти транзитивную зависимость. Например: ИНН → Город → Регион. Чтобы привести отношение к третьей нормальной форме, проведём декомпозицию. Выделим в одно отношение составляющие «проблемной» функциональной зависимости, а во второе все остальные атрибуты, необ ходимые для того, чтобы не потерять смысл исходной таблицы (рис. 20). Исследуем новые полученные отношения на соответ ствие нормальным формам. Вначале рассмотрим отношение Определим возможные ключи отноше «Налогоплательщики». ния. Из указанных выше предположений очевидно, что у от ношения два возможных ключа: «ИНН» и «Номер паспорта». 36 Реляционная модель данных ИНН 1234567890 1234567891 5465654664 ... Налогоплательщики ФИО Номер паспорта Пупкин Василий Алексеевич 44-04 123456 Пупкина Василиса Алексеевна 44-04 123457 Козлодоев Антон Борисович 34-06 123456 ... ... Город Москва Москва Брянск ... Города-Регионы Город Регион Москва 77 Брянск 32 ... ... Рис. 20. Декомпозиция отношения «Налогоплательщики» Тогда мы автоматически получаем следующие функциональные зависимо сти: ИНН → Номер паспорта, Номер паспорта → ИНН, ИНН → {ФИО, Город}, Номер паспорта → {ФИО, Город}. Исследуем данное отношение на соответствие нормальным формам. Все атрибуты атомарны. Поэтому отношение «Налогоплательщики» на ходится в первой нормальной форме. Все ключи отношения не являются составными. Таким образом, отно шение «Налогоплательщики» находится во второй нормальной форме. Отсутствуют неприводимые слева зависимости между неключевыми ат рибутами — отношение находится в третьей нормальной форме. Замечание: если отношение состоит только из двух атрибутов и нахо дится в первой нормальной форме, то оно автоматически находится во вто рой, третьей, четвёртой, пятой нормальных формах, а также в нормальной форме Бойса-Кодда (последние три нормальные формы мы рассмотрим далее). Таким образом, второе отношение «Города-Регионы» тоже находится в третьей нормальной форме. Рассмотрим ещё один пример. Предположим, что у нас есть отношение «Выплаты налогоплательшиков» (рис. 21). В отношении «Налогоплательщики» четыре атрибута: «ИНН», «Номер паспорта», «Код платежа» и «Сумма». Код платежа уникален для каждого Проектирование реляционных баз данных ИНН 1234567890 1234567890 1234567890 1234567891 5465654664 5465654664 ... Выплаты налогоплательщиков Номер паспорта Код платежа 44-04 123456 12345678 44-04 123456 12345679 44-04 123456 12345612 44-04 123457 12345679 34-06 123456 12345678 34-06 123456 12345612 ... ... 37 Сумма 513 3123 4523 1234 513 1230 ... Рис. 21. Отношение «Выплаты налогоплательщиков» человека, но может повторяться у разных людей. То есть у одного и того же человека определённый код платежа встречается только один раз. ИНН и номер паспорта уникальны для каждого гражданина. У данного отношения два возможных ключа: {ИНН, Код платежа} и {Номер паспорта, Код платежа}. Таким образом, мы получаем следующие зависимости: {ИНН, Код платежа} → {Номер паспорта, Сумма}, {Номер паспорта, Код платежа} → {ИНН, Сумма}. Так как ИНН и Номер паспорта уникальны для каждого человека, то они определяют друг друга: {ИНН} → {Номер паспорта}. Исследуем данное отношение на соответствие нормальным формам. Нахождение в первой нормальной форме очевидно. Неключевой атрибут в отношении только один — Сумма. Он неприводимо зависит от обоих возможных ключей. Отношение находится во второй нормальной форме. Отсюда автоматом следует находение в третьей нормальной форме, так как не хватает неключевых атрибутов для построения транзитивной зави симости. Но проблемы по-прежнему есть! 1. Проблема добавления: нельзя сделать запись о том, что человеку с определённым номером паспорта соответствует определённый номер ИНН, не добавив информации о каких-либо платежах. 2. Проблема удаления: если мы удаляем информацию о всех платежах налогоплательщика, то теряем информацию о соответствии его номе ра ИНН номеру паспорта. 38 Реляционная модель данных 3. Проблема изменения: если у человека изменился номер ИНН или номер паспорта, то придётся сделать изменения столько раз, сколько было записей о платежах. Можно ли улучшить? Для ответа на этот вопрос введём понятие нор мальной формы Бойса-Кодда. Определение 3.20. Отношение находится в нормальной форме Бойса-Кодда (НФБК) тогда и только тогда, когда оно находится в первой нормальной форме и детерминанты всех его функциональ ных зависимостей являются потенциальными (возможными) ключа ми. Когда имеет смысл говорить о данной нормальной форме? Нормальная форма Бойса-Кодда отличается от третьей нормальной формы только в случае выполнения трёх условий. 1. Отношение имеет два (или более) потенциальных ключа. 2. Два (или более) ключа составные. 3. Два (или более) потенциальных составных ключа перекрываются (по множествам атрибутов). В случае нарушения одного или более условий нормальная форма Бойса Кодда совпадает с третьей нормальной формой. Исследуем наш пример на соответствие нормальной форме Бойса Кодда. Все три условия выполнены. Нормальная форма Бойса-Код да не совпадает с третьей нормальной формой. Исследуем далее. Очевидно, что третья из найденных функциональных зависимостей ({ИНН} → {Номер паспорта}) нарушает определение нормальной формы Бойса-Кодда. Выполним декомпозицию отношения (рис. 22). Легко показать, что полученная пара отношений находится в нормаль ной форме Бойса-Кодда. Теперь мы можем дать альтернативное определение третьей нормаль ной формы. Определение 3.21. Отношение находится в третьей нормальной форме тогда и только тогда, когда оно находится в первой нор мальной форме и для любой её функциональной зависимости X → A выполняется хотя бы одно из трёх условий: A ⊆ X; X — возможный ключ; A входит в какой-либо из возможных ключей. Замечание: если оставить только первые два условия, то получится определение нормальной формы Бойса-Кодда. Рассмотрим новый пример (рис. 23). В отношении «Предметы» три ат рибута: «Предмет», «Преподаватель» и «Учебник». Каждый из предметов Проектирование реляционных баз данных 39 Выплаты налогоплательщиков ИНН Код платежа Сумма 1234567890 12345678 513 1234567890 12345679 3123 1234567890 12345612 4523 1234567891 12345679 1234 5465654664 12345678 513 5465654664 12345612 1230 ... ... ... Номера налогоплательщиков ИНН Номер паспорта 1234567890 44-04 123456 1234567891 44-04 123457 5465654664 34-06 123456 ... ... Рис. 22. Декомпозиция отношения «Выплаты налогоплательщиков» ведёт определённый коллектив преподавателей. Один и тот же препода ватель может вести разные предметы. По каждому из предметов преду смотрен строго постоянный набор учебников. Если преподаватель ведёт какой-либо предмет, то он должен использовать все из соответствующих учебников. Один и тот же учебник могут использовать в разных предметах. Предмет БД и СУБД БД и СУБД БД и СУБД БД и СУБД Основы ЭВМ Основы ЭВМ ... Предметы Преподаватель Учебник В.Ю. Пупкин Дейт. Введение в БД Н.В. Лупкина Дейт. Введение в БД В.Ю. Пупкин Г.Г. Молина. Основы СУБД Н.В. Лупкина Г.Г. Молина. Основы СУБД В.Ю. Пупкин Э. Таненбаум. Архитектура компьютера В.Ю. Пупкин Д.Л. Шиндлер. Основы компьютерных сетей ... ... Рис. 23. Отношение «Предметы» Определим ключ отношения. Исходя из вышесказанного, ключом отно 40 Реляционная модель данных шения должны являтся все три атрибута вместе: {Предмет, Преподаватель, Учебник}. Тогда из нахождения отношения в первой нормальной форме автома тически следует его нахождение в нормальной форме Бойса-Кодда (нет неключевых атрибутов и всего один ключ). Но очевидно, что отношение спроектировано плохо! Нетрудно заметить, что книги не зависят от пре подавателей и наоборот. Как определить причину проблемы? Для этого введём несколько определений. Определение 3.22. Пусть задано отношение R и три его произ вольных подмножества атрибутов A, B, C. Тогда говорят, что B многозначно зависит (МЗЗ) от A (A ։ B) (или есть многозначная зависимость B от A) тогда и только тогда, когда множество зна чений атрибута B, соответствующих паре значений атрибутов A и C, зависит только от значения атрибута А, но не зависит от значения атрибута C. Нетрудно доказать, что в любом отношении не бывает одной многознач ной зависимости. Для каждой многозначной зависимости A ։ B всегда найдется парная многозначная зависимость A ։ C. Рассмотрим атрибуты нашего отношения. Если зафиксировать конкрет ный предмет, то соответствующее ему множество значений атрибута «Учеб ник» (если не считать повторения) будет постоянным, какого бы мы не выбрали преподавателя. То же самое мы увидим и относительно соот ветствующего предмету множества преподавателей. Оно не будет зави сеть от конкретного учебника. Следовательно, в нашем отношении при сутствует пара многозначных зависимостей: Предмет ։ Преподаватель и Предмет ։ Учебник (сокращенно записывается при помощи вертикальной черты |: Предмет ։ Преподаватель|Учебник). Очевидно, что многозначная зависимость — это обобщение функцио нальной зависимости. Каждая функциональная зависимость является од новременно и многозначной, но не наоборот. Определение 3.23. Многозначная зависимость А ։ B называ ется тривиальной, если либо B ⊆ A, либо множество атрибутов отношения равно объединению подмножеств A и B. Теперь, когда мы дали определение многозначной зависимости, можно более жёстко сформулировать условие декомпозиции без потерь. Теорема 3.2: о необходимом и достаточном условии декомпозиции без потерь (теорема Фейгина) Проектирование реляционных баз данных 41 Пусть дано отношение R(A, B, C), где A, B и C — непересекаю щиеся подмножества множества атрибутов R. Причем множество атрибутов R равно объединению подмножеств A, B, C (A ∪ B ∪ C = = R). Отношение R может быть декомпозировано без потерь на его проекции {A, B} и {A, C} тогда и только тогда, когда оно удовле творяет многозначной зависимости A ։ B. Доказательство теоремы Фейгина рассматривать не будем. Определение 3.24. Отношение R находится в четвёртой нор мальной форме тогда и только тогда, когда оно находится в пер вой нормальной форме и для любой его нетривиальной многозначной зависимости A ։ B выполняется, что все атрибуты отношения R функционально зависят от A. Можно сформулировать альтернативное определение. Определение 3.25. Отношение R находится в четвёртой нор мальной форме (4НФ) тогда и только тогда, когда оно находится в нормальной форме Бойса-Кодда и для любой его нетривиальной многозначной зависимости A ։ B существует аналогичная функ циональная зависимость A → B. Теперь исследуем наш пример. Очевидно, что пара многозначных зави симостей Предмет ։ Преподаватель|Учебник не удовлетворяет определе нию четвертой нормальной формы. Проведём декомпозицию (рис. 24). Преподаватели Предмет Преподаватель БД и СУБД В.Ю. Пупкин БД и СУБД Н.В. Лупкина Основы ЭВМ В.Ю. Пупкин ... ... Предмет БД и СУБД БД и СУБД Основы ЭВМ Основы ЭВМ ... Учебники Учебник Дейт. Введение в БД Г.Г. Молина. Основы СУБД Э. Таненбаум. Архитектура компьютера Д.Л. Шиндлер. Основы компьютерных сетей ... Рис. 24. Декомпозиция отношения «Предметы» 42 Реляционная модель данных Оба полученных в результате декомпозиции отношения содержат толь ко по два атрибута. Поэтому можно без дополнительных исследований сказать, что они находятся в пятой нормальной форме. Рассмотрим новый пример (рис. 25). Отношение «Поставщики» содер жит три атрибута: «Поставщик», «Товар» и «Проект». Предполагается, что каждый поставщик умеет поставлять строго определённый набор то варов. Для каждого проекта требуется также строго определенный набор товаров. Причём если известно, что поставщик z работает с проектом x, для проекта x требуется товар y и поставщик z умеет поставлять товар y, то отношение «Поставщики» обязательно содержит запись {z, y, x}. Поставщики Поставщик Товар Проект Иванов и Ко Гайки Лекарство от рака Иванов и Ко Болты Лекарство от рака Иванов и Ко Гайки Станция Мир Петров и Ко Гайки Станция Мир ... ... ... Рис. 25. Отношение «Поставщики» Можно догадаться, что отношение декомпозируется без потерь на три более простых (рис. 26). Поставщики-Товары Поставщик Товар Иванов и Ко Гайки Иванов и Ко Болты Петров и Ко Гайки ... ... Поставщики-Проекты Поставщик Проект Иванов и Ко Лекарство от рака Иванов и Ко Станция Мир Петров и Ко Станция Мир ... ... Товары-Проекты Товар Проект Гайки Лекарство от рака Болты Лекарство от рака Гайки Станция Мир ... ... Рис. 26. Декомпозиция отношения «Поставщики» Проектирование реляционных баз данных 43 При большом количестве записей и хотя бы на порядок меньшем раз нообразии значений атрибутов такая декомпозиция даст преимущество с точки зрения занимаемого дискового пространства. Экономия дискового пространства может, в свою очередь, привести и к другим улучшениям. Но откуда взялась идея такой декомпозиции? Чтобы понять это, введём несколько определений. Определение 3.26. Пусть задано отношение R и подмножества A1 , A2 , . . . An множества его атрибутов. Тогда говорят, что отно шение R удовлетворяет зависимости соединения ∗{A1 , A2 , . . . An } то гда и только тогда, когда любой допустимый набор кортежей от ношения R эквивалентен набору кортежей отношения, получаемо го путем соединения его проекций по подмножествам атрибутов A1 , A2 , . . . An . Замечание: зависимость соединения — это ещё более общая форма многозначной зависимости. Определение 3.27. Зависимость соединения ∗{A1 , A2 , . . . An } для отношения R называется тривиальной тогда и только тогда, ко гда одно из подмножеств атрибутов A1 , A2 , . . . An совпадает с са мим отношением R. Очевидно, что для любого отношения можно найти более одной триви альной зависимости соединения. Определение 3.28. Зависимость соединения ∗{A1 , A2 , . . . An } от ношения R подразумевается возможными ключами, если каждое из подмножеств атрибутов A1 , A2 , . . . An включает в себя какой-либо из возможных ключей целиком. Определение 3.29. Отношение R находится в пятой нормальной форме (5НФ) тогда и только тогда, когда оно находится в первой нормальной форме и каждая нетривиальная зависимость соедине ния в нём подразумевается возможными ключами. В нашем примере все три атрибута отношения являлись одним клю чом. Поэтому нахождение отношения в нормальной форме Бойса-Кодда вытекало автоматически из нахождения в первой нормальной форме. Мно гозначных зависимостей, нарушающих определение четвёртой нормальной формы, в отношении нет. Но есть проблемная зависимость соединения: ∗{{Поставщик, Товар}, {Поставщик, Проект}, {Товар, Проект}}. Именно эта зависимость и нарушает определение пятой нормальной формы. Поэтому имеет смысл декомпозиция на три более простых отно шения. Для закрепления понятия рассмотрим пример, когда декомпозиция бес смысленна (рис. 27). 44 Реляционная модель данных Номер заказа 12345 12346 12347 12348 ... Заказы Клиент Пупкин В.А. Козлов К.К. Свинкина Х.П. Пупкин В.А. ... Сумма 1500 2500 1500 1300 ... Рис. 27. Отношение «Заказы» У отношения «Заказы» ключ — атрибут «Номер заказа». Все осталь ные атрибуты зависят от него. Легко показать, что данное отношение на ходится в четвёртой нормальной форме. Также можно найти зависимость соединения: ∗{{Номер заказа, Клиент}, {Номер заказа, Сумма}}. Данная зависимость соединения не нарушает определения пятой нор мальной формы, так обе проекции включают в себя ключ «Номер заказа». То есть, зависимость соединения подразумевается возможным ключом. От ношение находится в пятой нормальной форме. В заключение темы нормализации отношений хотелось бы заметить, что в реальной жизни пятая и четвёртая нормальные формы используются редко. Обычно при разработке базы данных достаточно привести все отно шения к третьей нормальной форме или нормальной форме Бойса-Кодда. Более того, применение излишней нормализации во многих задачах может привести к потере производительности. Поэтому всегда важно помнить о компромиссе между нахождением базы данных в той или иной нормаль ной форме и быстродействием. Иногда полезно даже применять обратное действие — денормализацию таблиц. 3.2. Язык SQL. Как уже говорилось ранее, основным языком постро ения запросов к реляционным базам данных является язык SQL. Несмот ря на существующие стандарты данного языка в разных СУБД он имеет некоторые отличия. Подобные отличия могут быть как небольшими, так и довольно значительными. Более того, даже если в двух разных СУБД возможно выполнение одного и того же запроса, то это не гарантирует нам их взаимозаменяемость. Например, один и тот же запрос может в некото рой СУБД удовлетворять необходимым для автоматической оптимизации правилам построения, а в другой, наоборот, противоречить. Таким обра зом, на практике не имеет смысла говорить о языке SQL в общем, а стоит рассматривать конкретные его реализации. Данный курс ориентирован на Язык SQL 45 СУБД PostgreSQL версии 8.4 (или старше) [6, 5] . Также для расширения кругозора студентов иногда будут даваться сравнения с СУБД Oracle [7] . По синтаксису язык SQL похож на набор английских предложений. Название основных операторов соответствует английским словам или сло восочетаниям. Язык SQL нечувствителен к регистру букв. Например, опе ратор выборки SELECT (подробно будет рассмотрен далее) можно писать как заглавными буквами, так и строчными (select) и даже вперемешку (до пустим, SeLeCt). Название таблиц, столбцов и других объектов может со стоять из символов и букв. Если название содержит спецсимволы, пробелы или русские буквы, то его надо указывать в двойных кавычках. Например, "ìîÿ òàáëèöà". Константные текстовые строки или символы размещают ся в одинарных кавычках. Например, 'ñòðîêà'. Также для большинства программистов будет непривычно, что сравнение на эквивалентность двух значений обозначается не двумя знаками равно (==), а одним (=). Создание отношений (таблиц) Первое, что обычно делают при работе с пустой базой данных, — это определение новых таблиц (отношений). Для это предназначен оператор CREATE TABLE. В данном пособии будут рассматриваться не абсолютно все возможности для каждого оператора языка SQL, а только наиболее важные. Кратко для оператора создания таблиц их можно описать следу ющим образом: CREATE TABLE íàçâàíèå_òàáëèöû ( íàçâàíèå_ñòîëáöà òèï_äàííûõ [DEFAULT çíà÷åíèå_ïî_óìîë÷àíèþ℄ [îãðàíè÷åíèå_íà_ñòîáåö℄, [íàçâàíèå_ñòîëáöà òèï_äàííûõ [DEFAULT çíà÷åíèå_ïî_óìîë÷àíèþ℄ [îãðàíè÷åíèå_íà_ñòîáåö℄,℄ ... íàçâàíèå_ñòîëáöà òèï_äàííûõ [DEFAULT çíà÷åíèå_ïî_óìîë÷àíèþ℄ [îãðàíè÷åíèå_íà_ñòîáåö℄,℄ òàáëè÷íûå_îãðàíè÷åíèÿ ). В качестве названий таблиц и столбцов могут выступать любые после довательности букв и символов, по необходимости заключенные в двойные кавычки. Каждый столбец в реляционной базе данных должен соответство вать определенному домену (типу данных). Среди основных типов данных языка SQL для СУБД PostgreSQL можно выделить следующие: числовые типы: – int — знаковое 32-битное целое число; 46 Реляционная модель данных – float — дробное 32-битное число; – double precision — дробное 64-битное число; – serial — автоматически заполняющееся уникальными целыми числовыми значениями поле; символьные типы: – char(n) — символьная строка длиной в n знаков (недостающие символы заполняются пробелами); – varchar(n) — символьная строка длиной до n знаков; – text — символьная строка длиной не более 4096 знаков; другие типы: – date — дата (год, месяц, день) без указания времени; – time — время; – timestamp — дата и время; – interval — интервал времени (вместе с месяцами, годами и дня ми); – boolean — логический тип (истина или ложь). Тип float может также использоваться с указанием точности в виде количества бинарных цифр, указанного в скобках. Если это число боль ше 24, то автоматически используется double precision. Символьный тип char отличается от символьного типа varchar тем, что всегда содержит столько символов, сколько указано в скобках. Например, если мы указа ли тип данных char(10), а пытаемся записать в это поле строку 'qq', то реально запишется строка 'qq '. В случае же varchar(10) запи шется именно 'qq'. Тип данных text можно рассматривать как тип данных varchar(4096). В PostgreSQL тип данных date содержит только информа цию о дате без указания времени, в то время как во многих других СУБД (например, Oracle) под этим типом данных подразумевается и дата и время вместе. В Oracle типу данных varchar соответствует тип varchar2. В будущем нам потребуется знать, как преобразовать один тип дан ных к другому. Для этого в PostgreSQL есть оператор cast. Например, ast('2010-05-10' as date) преобразовывает символьную строку к ти пу date. В Oracle строка преобразовывается в дату при помощи метода to_date(). Ключевое слово DEFAULT позволяет задать значение по умолчанию. Если оно указано после имени и типа стобца вместе с каким-то значением, то при заполнении строк таблицы можно не указывать, что будет храниться в данном поле. В этом случае в данное поле будет помещено значение по умолчанию. Важным аспектом при создании таблицы является выбор ограничений целостности. Ограничения целостности — это набор правил, ограничива ющий возможные значения атрибутов таблицы. Ограничения целостности Язык SQL 47 могут применяться к одному атрибуту (мы будем называть их ограничения на столбец) или к нескольким атрибутам одновременно (мы будем назы вать их табличные ограничения). Различают следующие виды ограниче ний: первичный ключ (PRIMARY KEY), уникальность (UNIQUE), провер ку (CHECK), отсутствие пустых значений (NOT NULL), внешний ключ (FOREIGN KEY). Уникальность поля (набора полей) подразумевает, что все записи будут содержать различные значения данного поля (набора полей). Правда, если значение поля (или хотя бы одного из полей в наборе) пустое (NULL), то уникальность для него не проверяется. То есть даже, если поле объявлено уникальным, в таблице всё равно может быть несколько записей, в которых оно принимает пустое значение (NULL). Отсутствие пустых значений подразумевает, что в данное поле нельзя записать NULL. Всегда должно быть указано конкретное значение. Данное ограничение целостности применимо только к отдельным полям. Прежде чем говорить о первичном ключе, подумаем, что представляет возможный ключ. Несложно понять, что если некоторое поле или набор полей обладают свойством уникальности и не могут принимать пустое зна чение, то по ним можно однозначно выделить всю строку таблицы целиком. Таким образом, задание одновременно ограничений целостности UNIQUE и NOT NULL эквивалентно заданию возможного ключа. Первичный ключ позволяет выделить среди всех возможных ключей основной. Во всём остальном данное ограничение целостности равно паре ограничений целостностности UNIQUE и NOT NULL. Замечение: при использовании UNIQUE или PRIMARY KEY автома тически создаётся индексная структура, позволяющая ускорить поиск по данному полю (или набору полей). Ограничение CHECK позволяет самим придумать алгоритм фильтра ции допустимых значений. Например, для целых чисел можно контролиро вать диапазон вводимой информации: CREATE TABLE test( start_year int CHECK(start_year < 2011), end_year int CHECK(end_year >1900), CHECK((end_year - start_year) BETWEEN 1 AND 100) ); В наборе ограничений целостности особо выделяется внешний ключ, который позволяет связать значение в нескольких таблицах. Чтобы понять его назначение, рассмотрим пример (рис. 28). В этом примере видно, что, по идее разработчика таблиц, атрибут «Id_сотрудника» таблицы «Штат» может принимать только такие значе 48 Реляционная модель данных Id 123 124 125 126 ... Сотрудники Фамилия Имя Пупкин Василий Козлов Константин Свинкина Хлоя Паркинович Мойша ... ... Отчество Алексеевич Константинович Павловна Соломонович ... Штат Id_сотрудника 123 124 125 126 ... Должность Дворник Директор Продавец-кассир Глав. бух. ... Отдел Хозяйственный отдел Дирекция Столовая Бухгалтерия ... Оклад 5000 350000 7000 150000 ... Рис. 28. База данных «Штат» ния, которые соответствуют значениям поля «Id» в описывающей реальных людей таблице «Сотрудники». Но легко представить себе ситуацию, когда оператор базы данных может захотеть обмануть других людей, например, с целью получения зарплаты за несуществующего сотрудника. Тогда он мо жет сделать запись в таблице «Штат», указав несуществующее значение поля «Id_сотрудника». Как этого избежать? Ограничение целостности FOREIGN KEY позволяет указать, что зна чения определённого поля (или набора полей) одной таблицы должны удо влетворять множеству значений определённого поля (или набора полей) другой таблицы. При использовании данного ограничения целостности по пытка добавления несуществующего значения приведёт к ошибке базы дан ных. Тем самым, описанная выше махинация будет невозможна! Правда, данное ограничение не запрещает записывать в поля пустые значения. Пол ная форма записи FOREIGN KEY выглядит следующим образом: [CONSTRAINT èìÿ℄ FOREIGN KEY(íàáîð_ïîëåé_1) REFERENCES òàáëèöà2(íàáîð_ïîëåé_2) [ON DELETE äåéñòâèå ON UPDATE äåéñòâèå℄. В случае если внешний ключ применяется как ограничение на столбец, конструкция FOREIGN KEY опускается, поскольку и так ясно, какой ат рибут имеется в виду. Замечание: набор_полей_2 в таблице «таблица2» должен быть уни кальным. Язык SQL 49 Ограничение целостности FOREIGN KEY влияет не только на одну таблицу, но и на вторую тоже. Представим, что произойдёт, если мы за хотим из таблицы «Сотрудники» удалить Пупкина или изменить его Id. Тогда надо что-то делать и с его должностью в таблице «Штат». Тут есть следующие варианты: запретить это делать вообще (RESTRICT); сделать в таблице «Штат» то же самое, что и в таблице «Сотрудники»; присвоить всем соответствующим записям в таблице «Штат» в поле «Id_сотрудника» пустое значение (SET NULL). Пример: CREATE TABLE t1( id integer PRIMARY KEY, name text UNIQUE NOT NULL, birthday date UNIQUE NOT NULL, info text ); CREATE TABLE t2( t1_id integer REFERENCES t1(id) ON DELETE CASCADE ON UPDATE RESTRICT, name text, birthday date, info_t2 text, FOREIGN KEY(name, birthday) REFERENCES t1(name, birthday) ON DELETE CASCADE ON UPDATE CASCADE ); Замечание: большинство СУБД самостоятельно добавляют в таблицу системный столбец OID, заполняющийся автоматически уникальными но мерами. В некоторых версиях PostgreSQL эта возможность по умолчанию отключена. Тем не менее, надёжнее будет её включить при помощи коман ды WITH OIDS: CREATE TABLE t1( id integer PRIMARY KEY ) WITH OIDS; Для удаления таблиц применяется оператор DROP TABLE. Пример: DROP TABLE t1; Для внесения изменений в созданные таблицы используется оператор ALTER TABLE. 50 Реляционная модель данных Выборка из таблиц Выборка записей из таблиц осуществляется при помощи оператора SELECT. Кратко его можно описать следующим образом: SELECT [DISTINCT [ON(óñëîâèå)℄℄ {ñïèñîê_ïîëåé|*} FROM ñïèñîê_òàáëèö [WHERE óñëîâèå_èëüòðàöèè℄ [GROUP BY ñïèñîê_ãðóïïèðóåìûõ_ïîëåé [HAVING óñëîâèå_ãðóïïîâîé_èëüòðàöèè℄℄ [UNION|INTERSECT|EXCEPT [ALL℄ çàïðîñ℄ [ORDER BY óñëîâèå_ñîðòèðîâêè℄ [LIMIT êîëè÷åñòâî_ñòðîê℄ [OFFSET ñìåùåíèå℄ Работу оператора SELECT лучше всего рассматривать на примерах. Бу дем использовать для этого две таблицы (рис. 29): «students» (студенты) и «marks» (оценки). id integer students last_name first_name text text student_id integer marks subject pass_date text date second_name text mark varchar(8) Рис. 29. Таблицы для примеров Таблица «students» содержит поля «id» (уникальный номер), last_name (фамилия), first_name (имя) и second_name (отчество). Таблица «marks» содержит поля «student_id» (уникальный номер студента из таблицы «students»), «subject» (предмет), «pass_date» (дата сдачи) и «mark» (оцен ка). На рисунке также показаны типы данных, соответствующие полям. Пример 1.1. Выборка всех записей из таблицы «students»: SELECT * FROM students; Пример 1.2. Предположим, что нам не интересна информация об уни кальном номере студента и мы не хотим видеть этот столбец в результатах запроса: SELECT last_name, first_name, seond_name FROM students; Язык SQL 51 Пример 2.1. Выбирать можно не только значения полей, но и их ком бинации, полученные при помощи операторов или функций, и даже любые константные значения. Выберем фамилию, имя, отчество всех студентов, но не в виде трех отдельных полей, а как одно поле, в котором фамилию от имени и отчества отделяют пробелы. SELECT last_name || ' ' || first_name || ' ' || seond_name FROM students; Замечание: оператор || склеивает две строки в одну. Пример 2.2. Выберем для всех студентов их фамилию и инициалы, раз деляя пробелом. SELECT last_name || ' ' || substr(first_name, 1, 1) || '.' || substr(sname, 1, 1) || '.'; Замечание: функция substr вырезает подстроку в строке. Пример 2.3. Рассмотрим запрос, использующий константное поле — текущее время, а именно выбирающий фамилии всех студентов первым полем, вторым — текущее время, а третьим — просто единицу. SELECT last_name, now(), 1 FROM Students; Замечание: функция now() возвращает текущие дату и время. Пример 2.4. Теперь рассмотрим применение условного оператора CASE к полям. Выберем фамилии всех студентов. Если фамилия больше десяти символов в длину, то отрежем лишние символы и заменим их на многото чие. SELECT CASE WHEN length(last_name) > 10 THEN substr(last_name, 1, 10) || '...' ELSE last_name END FROM students; Замечание: функция length вычисляет длину текстовой строки. Пример 3. Если Вы хотите, чтобы поле в результате запроса носило название, отличное от того, что есть в таблице, то можно дать ему псевдо ним. Выберем фамилии всех студентов и укажем, чтобы поле last_name в результате запроса носило название surname. SELECT last_name AS surname FROM students; 52 Реляционная модель данных Не всегда в запросе требуется выбирать все записи. Для ограничения множества записей используется конструкция WHERE. Она позволяет пе речислить условия, накладываемые на поля отношения с целью фильтра ции результатов. Условия — это набор из одного или нескольких булевых значений (истина или ложь), объединенных операциями AND или OR. Пример 4.1. Выберем всех студентов, у которых фамилия начинается на букву И. SELECT * FROM students WHERE last_name like 'È%'; Замечание: оператор like выполняет сравнение по шаблону. Символ % означает любую строчку. Таким образом, È% означает любые текстовые строки, начинающиеся с заглавной буквы И. Существует также оператор ilike, который выполняет сравнение по шаблону, но без учета регистра букв, то есть не различая заглавные и строчные буквы. Пример 4.2. Выберем всех студентов, у которых имя Петр, а отчество Иванович. SELECT * FROM students WHERE first_name = 'Ïåòð' AND seond_name = 'Èâàíîâè÷'; Замечание: обратите внимание, что сравнение на равенство осуществ ляется посредством одного знака равенства, а не двух, как в большинстве языков программирования. В таблицах базы данных записи могут храниться в произвольном поряд ке. Но просматривать их обычно хочется в определённом порядке, отсор тированным по какому-либо признаку. Конструкция ORDER BY позволяет отсортировать записи по определенному полю или условию, наложенному на одно или несколько полей. Различают два вида сортировки: по возрас танию (обозначается как ASC) и по убыванию (обозначается как DESC). Пример 5. Выберем всех студентов, фамилия которых начинается на Ва, и отсортируем результаты запроса по фамилии, имени и отчеству в обратном порядке. SELECT * FROM students WHERE last_name like 'Âà%' ORDER BY last_name DESC, first_name DESC, seond_name DESC; Язык SQL 53 Очень редко требуемая информация находится в одной таблице. Гораз до чаще необходимые данные хранятся в двух или более таблицах. Но с точки зрения пользователя она нужна единым целым. Такие задачи реша ются при помощи объединения таблиц в запросах. Таблицы могут быть либо перечислены через запятую внутри конструкции FROM, либо соеди нены при помощи специальных операций соединения таблиц. Они также могут содержать одинаковые поля. Чтобы отличить в запросе два одинако вых поля в разных таблицах, перед ними ставится её название, отделенное точкой. Заполним наши таблицы из примера, чтобы было легче понять, как работает объединение (рис. 30). id 1 2 last_name Иванов Петров student_id 1 1 2 2 students first_name Иван Пётр marks subject Физика Химия Химия Рус. язык second_name Иванович Петрович pass_date 5.06.2010 7.06.2010 7.06.2010 9.06.2010 mark 5 4 3 4 Рис. 30. Заполненные таблицы для примеров Пример 6. Построим простое декартово соединение двух таблиц. SELECT students.*, marks.* FROM students, marks; Результатом будет отношение, содержащее все столбы из обеих таблиц и n × m записей, где n — количество записей в таблице students, а m — количество записей в таблице marks (рис. 31). Как видно из примера, простое объединение таблиц в большинстве си туаций бессмысленно. Было бы более логично сопоставить каждому сту денту только его оценки. Пример 7. Напишем запрос, выбирающий фамилию, имя, отчество сту дента, а также предмет и оценку, которую он по нему получил. Будем сопо ставлять оценки и студентов, сравнивая значения полей «id» (из таблицы «students») и «student_id» (из таблицы «marks»). 54 id 1 1 1 1 2 2 2 2 Реляционная модель данных last_name Иванов Иванов Иванов Иванов Петров Петров Петров Петров first_name Иван Иван Иван Иван Пётр Пётр Пётр Пётр результат second_name student_id Иванович 1 Иванович 1 Иванович 2 Иванович 2 Петрович 1 Петрович 1 Петрович 2 Петрович 2 subject Физика Химия Химия Рус. язык Физика Химия Химия Рус. язык pass_date 5.06.2010 7.06.2010 7.06.2010 9.06.2010 5.06.2010 7.06.2010 7.06.2010 9.06.2010 mark 5 4 3 4 5 4 3 4 Рис. 31. Заполненные таблицы для примеров SELECT students.last_name, students.first_name, students.seond_name, marks.subjet, marks.mark FROM students, marks WHERE students.id = marks.student_id ORDER BY students.last_name, students.first_name, students.seond_name; Данный пример будет работать не только в PostgreSQL, но и в других СУБД. Правда, не везде эффективно. В частности, в PostgreSQL для по вышения скорости выполнения запроса необходимо использовать внутрен нее соединение: INNER JOIN (слово INNER можно опускать). INNER JOIN всегда используется с одной из двух конструкций: ON или USING. Так как USING — это частная форма ON, то мы рассмотрим только первую из кон струкций. Пример 8.1. Конструкция ON содержит условие объединения таблиц. Перепишем предыдущий пример с её использованием. SELECT students.last_name, students.first_name, students.seond_name, marks.subjet, marks.mark FROM students INNER JOIN marks ON (students.id = marks.student_id) ORDER BY students.last_name, students.first_name, students.seond_name; Пример 8.2. Теперь представим, что у нас есть еще студент Сидоров Сидор Сидорович с номером 3, который пока не получил ни одной оцен ки. Если мы выполним запрос из примеров 7 и 8.1, то из-за условия Язык SQL 55 students.id = marks.student_id Сидоров не попадет в результаты. Что же делать, если нам надо не только показать все оценки, но и обязательно показать всех студентов? В этом случае можно воспользоваться внешним соединением OUTER JOIN. Различают три вида внешних соединений: левое (LEFT), правое (RIGHT) и полное (FULL). Рассмотрим сначала первые два из них. В предыдущих примерах таблица «students» стоит слева, а таб лица «marks» справа. Нам нужно, чтобы в результате запроса были все студенты. Если же есть оценки, сопоставленные несуществующим студен там, то они нам не нужны. Поэтому мы используем LEFT OUTER JOIN (так как таблица «students» стоит слева). SELECT students.last_name, students.first_name, students.seond_name, marks.subjet, marks.mark FROM students LEFT OUTER JOIN marks ON (students.id = marks.student_id) ORDER BY students.last_name, students.first_name, students.seond_name; Замечание: можно получить то же самое, если использовать RIGHT OUTER JOIN и поменять местами таблицы students и marks. Пример 8.3. Усложним задачу. Пусть теперь нужно посмотреть всех студентов и соответствующие им оценки, а также необходимо, чтобы были показаны и те оценки, которые поставлены несуществующим сту дентам. То есть необходимо выбрать также те оценки, у которых поле «student_id» содержит значение, не имеющее аналогов в поле «id» табли цы «students». Для этого мы воспользуемя полным внешним соединением FULL OUTER JOIN. SELECT students.last_name, students.first_name, students.seond_name, marks.subjet, marks.mark, marks.student_id FROM students FULL OUTER JOIN marks ON (students.id = marks.student_id) ORDER BY students.last_name, students.first_name, students.seond_name; Изменим схему таблиц. Пусть теперь есть отдельное отношение для хранения расписания сессии. Связь с оценками осуществляется посред ством поля «subject_id» (рис. 32). 56 Реляционная модель данных id 1 2 3 student_id 1 1 2 2 4 last_name Иванов Петров Сидоров marks subject_id 1 2 3 3 2 students first_name Иван Пётр Сидор mark 5 4 3 4 4 id 1 2 3 4 second_name Иванович Петрович Сидорович time_table subject pass_date Физика 5.06.2010 Химия 7.06.2010 Рус. язык 9.06.2010 История 11.06.2010 Рис. 32. Изменённая схема таблиц Пример 8.4. Решим задачу из последнего примера для новой схемы таблиц. SELECT students.last_name, students.first_name, students.seond_name, time_table.subjet, marks.mark, marks.student_id FROM students FULL OUTER JOIN (marks INNER JOIN time_table ON (marks.subjet_id = time_table.id)) ON (students.id = marks.student_id) ORDER BY students.last_name, students.first_name, students.seond_name; Поставим себе новую задачу. Попробуем подсчитать статистику полу чаемых студентами оценок. Сопоставим каждой из них количество студен ческих попыток сдачи, окончившихся её получением. Будем решать по по рядку. Для начала попробуем просто получить список возможных оценок без повторений. Есть два способа. Пример 9.1. Первый вариант — использовать конструкцию удаления повторений DISTINCT. SELECT DISTINCT mark FROM marks; Результатом будет один столбец с тремя значениями: 5, 4, 3. Пример 9.2. Второй способ — использовать оператор группировки GROUP BY. Язык SQL 57 SELECT mark FROM marks GROUP BY mark; Результат будет тот же. Но на самом деле эти конструкции работают по-разному. DISTINCT просто выбрасывает те записи, которые принимают уже выбранные значения. GROUP BY же раскладывает все записи целиком по группам, определенным значением ключа группировки — поля «mark», а затем показывает по одной строчке для каждой группы (в данном случае по одному значению поля «mark»). Поэтому с конструкцией GROUP BY воз можно сделать и более сложные запросы. Именно эта конструкция нам и понадобится для решения первоначально поставленной задачи. Замечание: в случае использования GROUP BY список выбираемых по лей может содержать только ключи группировки, либо результаты работы агрегатных функций. Агрегатная функция — это функция, применяемая к множеству значений (произвольного размера) и вычисляющая на его ос нове одно новое значение. Вычисление происходит пошагово (индуктивно) от одного элемента множества к другому. Основные агрегатные функции: count — количество элементов множества, sum — сумма элементов множества, max — максимальное значение среди элементов множества, min — минимальное значение среди элементов множества, avg — среднее значение элементов множества. Агрегатные функции применяются только в совокупности с оператором GROUP BY к множе ствам значений, образуемых полученными в результате группировки строками. Пример 9.3. Теперь мы можем решить исходную задачу про оценки. В примере 9.2 оператор GROUP BY раскладывает все записи на группы по значению поля «mark». Применим к этим группам агрегатную функцию count. SELECT mark, ount(*) FROM marks GROUP BY mark; Пример 9.4. Не обязательно применять агрегатную функцию ко всей строчке целиком. Можно считать, например, только одно из полей. SELECT mark, ount(student_id) FROM marks GROUP BY mark; Результат обоих запросов будет одинаковым — три пары значений: (5, 1), (4, 3), (3, 1). 58 Реляционная модель данных Пример 10. Решим более сложную задачу. Найдем, какая из оценок была наиболее популярна на экзаменах. Для начала предположим, что ес ли таких оценок было несколько, то нам нужна только одна из них и не важно какая. Воспользуемся конструкцией LIMIT, ограничивающей коли чество выбираемых записей. SELECT mark, ount(student_id) FROM marks GROUP BY mark ORDER BY ount(student_id) DESC LIMIT 1; Пример 11.1. Усложним нашу задачу. Если максимальное количество раз встречается не одна оценка, а несколько, то будут показаны все. LIMIT нам не поможет, так как мы не знаем, сколько таких оценок будет. Для этого нам потребуется познакомиться с вложенными запросами. Любая со ставляющая SQL запроса, будь то таблица, столбец, условие или какая-то еще компонента, может быть заменена на вложенный запрос (записанный в скобках). Для начала решим более простую задачу. Найдем, сколько раз встречалась самая популярная оценка. Мы будем искать максимум в результатах работы ранее разработанного запроса. SELECT max(nt) FROM (SELECT mark, ount(student_id) as nt FROM Marks GROUP BY Mark) num_marks; Замечание: если запрос используется вместо таблицы, то необходимо указать псевдоним — имя виртуальной таблицы, образованной его резуль татами. В данном примере мы выдали запросу псевдоним «num_marks». Пример 11.2. Теперь, используя запрос из примера 11.1, решим ис ходную задачу. Нам потребуется выбрать записи из запроса примера 9.4 такие, что значение count у них будет равно значению максимума, получен ному в примере 11.1. Для этого наложим условие на результат применения агрегатной функции count. Сгруппированные значения (а результат агре гатной функции — это именно сгруппированное значение) нельзя исполь зовать в фильтре WHERE, так как он выполняется раньше, чем группировка GROUP BY. Для условий, содержащих такие вещи, существует конструкция HAVING. SELECT mark, ount(student_id) FROM marks GROUP BY mark Язык SQL 59 HAVING ount(student_id) = (SELECT max(nt) FROM (SELECT mark, ount(student_id) as nt FROM marks GROUP BY mark) num_marks); Если у двух запросов одинаковый набор выбираемых полей, то их мож но соединить при помощи различных операций, знакомых по теории мно жеств. Доступны следующие операции: объединение запросов UNION, пере сечение запросов INTERSECT и разность запросов EXCEPT (в oracle MINUS). Пример 12. Найдем фамилии всех студентов, кто получил оценки 3 и 4. SELECT last_name FROM students INNER JOIN marks ON(students.id = marks.student_id) WHERE marks.mark = '4' UNION SELECT last_name FROM students INNER JOIN Marks ON(students.id = marks.student_id) WHERE marks.mark = '3'; В этом примере строится два запроса. Первый объединяет две табли цы: «students» и «marks» по уникальному номеру студента и выбирает все записи, где оценка равна 4. Так как у одного студента может быть несколько оценок, равных 4, то его фамилия может встречаться несколь ко раз. Но наc это не пугает! Второй запрос делает то же самое, но для оценки 3. Затем результаты запросов объединяются при помощи опера ции UNION. Операция UNION действует в терминах множеств. Поэтому все повторяющиеся фамилии выкидываются. Если мы хотели бы оставить фа милию студента столько раз, сколько он получил оценку, то надо было бы написать UNION ALL вместо UNION. Замечание: данный запрос не эффективен! Он приведен лишь для объ яснения оператора UNION. Добавление, изменение и удаление записей Добавление новых записей в таблицы осуществляется при помощи опе ратора INSERT. Есть два варианта его работы: добавление одной констант ной записи и добавление множества записей на основе результатов запро са. Вариант 1: INSERT INTO òàáëèöà(ñïèñîê_ïîëåé) VALUES(ñïèñîê çíà÷åíèé). 60 Реляционная модель данных Вариант 2: INSERT INTO òàáëèöà(ñïèñîê_ïîëåé) çàïðîñ. Пример добавления одной записи в таблицу «students»: INSERT INTO students(last_name, first_name, seond_name, id) VALUES('Êîçëîâ', 'Êîíñòàíòèí', 'Êîíñòàíòèíîâè÷', 5); Пример копирования всех оценок студента Сидорова студенту Козлову: INSERT INTO marks(student_id, subjet_id, mark) SELECT 5, subjet_id, mark WHERE student_id = 3; Изменение полей уже существующих в таблице записей осуществляет ся при помощи оператора UPDATE. Общий вид оператора следующий: UPDATE òàáëèöà SET ïîëå = çíà÷åíèå [, äðóãèå ïàðû ïîëå = çíà÷åíèå℄ [WHERE óñëîâèå℄. Пример замены фамилии студента Сидорова на Сидорчука: UPDATE students SET last_name = 'Ñèäîð÷óê' WHERE id = 3; Удаление записей из таблиц осуществляется при помощи оператора DELETE. Общий вид оператора следующий: DELETE FROM òàáëèöà [WHERE óñëîâèå℄. Пример удаления всех записей из таблицы marks: DELETE FROM marks; Пример удаления студента Сидорчука: DELETE FROM students WHERE id = 3; Рекомендуется самостоятельно изучить другие объекты языка SQL, не описанные в данном пособии: представления (VIEW), последовательности (SEQUENCE), функции (FUNCTION), агрегатные функции (AGREGGATE), тригге ры (TRIGGER), индексы (INDEX), а также управление правами доступа (ко манды GRANT и REVOKE) и транзакции (команды BEGIN, COMMIT, ROLLBACK и END) [3] . 4. Объектная модель данных Объектные или, как иногда говорят, объектно-ориентированные моде ли данных тесно связаны с понятием объектно-ориентированных языков и объектно-ориентированной парадигмой программирования. Мы будем счи тать объектной такую модель, которая полностью поддерживает следую щие понятия объектно-ориентированной парадигмы программирования: систему поддержки типов; классы и объекты; уникальные идентификационные номера объектов; наследование. Рассмотрим их подробнее. Нормальная объектная база данных должна предоставлять пользователю некоторый набор атомарных типов и набор средств, позволяющих создавать на их основе более сложные типы. Этот набор должен включать в себя, как минимум, следующие составляющие: структуры записей, коллекции, ссылки. Всё вместе это называется системой поддержки типов. Полноценная объектная модель должна позволять поддерживать осо бенный выводимый тип, называемый классом, который может включать в себя не только другие типы данных, но и методы, выполняемые в контексте объектов данного класса. Методы отличаются от обычных функций (проце дур) только тем, что всегда содержат один скрытый параметр — текущий экземпляр класса. Под экземпляром класса подразумевается либо константное значение данного типа, либо переменная, содержащая значения данного типа. Чтобы можно было различить два объекта, принадлежащих одному и тому же классу (типу) данных, в объектной модели принято сопоставлять каждому из них уникальный (среди всех объектов всех типов) идентифи кационный номер. Как и в объектно-ориентированных языках программирования, в объ ектной базе данных должно поддерживаться наследование классов. Если класс B наследует класс A, то он включает в себя все характеристики класса A, в том числе: тип, все методы и все атрибуты. Теперь мы можем дать определение объектной системы управления ба зами данных. Определение 4.1. Объектной СУБД называется такая систе ма управления базами данных, которая полностью поддерживает 62 Объектная модель данных объектную модель, включая определение данных и основные мани пуляции с ними (добавление, удаление, изменение и выборку). Большинство проектов, посвященных чисто объектным базам данных, появишихся в 90-х годах, на текущий момент на грани краха. Это связа но с тем, что производители реляционных систем вместо перехода к чисто объектным базам данных сделали ставку на пополнение существующих ре ляционных СУБД новыми возможностями, характерными для объектных баз данных. Такие СУБД получили название объектно-реляционных. Например, cтандарт SQL-99 определяет некоторые элементы характер ные для объектно-реляционных СУБД. В том числе: определение типов и методов для них, ссылочные типы и другие составляющие. Некоторые широко известные СУБД содержат и более яркие элемен ты объектной модели. Например, в СУБД PostgreSQL встречается такое понятие, как наследование. Написание интерфейсов к информационным системам в последнее вре мя чаще всего осуществляется на объектно-ориентированных языках про граммирования. При этом процесс преобразования данных из реляционной (или объектно-реляционной) СУБД в объекты, удобные для использова ния в контексте данного языка программирования, оказывается трудоемкой задачей. Причём неопытный пользователь может на этой стадии допустить огромное количество различных ошибок. Всё это определило появление нового класса программных компонент (библиотек), осуществляющих ав томатическое преобразование из записей отношений реляционной СУБД в объекты объектно-ориентированного языка программирования и наоборот. Такие механизмы принято называть объектно-реляционными преобразова телями (object-relation mappers). Одним из наиболее ярких на сегодняшний момент объектно-реляцион ных преобразователей является механизм ActiveRecord, входящий в состав системы RubyOnRails (ROR). 4.1. Язык ODL. В 1993 году в рамках стандарта ODMG-93 был сфор мулирован язык ODL (Object Definition Language) — стандартизованный язык, служащий для описания структур баз данных в терминах объектно ориентированного проектирования. Объявление нового класса на языке ODL выглядит следующим обра зом: ñlass Íàèìåíîâàíèå { ñïèñîê ñâîéñòâ } Свойства класса могут включать в себя атрибуты, связи или методы. Язык ODL 63 Пример. Определение класса «Star» с двумя атрибутами: простым строковым атрибутом «name» и атрибутом, определенном в виде струк туры из двух полей — «address». lass Star { attribute string name; attribute Strut Addr {string street, string ity} address; }; Основные атомарные типы языка ODL: integer — целое число, float — вещественное число, character — символ, string — строка символов, boolean — бинарное логическое значение, enumerations — перечисляемый тип. Пусть T и S — произвольные типы, а I — целое число. Тогда составные типы языка ODL выглядят следующим образом: Set < T > — множество значений типа T ; Ba g < T > — мультимножество значений типа T ; List < T > — список значений типа T ; Array < T, I > — массив из I элементов типа T ; Dictionary < T, S > — словарь сопоставлений значений типа T значениям типа S; Struct M {T1 F1 , T1 F2 , . . . , Tn Fn } — структура с обозначением M, состоящая из n полей с именами F j и типами T j . Замечание: мультимножество отличается от множества возможностью наличия повторяющихся значений. Атрибуты связи записываются при помощи ключевого слова relationship. Различают прямые и обратные связи. Обратные связи зада ются при помощи добавления конструкции inverse. Пример: два отношения «Movie» (фильм) и «Star» (звезда) находятся в отношении многие ко многим. lass Movie { ... relationship Set<Star> starsOf inverse Star::starredIn; } 64 Объектная модель данных lass Star { ... relationship Set<Movie> starredIn inverse Movie::starsOf; } Свойства классов могут быть также описаниями методов. Пример: класс «Movie» содержит определение одного метода «lengthInHours», воз вращающего объект дробного типа. В методе определена одна возможная исключительная ситуация, возникающая в случае отсутствия указания дли ны фильма («noLengthFound»). lass Movie { ... float lengthInHours() raises(noLengthFound); } Язык ODL не предназначен для написания законченных баз данных или программ. Это стандартизованное средство, позволяющее получить независимое (от языка программирования) описание объектов. При реаль ной работе такое представление конвертируется в термины используемого объектно-ориентированного языка программирования. 5. Примеры решения задач Пример 1. Дано отношение «A» (рис. 33). Name Петров Иванов Петров Петров Козлов Козлов Сидоров ... A Car BMW M3 VAZ 21093i FERRARI F40 VAZ 21093i Peugeot 307 BMW M3 BMW M3 ... Рис. 33. Таблица «A» Напишите запрос, показывающий владельцев (атрибут «Name») наибо лее популярной машины или машин (атрибут «Car»). Например, в данном случае (если за многоточием ничего не было бы) это Петров, Козлов, Си доров. Решение: SELECT Name FROM A WHERE Car IN (SELECT Car FROM A GROUP BY Car ORDER BY ount(*) DESC LIMIT 1); Пример 2. Дано отношение «Иерархия отделов предприятия» (рис. 34). Отдел ... Иерархия отделов предприятия Сотрудник Должность Подчиненный отдел ... ... ... Рис. 34. Таблица «Иерархия отделов предприятия» Известно, что в каждом отделе работает несколько сотрудников с раз ными должностями. Если один отдел стоит в иерархии выше, чем другой 66 Примеры решения задач отдел, то все сотрудники первого из них являются начальниками каждо го сотрудника второго из них. Ни одно из полей не может быть пусто. Найти ключи отношения. Исследовать его на нахождение в 6-ти нормаль ных формах (1НФ, 2НФ, 3НФ, НФБК, 4НФ, 5НФ). Если отношение не находится в какой-либо из нормальных форм, то провести декомпозицию данного отношения и повторить исследование для новых полученных таб лиц до нормальной формы Бойса-Кодда. Решение. Обозначим для удобства поля отношения латинскими буква ми A, B, C, D. Поскольку нигде не говорится, что в одном отделе сотруд ник не может занимать несколько должностей, и подчинённых отделов мо жет быть несколько, то ключом отношения являются все четыре атрибута: {A, B, C, D}. Неприводимых слева функциональных зависимостей отноше ние не содержит. Все атрибуты отношения не могут принимать в качестве значений мно жественные элементы. Таким образом, они атомарны. Отношение находит ся в первой нормальной форме. Неключевых атрибутов нет. Отсюда получаем, что так как отношение находится в первой нормальной форме, то оно находится и во второй нор мальной форме. Аналогично получаем, что из нахождения отношения в первой нормаль ной форме следует его нахождение и в третьей нормальной форме. У отношения всего один ключ. Следовательно, нахождение в нормаль ной форме Бойса-Кодда автоматически следует из нахождения в третьей нормальной форме. Теперь обратим внимание, что множество подчинённых отделов зависит только от самого отдела, но не зависит от атрибутов «Должность» и «Со трудник». Значит присутствует нетривиальная многозначная зависимость: A ։ {B, C}|D. Вывод: отношение «Иерархия отделов предприятия» не находится в чет вёртой нормальной форме! Выполним декомпозицию. В соответствии с найденной проблематичной многозначной зависимостью получаем два отношения (рис. 35). Исследуем полученные отношения. Все атрибуты по-прежнему атомар ны. Оба отношения находятся в первой нормальной форме. В отношении «Штат сотрудников» ключом являются все три атрибута. Поэтому по ана логии с исходной таблицей получаем, что отношение находится в нормаль ной форме Бойса-Кодда. Второе отношение состоит всего из двух атри бутов. Следовательно, оно находится в пятой нормальной форме. Задача решена. Задачи для самостоятельного решения 67 Штат сотрудников Отдел Сотрудник Должность ... ... ... Иерархия отделов предприятия Отдел Подчиненный отдел ... ... Рис. 35. Декомпозиция таблицы «Иерархия отделов предприятия» 5.1. Задачи для самостоятельного решения. В данном разделе предлагаются задачи, входившие в разные годы в состав экзаменационных билетов по курсу «Базы данных и СУБД». 1. Дано отношение: A position 0 1 2 ... bit 0 0 1 ... Напишите запрос, считающий поперечную четность. То есть рассчи тывающий восемь значений n j (j = 0 . . . 7), где n j — четности суммы всех битов, стоящих в позиции j + 8 × i для всех возможных i в дан ном отношений. 2. Даны отношения: A name Петров Козлов Сидоров Сидоров Сидоров ... subject Физика Химия Физ-ра Физ-ра Физ-ра ... mark 5 4 2 3 3 ... date 10.06.2004 11.06.2004 05.05.2004 08.05.2003 09.05.2004 ... study_year 2003/2004 2003/2004 2003/2004 2002/2003 2003/2004 ... и B name subject mark В отношении «A» у каждого студента могут быть различные оцен ки по одному и тому же предмету, так как предмет может быть в нескольких семестрах и студент может в одном и том же семестре сдавать этот предмет несколько раз. Напишите запрос (в одно дей ствие), который выбрал бы из таблицы «A» результирующие оценки по предметам, сдаваемым студентами в 2003/2004 учебном году, и заполнил бы ими таблицу «B». Причем необходимо внести только последние полученные студентами положительные отметки. 68 Примеры решения задач 3. Дано отношение: A key1 1 1 2 2 ... key2 2 1 2 3 ... Напишите запрос, удаляющий все записи, у которых значение пер вого из ключей повторяется. То есть для указанного примера запол нения таблицы должны остаться только записи: (1, 2) и (2, 2). 4. Дано отношение: A pid 1 1 1 ... post Профессор Профессор Доцент ... A pid 1 1 1 1 1 ... subject Физика Физика Химия Химия Химия ... status rrrrrr rrwrrw rrrrrr ... kid 36 31 36 ... date 10.10.2005 10.10.2005 11.10.2005 ... Напишите запрос, который всем записям с одинаковыми значения ми полей «pid» и «kid» одновременно устанавливает в поле «date» максимальное из соответствующего им множества значений данного поля. 5. Дано отношение: theme_n 1 2 1 2 3 ... pass_mark 10 5 10 5 5 ... result_mark 7 8 7 8 7 ... Напишите запрос, показывающий для каждого студента список всех сданных им предметов. Предмет считается сданным, если по каждой теме данного предмета у студента result_mark ≥ pass_mark. 6. Дано отношение: A N день предмет аудитория группа Напишите запрос, который находит группы с максимальным числом пар в неделю. Таких групп может быть несколько. 7. Даны отношения: A id 1 2 ... title Физика. Учебник. Химия. Учебник. ... year 2005 2004 ... и B pid 1 2 1 ... aid 1 1 2 ... name Иванов И.И. Петров П.П. Иванов И.И. ... type студент студент студент Напишите запрос, выбирающий из таблицы «A» все такие книги, у которых ни один из соавторов не является студентом. 8. Дано отношение: A name Иванов И.И. Иванов И.И. Петров П.П. Козлов К.К. ... post Дворник Сантехник Профессор Доцент ... grade К.т.н К.т.н б/c Д.т.н. ... type штатный совместитель штатный совместитель ... Задачи для самостоятельного решения 69 Напишите запрос, считающий процент сотрудников, имеющих уче ную степень среди общего числа персонала. Для данного примера ответ должен быть 66.7%. 9. Даны два отношения: CREATE TABLE A ( field_a1 integer primary key; field_a2 integer not null; ); CREATE TABLE B ( field_b1 integer primary key; field_b2 integer not null; ); Напишите триггер, не позволяющий записывать в таблицу «A» запи си, у которых значение поля «field_a1» принадлежит множеству зна чений поля «field_b1» таблицы «B», a значение поля «field_a2» при надлежит множеству значений поля «field_b2» также таблицы «B». То есть, например, если в «B» есть записи {1, 1}, {2, 2}, то в «A» не должны допускаться записи {1, 1}, {1, 2}, {2, 1}, {2, 2}. 10. Дано отношение: CREATE TABLE A ( field_a1 text primary key; ); Напишите триггер, который не позволял бы никакие действия с таб лицей «A», после которых в ней могло бы оказаться меньше десяти записей, у которых значения поля «field_a1» были бы разные. То есть таблица всегда должна содержать десять записей с различными значениями поля «field_a1». 11. Напишите агрегатную функцию, которая позволяла бы найти в задан ном множестве текстовых значений длину наибольшей строки, содер жащей подстроку ’PostgreSQL’. Пример: Отношение A f1 ’Тест’ ’Тест PostgreSQL’ ’Тест 2 PostgreSQL’ ’Тест - просто тест’ f2 1 2 3 4 Назовем требуемую функцию “findMax”. Тогда запрос “SELECT findMax(f1) FROM A” должен вернуть следующий результат: 17 (17 — длина строки ’Тест 2 PostgreSQL’). 70 Примеры решения задач 12. Напишите агрегатную функцию, которая позволяла бы склеивать все заданные текстовые значения в одну строку через запятую и пробел. Пример: Отношение A f1 ’Колбаса’ ’Масло’ ’Пиво’ Пусть наша функция называется “join”. Тогда запрос “SELECT join(f1) FROM A” должен вернуть следующий результат: ’Колбаса, Масло, Пиво’. 13. Напишите функцию sign(int), вычисляющую функцию сигнума от це лого числа. 14. Реализуйте самостоятельно для заданных таблиц «A» и «B» кон струкцию FOREIGN KEY(field) REFERENCES table(table_field) ON DELETE SET DEFAULT. 15. Дано отношение: A id 1 2 3 wid 521400 wname Юриспруденция 651200 Энергомашиностроение sid sname 060800 101200 Экономика и управление Двигатели внутреннего сгорания Напишите функцию, которая для указанной таблицы по значению по ля «id» возвращает корректную информацию о специальности. На пример, результат запроса “SELECT id, f1(id) FROM A” будет такой: A id 1 2 3 f1 Направление 521400 Юриспруденция. Специальность 060800 Экономика и управление. Направление 651200 Энергомашиностроение, специальность 101200 Двигатели внутреннего сгорания. Обратите внимание на знаки препинания и регистр букв. Список литературы и интернет-ресурсов 1. Гарсиа-Молина Г., Ульман Д., Уидом Д. Системы баз данных. Полный курс. — М.: Вильямс, 2003. 2. Дейт К.Дж. Введение в системы баз данных. — М.: Вильямс, 2001. 3. Уорсли Д., Дрейк Д. PostgreSQL для профессионалов. — М.: Питер, 2003. 4. http://www.l.am.a.uk/teahing/2003/ Databases/oo-manifesto.pdf Malcolm Atkinson, Francois Bancilhon, David DeWitt, Klaus Dittrich, David Maier, Stanley Zdonik. The Object Oriented Database System Manifesto. Proc. 1st International Conference on Deductive and Object-Oriented Databases, Kyoto, Japan 1989. New York, N.Y.: Elsevier Science 1990. 5. http://ru.wikipedia.org/wiki/PostgreSQL — Википедия (свобод ная энциклопедия) о СУБД PostgreSQL. 6. http://www.postgresql.org PostgreSQL. — Официальный сайт 7. http://www.orale.om/us/produts/database/index.html — Официальный сайт СУБД Oracle. СУБД Учебное издание Радыгин Виктор Юрьевич БАЗЫ ДАННЫХ И СУБД Учебно-методическое пособие Редактор Н.А. Киселёва Санитарно-эпидемиологическое заключение №77.99.60.953.Д.006314.05.07 от 31.05.2007 Подписано в печать 14.01.10 Формат бумаги 60x84/16. Изд. № 127/10-у Усл.печ.л. 4,5. Уч.-изд.л. 4,75. Тираж 100. Заказ № 341 Издательство МГИУ, 115280, Москва, Автозаводская, 16 www.izdat.msiu.ru; e-mail: [email protected]; тел. (495) 620-39-90 По вопросам приобретения продукции издательства МГИУ обращаться по адресу: 115280, Москва, Автозаводская ул., 16 www.izdat.msiu.ru; e-mail: [email protected]; тел. (495) 620-39-90 Отпечатано в типографии издательства МГИУ