Направление объектно-ориентированных баз данных (ООБД) возникло сравнительно давно. Публикации появлялись уже в середине 80-х гг. Однако наиболее активно это направление развивается в последние годы. С каждым годом увеличивается число публикаций и реализованных коммерческих и экспериментальных систем.
Возникновение направления ООБД определяется прежде всего потребностями практики: необходимостью разработки сложных информационных прикладных систем, для которых технология предшествующих систем БД не была вполне удовлетворительной.
Конечно, ООБД возникли не на пустом месте. Соответствующий базис обеспечивают как предыдущие работы в области БД, так и давно развивающиеся направления языков программирования с абстрактными типами данных и объектно-ориентированных языков программирования.
Что касается связи с предыдущими работами в области БД, то наиболее сильное влияние на работы в области ООБД оказывают проработки реляционных СУБД и следующее хронологически за ними семейство БД, в которых поддерживается управление сложными объектами. Кроме того, исключительное влияние на идеи и концепции ООБД и, как кажется, всего объектно-ориентированного подхода оказал подход к семантическому моделированию данных. Большое влияние оказывают также развивающиеся параллельно с ООБД направления дедуктивных и активных БД.
Среди языков и систем программирования наибольшее первичное влияние на ООБД оказал Smalltalk. Этот язык сам по себе не является полностью пионерским, хотя в нем была введена новая терминология, являющаяся теперь наиболее распространенной в объектно-ориентированном программировании. На самом деле, Smalltalk основан на ряде ранее выдвинутых концепций.
Большое число опубликованных работ не означает, что все проблемы ООБД полностью решены. Как отмечается в Манифесте группы ведущих ученых, занимающихся ООБД, современная ситуация с ООБД напоминает ситуацию с реляционными системами середины 70-х гг. При наличии большого количества экспериментальных проектов (и даже коммерческих систем) отсутствует общепринятая объектно-ориентированная модель данных, и не потому, что нет ни одной разработанной полной модели, а по причине отсутствия общего согласия о принятии какой-либо модели. Имеются и более конкретные проблемы, связанные с разработкой декларативных языков запросов, выполнением и оптимизацией запросов, формулированием и поддержанием ограничений целостности, синхронизацией доступа и управлением транзакциями и т.д.
В наиболее общей и классической постановке объектно-ориентированный подход базируется на следующих концепциях:
· объекта и идентификатора объекта;
· атрибутов и методов;
· классов;
· иерархии и наследования классов.
Любая сущность реального мира в объектно-ориентированных языках и системах моделируется в виде объекта. Любой объект при своем создании получает генерируемый системой уникальный идентификатор, который связан с объектом все время его существования и не меняется при изменении состояния объекта.
Каждый объект имеет состояние и поведение. Состояние объекта – набор значений его атрибутов. Поведение объекта – набор методов (программный код), оперирующих над состоянием объекта. Значение атрибута объекта – это тоже некоторый объект или множество объектов. Состояние и поведение объекта инкапсулированы в объекте; взаимодействие объектов осуществляется на основе передачи сообщений и выполнении соответствующих методов.
Множество объектов с одним и тем же набором атрибутов и методов образует класс объектов. Объект должен принадлежать только одному классу (если не учитывать возможности наследования). Допускается наличие примитивных предопределенных классов, объекты-экземпляры которых не имеют атрибутов: целые, строки и т.д. Класс, объекты которого могут служить значениями атрибута объектов другого класса, называется доменом этого атрибута.
Допускается порождение нового класса на основе уже существующего класса – наследование. В этом случае новый класс, называемый подклассом существующего класса (суперкласса), наследует все атрибуты и методы суперкласса. В подклассе, кроме того, могут быть определены дополнительные атрибуты и методы. Различаются случаи простого и множественного наследования. В первом случае подкласс может определяться только на основе одного суперкласса, во втором случае суперклассов может быть несколько. Если в языке или системе поддерживается единичное наследование классов, набор классов образует древовидную иерархию. При поддержании множественного наследования классы связаны в ориентированный граф с корнем, называемый решеткой классов. Объект подкласса считается принадлежащим любому суперклассу этого класса.
Одной из более поздних идей объектно-ориентированного подхода является идея возможного переопределения атрибутов и методов суперкласса в подклассе (перегрузки методов). Эта возможность увеличивает гибкость, но порождает дополнительную проблему: при компиляции объектно-ориентированной программы могут быть неизвестны структура и программный код методов объекта, хотя его класс (в общем случае – суперкласс) известен. Для разрешения этой проблемы применяется так называемый метод позднего связывания, означающий, по сути дела, интерпретационный режим выполнения программы с распознаванием деталей реализации объекта во время выполнения посылки сообщения к нему. Введение некоторых ограничений на способ определения подклассов позволяет добиться эффективной реализации без потребностей в интерпретации.
Наиболее важным новым качеством ООБД, которого позволяет достичь объектно-ориентированный подход, является поведенческий аспект объектов. В прикладных информационных системах, основывавшихся на БД с традиционной организацией (вплоть до тех, которые базировались на семантических моделях данных), существовал принципиальный разрыв между структурной и поведенческой частями. Структурная часть системы поддерживалась всем аппаратом БД, ее можно было моделировать, верифицировать и т.д., а поведенческая часть создавалась изолированно. В частности, отсутствовали формальный аппарат и системная поддержка совместного моделирования и гарантирования согласованности этих структурной (статической) и поведенческой (динамической) частей. В среде ООБД проектирование, разработка и сопровождение прикладной системы становится процессом, в котором интегрируются структурный и поведенческий аспекты. Конечно, для этого нужны специальные языки, позволяющие определять объекты и создавать на их основе прикладную систему.
В настоящее время ведется очень много экспериментальных и производственных работ в области объектно-ориентированных СУБД. Уже несколько лет назад отмечалось существование по меньшей мере тринадцати коммерчески доступных систем ООБД. Среди них системы O2, ORION, GemStone и Iris.
1. Язык SQL – функции запросов и основные возможности
Развитие языка SQL
Увеличение объема и структурной сложности хранимых данных, расширение круга пользователей информационных систем привели к широкому распространению наиболее удобных и сравнительно простых для понимания реляционных (табличных) систем управления базами данных (СУБД). Почти все базы данных, созданные с конца 1970-х годов, основаны на реляционном подходе, кроме того, подавляющее большинство научных исследований в области баз данных в течение последних 25 лет приходилось на долю реляционных баз данных. Реляционный подход представляет собой основную тенденцию сегодняшнего рынка, и реляционная модель – наиболее существенная разработка в истории развития баз данных.
Все языки манипулирования данными, созданные до появления реляционных баз данных и разработанные для многих СУБД персональных компьютеров, так называемые дореляционные языки манипулирования данными (ЯМД) – это языки, ориентированные на операции с данными, представленными в виде логических записей файлов. Их применение требовало от пользователей детального знания организации хранения данных и достаточных усилий для указания не только того, какие данные нужны, но и того, где они размещены и как шаг за шагом можно получить их.
Появление теории реляционных баз данных и предложенного Коддом Э.Ф. языка запросов “alpha”, основанного на реляционном исчислении, инициировало разработку ряда языков запросов, которые можно отнести к двум классам:
1. Алгебраические языки запросов – языки, позволяющие выражать запросы средствами специализированных операторов, применяемых к отношениям (JOIN – соединить, INTERSECT – пересечь, SUBTRACT – вычесть и т.д.).
2. Языки исчисления предикатов – набор правил для записи выражения, определяющего новое отношение из заданной совокупности существующих отношений.
Разработка, в основном, шла в отделениях фирмы IBM (языки ISBL, SQL – Structured Query Language – структурированный язык запросов, QBE – Query-By-Example – запрос по образцу) и университетах США (PIQUE, QUEL). Последний создавался для СУБД INGRES (Interactive Graphics and Retrieval System), которая была разработана в начале 1970-х годов в университете шт. Калифорния и сегодня входит в пятерку лучших профессиональных СУБД. Из всех этих языков полностью сохранились и развиваются QBE и SQL (которые и будут рассматриваться в данной юните), а из остальных взяты в расширение внутренних языков СУБД только наиболее интересные конструкции. В начале 1980-х годов SQL “победил” другие языки запросов и стал фактическим стандартом таких языков для профессиональных реляционных СУБД. В 1986 году он стал международным стандартом языка баз данных и начал внедряться во все распространенные СУБД персональных компьютеров.
Непроцедурный, структуризированный язык запросов (SQL) – язык, ориентированный на операции с данными, представленными в виде логически взаимосвязанных совокупностей таблиц. Особенность предложений языка запросов SQL – ориентированность в большей степени на конечный результат обработки данных, чем на процедуру этой обработки. SQL сам определяет, где находятся данные, какие индексы и даже наиболее эффективные последовательности операций следует использовать для их получения: не надо указывать эти детали в запросе к базе данных.
Непрерывный рост быстродействия, а также снижение энергопотребления, размеров и стоимости компьютеров привели к резкому расширению возможных рынков их сбыта, круга пользователей, разнообразия типов и цен. Естественно, что расширился спрос на разнообразное программное обеспечение. Борясь за покупателя, фирмы, производящие программное обеспечение, стали выпускать на рынок все более и более интеллектуальные и, следовательно, объемные программные комплексы. Приобретая (желая приобрести) такие комплексы, многие организации и отдельные пользователи часто не могли разместить их на собственных ЭВМ, однако не хотели и отказываться от нового сервиса. Для обмена информацией и ее обобществления были созданы сети ЭВМ, где обобществляемые программы и данные стали размещать на специальных обслуживающих устройствах – файловых серверах.
СУБД, работающие с файловыми серверами, позволяют множеству пользователей разных ЭВМ (иногда расположенных достаточно далеко друг от друга) получать доступ к одним и тем же базам данных. При этом упрощается разработка различных автоматизированных систем управления организациями, учебных комплексов, информационных и других систем, где множество сотрудников (учащихся) должны использовать общие данные и обмениваться создаваемыми в процессе работы (обучения). Однако при такой идеологии вся обработка запросов из программ или с терминалов пользовательских ЭВМ выполняется на этих же ЭВМ. Поэтому для реализации даже простого запроса ЭВМ часто должна считывать из файлового сервера и (или) записывать на сервер целые файлы, что ведет к конфликтным ситуациям и перегрузке сети.
Для исключения указанных и некоторых других недостатков была предложена технология “клиент-сервер” – технология обработки данных в сетях ЭВМ, по которой запросы пользовательских ЭВМ (клиент) обрабатываются на специальных серверах баз данных (сервер), а на ЭВМ-клиент возвращаются лишь результаты обработки запроса. При этом, естественно, нужен единый язык общения с сервером и в качестве такого языка выбран SQL. Поэтому все современные версии профессиональных реляционных СУБД (DB2, Oracle, Ingres, Informix, Sybase, Progress, Rdb) и даже нереляционных СУБД (например, Adabas) используют технологию “Клиент-Сервер” и язык SQL. К тому же приходят разработчики СУБД персональных ЭВМ, многие из которых уже сегодня снабжены языком SQL.
Стандартизация SQL
Статус de facto SQL как стандартного языка реляционной базы данных был зафиксирован с принятием его в 1986 г. в качестве стандарта Американского Национального Института стандартов (ANSI). Другими стандартами для SQL являются SQL Access Group SAG – группа стандартов, поддерживаемая более чем 40 крупными государственными и коммерческими пользователями, ISO (Национальная Организация Стандартов), X/Open (группа стандартов для UNIX), собственно SQL, утвержденный IBM System Application Architecture и даже федеральным правительством США.
К моменту принятия последней спецификации ISO SQL-92 она поддерживалась не всеми коммерческими продуктами (ISO SQL-92 и ANSI SQL-92 являются аналогичными стандартами). Вследствие этого в настоящее время наиболее полно реализованным стандартом является спецификация ANSI SQL-89.
Стандарт ANSI SQL-89 поддерживает три формы SQL: модульный язык (позволяет создавать процедуры, которые затем могут вызываться из традиционных языков программирования), встроенный SQL (статический SQL – предложения которого физически встраиваются в исходный код программы) и непосредственный вызов (запросы выполняются интерактивно). Можно говорить о двойном назначении SQL – использованного языка SQL как интерактивного (для выполнения запросов) и как встроенного (для построения прикладных программ).
Недавно принятый стандарт ANSI SQL-92 расширяет возможности встроенных SQL-операторов и позволяет включить динамический SQL. Несмотря на то что динамический SQL пока не может по эффективности сравниться со статическим, он предоставляет большую гибкость при формировании запросов к базе данных, поскольку определение SQL-операторов и их соединение с базой данных могут быть отложены до тех пор, пока не наступит их время выполнения.
И в интерактивной и во встроенной формах SQL имеются многочисленные части, или субподразделения. К сожалению, эти термины не используются повсеместно во всех реализациях. Они подчеркиваются ANSI и полезны на концептуальном уровне, но большинство SQL программ практически не обрабатывают их отдельно, так что они, по существу, становятся функциональными категориями команд SQL. DDL (Data Definition Language – язык определения данных) – так называемый язык описания схемы в стандарте ANSI, состоит из команд, которые создают объекты (таблицы, индексы, просмотры и т.д.) в базе данных. DML (Data Manipulation Language – язык манипулирования данными) – это набор команд, которые определяют, какие значения представлены в таблицах в любой момент времени. DCL (Data Control Language – язык управления данными) – комплекс средств, которые определяют, разрешить ли пользователю выполнять определенные действия или нет.
Реализация в SQL концепции операций, ориентированных на табличное представление данных, позволило создать компактный язык с небольшим (менее 30) набором предложений. Как в интерактивном, так и в встроенном SQL существуют следующие предложения:
1) предложения определения данных (определение баз данных, а также определение и уничтожение таблиц и индексов);
2) запросы на выбор данных (предложение SELECT);
3) предложения модификации данных (добавление, удаление и изменение данных);
4) предложения управления данными (предоставление и отмена привилегий на доступ к данным, управление транзакциями и другие).
Кроме того, SQL предоставляет возможность выполнять в этих предложениях следующее:
a) арифметические вычисления (включая разнообразные функциональные преобразования), обработку текстовых строк и выполнение операций сравнения значений арифметических выражений и текстов;
b) упорядочение строк и (или) столбцов при выводе содержимого таблиц на печать или экран дисплея;
c) создание представлений (виртуальных таблиц), позволяющих пользователям иметь свой взгляд на данные без увеличения их объема в базе данных;
d) запоминание выводимого по запросу содержимого таблицы, нескольких таблиц или представления в другой таблице (реляционная операция присваивания).
e) агрегатирование данных: группирование данных и применение к этим группам таких операций, как среднее, сумма, максимум, минимум, число элементов и т.п.
Типы данных
Основные типы данных SQL – используемые языком SQL основные типы данных, форматы которых могут несколько различаться для разных СУБД: целое число; десятичное число; вещественное число; символьная строка фиксированной или переменной длины; дата в формате (по умолчанию mm/dd/yy); время в формате (по умолчанию hh.mm.ss); деньги в формате, определяющем символ денежной единицы и его расположение (суффикс или префикс) и др.
Рассмотрим основные типы данных SQL:
INTEGER – целое число (обычно до 10 значащих цифр и знак);
SMALLINT – “короткое целое” (обычно до 5 значащих цифр и знак);
DECIMAL(p,q) – десятичное число, имеющее p цифр (0 < p < 16) и знак; с помощью q задается число цифр справа от десятичной точки (q < p, если q = 0, оно может быть опущено);
FLOAT – вещественное число с 15 значащими цифрами и целочисленным порядком, определяемым типом СУБД;
CHAR(n) – символьная строка фиксированной длины из n символов (0 < n < 256);
VARCHAR(n) – символьная строка переменной длины, не превышающей n символов (n > 0 и разное в разных СУБД, но не больше 4096);
DATE – дата в формате, определяемом специальной командой (по умолчанию mm/dd/yy); поля даты могут содержать только реальные даты, начинающиеся за несколько тысячелетий до нашей эры и ограниченные V–X тысячелетием нашей эры;
TIME – время в формате, определяемом специальной командой (по умолчанию hh.mm.ss);
DATETIME – комбинация даты и времени;
MONEY – деньги в формате, определяющем символ денежной единицы ($, руб,...) и его расположение (суффикс или префикс), точность дробной части и условие для показа денежного значения.
В некоторых СУБД еще существует тип данных LOGICAL, DOUBLE и ряд других. Так, СУБД INGRES предоставляет пользователю возможность самостоятельного определения новых типов данных, например, плоскостные или пространственные координаты, единицы различных метрических систем, пяти- или шестидневные недели (рабочая неделя, где сразу после пятницы или субботы следует понедельник), дроби, графика, большие целые числа и т.п.
4. 1.4. Средств а определения схемы
Средством определения схемы базы данных, как уже говорилось, является язык описания схемы DDL, который состоит из предложений (команд), которые в свою очередь создают объекты (таблицы, индексы, просмотры и т.д.) в базе данных. Рассмотрим эти предложения.
С точки зрения пользователя базу данных можно представить следующим образом (рис 1).
Рис. 1. База данных в восприятии пользователя
При этом следует различать базовые и виртуальные таблицы. Базовая таблица – таблица реляционной БД, для каждой строки которой в действительности имеется некоторый двойник, хранящийся в физической памяти ЭВМ, и которая создается с помощью предложения CREATE TABLE (создать таблицу). Виртуальная таблица (представление) – таблица, которая не существует в базе данных, но как бы существует с точки зрения пользователя и в которой формируются результаты запросов на получение данных из базовых таблиц.
Таблицы создаются командой CREATE TABLE. Эта команда создает структуру таблицы. Значения вводятся с помощью DML команды INSERT (см. далее). Команда CREATE TABLE в основном определяет имя таблицы в виде описания набора имен столбцов, указанных в определенном порядке. Она также определяет типы данных и размеры столбцов. Каждая таблица должна иметь, по крайней мере, один столбец.
При записи синтаксических конструкций используются следующие обозначения:
– звездочка (*) для обозначения “все” – употребляется в обычном для программирования смысле, т.е. “все случаи, удовлетворяющие определению”;
– квадратные скобки ([]) – означают, что конструкции, заключенные в эти скобки, являются необязательными (т.е. могут быть опущены);
– многоточие (...) – указывает на то, что непосредственно предшествующая ему синтаксическая единица факультативно может повторяться один или более раз;
– прямая черта (|) – означает наличие выбора из двух или более возможностей. Например обозначение элемент 1 | элемент 2 указывает, можно выбрать один из элементов элемент 1 или элемент 2; когда же один из элементов выбора заключен в квадратные скобки, то это означает, что он выбирается по умолчанию (так, [ элемент 1 ]| элемент 2 означает, что отсутствие всей этой конструкции будет восприниматься как выбор элемент1);
– точка с запятой (;) – завершающий элемент предложений SQL;
– запятая (,) – используется для разделения элементов списков;
– пробелы () – могут вводиться для повышения наглядности между любыми синтаксическими конструкциями предложений SQL;
– термины т аблица, столбец,... – заменяют (с целью сокращения текста синтаксических конструкций) термины имя_таблицы, имя_столбца,..., соответственно.
Согласно этим правилам синтаксис команды CREATE TABLE будет следующим:
CREATE TABLE базовая_таблица (столбец тип_данных
[,столбец тип_данных]...);
Таблицы принадлежат пользователю, который их создал, и имена всех таблиц, принадлежащих данному пользователю, должны отличаться друга от друга, как и имена всех столбцов внутри данной таблицы. Отдельные таблицы могут использовать одинаковые имена столбцов, даже если они принадлежат одному и тому же пользователю. Ссылаться к этим таблицам можно с помощью имени владельца этих таблиц, сопровождаемого точкой. Например, таблица Employees, созданная Smith, будет называться Smith.Employees, когда она упоминается каким-то другим пользователем. Порядок столбцов в таблице определяется порядком, в котором они указаны.
Индекс – это структура данных, которая помогает СУБД быстрее обнаруживать отдельные записи в таблице, а потому позволяет сократить время выполнения запросов пользователя. Таблицы могут иметь большое количество строк, а так как строки не находятся в каком-нибудь определенном порядке, на их поиск по указанному значению может потребоваться время. Индекс в базе данных аналогичен предметному указателю, приведенному в конце книги. Это структура, связанная с таблицей и предназначенная для поиска информации по тому же принципу, что и предметный указатель в книге. Индекс – это и достаточно сложная проблема, и в то же время обеспечение способа объединения всех значений в группы из одной или больше строк, которые отличаются одна от другой.
Когда пользователь создает индекс таблицы – он задает столбец, по которому будет производиться индексация. База данных запоминает соответствующий порядок всех значений этого столбца в области памяти.
Предположим, что таблица заказчиков имеет тысячи входов, а требуется найти заказчика с номером=2999. Так как строки не упорядочены, программа будет просматривать всю таблицу, строку за строкой, проверяя каждый раз значение поля номера на равенство значению 2999. Однако, если бы имелся индекс в столбце “номер”, то программа могла бы выйти на номер 2999 прямо по индексу. В то время как индекс значительно улучшает эффективность запросов, использование индекса несколько замедляет операции модификации DML (такие, как INSERT и DELETE), что связано с затратами времени на создание или удаление индекса, а сам индекс занимает объем памяти. Следовательно, каждый раз, когда создается таблица, необходимо принимать решение, индексировать ее или нет. Индексы могут состоять из многочисленных полей. Если больше чем одно поле указывается для одного индекса, второе упорядочивается внутри первого, третье внутри второго и т.д.
Предложение для создания индекса обычно следующее (следует заметить, что стандарт ANSI не поддерживает индексы, хотя они очень полезны и широко применяемы):
CREATE INDEX ON (имя_столбца[,]...);
Таблица должна уже быть создана и должна содержать имя столбца. Однажды созданный индекс будет невидим пользователю. SQL самостоятельно решает, когда он необходим чтобы ссылаться на него, и делает это автоматически.
Представления (View) – это таблицы, чье содержание выбирается или получается из других таблиц. Они работают в запросах и операторах DML точно так же, как и базовые таблицы, но не содержат никаких собственных данных. Представления подобны окнам, через которые вы просматриваете информацию, фактически храняющуюся в базовой таблице. Представление – это фактически запрос, который создается по требованию отдельного пользователя в момент поступления этого требования.
Представление создается командой CREATE VIEW. Она состоит из слов CREATE VIEW (создать представление), имени представления, которое нужно создать, слова AS (как) и, далее, запроса.
Синтаксис предложения CREATE VIEW имеет вид:
CREATE VIEW имя_представления
[(столбец[,столбец]...)]
AS подзапрос;
Полученное представление можно использовать точно так же, как и любую другую таблицу. Она может быть запрошена, модифицирована, вставлена, удалена и соединена с другими таблицами и представлениями.
Преимущество использования представления по сравнению с основной таблицей в том, что представление будет модифицировано автоматически всякий раз, когда таблица, лежащая в его основе, изменяется. Содержание представления не фиксировано и создается каждый раз при создании представления. Представления значительно расширяют управление данными. Это превосходный способ дать публичный доступ к некоторой, но не всей информации в таблице. Представление может теперь изменяться командами модификации DML, но модификация не будет воздействовать на само представление. Команды будут на самом деле перенаправлены к базовой таблице.
Каждая СУБД должна обеспечивать функцию системного каталога. Системный каталог реляционной СУБД – это набор таблиц, в которых содержится информация, необходимая для правильного функционирования СУБД: о поддерживаемых базах данных и их базовых таблицах, пользователях и их правах доступа к информации, правилах модификации данных и т.д. Следует различать термины “каталог” и “информационная схема”. Каталог описывает отдельную базу данных, тогда как информационная схема состоит из описания той части базы данных, которая относится к некоторому отдельному пользователю. Другими словами, может быть любое число каталогов, каждый из которых делится на произвольное число схем. В разных СУБД, поддерживающих SQL, существует от десятка до нескольких десятков системных таблиц.
Так, в каждой строке системной таблицы SYSTABLES хранится описание одной из таблиц пользовательских или системной баз данных. Для каждой из них указывается имя таблицы, имя пользователя, который создал эту таблицу, число столбцов в ней и ряд других элементов информации. В таблице SYSCOLUMNS содержится строка для каждого столбца каждой таблицы, в которой указано имя столбца, имя таблицы, частью которой является данный столбец, тип данных для этого столбца и много другой информации о столбце.
С помощью предложения SELECT пользователь может получить информацию из любой системной таблицы. Например, он может дать запрос на получение имен таблиц, числа их столбцов и строк, владельца и краткого описания (если таковое вводилось в базу данных). Пользователь, не знакомый со структурой базы данных, может с помощью подобного рода запросов получить информацию о такой структуре. Следует отметить, что СУБД не позволяет обновлять каталог.