Базы данных. Вводный курс

         

с рассказа об истории систем


Мы начали эту лекцию с рассказа об истории систем управления внешней памятью. Развитие аппаратных и программных средств управления внешней памятью диктовалось потребностями информационных систем, для построения которых требовалась возможность надежного долговременного хранения больших объемов данных, а также обеспечение достаточно быстрого доступа к этим данным.
Системы управления файлами во внешней памяти обеспечивают минимальные потребности информационных систем, предоставляя средства распределения и структуризации дисковой памяти, именования файлов, авторизации доступа и поддержки многопользовательского режима. По мере развития технологии информационных систем их потребности возрастают, выходя за пределы возможностей, обеспечиваемых файловыми системами.
Следует особо обратить внимание на то, что и сегодня основной класс устройств внешней памяти базируется на магнитных дисках с подвижными головками. Поэтому временные соотношения, приведенные в связи с , по-прежнему весьма актуальны. На этих соотношениях, главным образом, базируются оптимизационные методы, применяемые в современных системах управления данными во внешней памяти.
Далее, на примере тривиальной информационной системы были показаны ситуации, в которых возможности файловых систем явно недостаточны. Более того, попытки расширения возможностей файловой системы путем включения в приложение дополнительных программных компонентов во многих случаях не приводят к успеху. В пределе такие попытки могут привести к появлению самостоятельного программного продукта, обладающего некоторыми чертами СУБД. Однако настоящие СУБД являются настолько большими и сложными программными системами, что вероятность успешного создания «самодельной» СУБД ничтожно мала.
Еще один вывод заключается в том, что при выборе технологии построения информационной системы нужно тщательно оценивать и прогнозировать ее потенциальные потребности в средствах управления данными. Конечно, любую информационную систему можно основывать на использовании промышленной, большой и мощной СУБД. Но вполне может оказаться так, что в действительности приложение будет использовать доли процентов общих возможностей СУБД. Накладные расходы (затраты на дополнительную аппаратуру, лицензирование дорогостоящего программного продукта, увеличение общего времени выполнения операций) могут оказаться неоправданными.


В этой лекции было введено важнейшее в технологии баз данных понятие модели данных. Кратко рассмотрены особенности трех ранних моделей данных: модели инвертированных таблиц, иерархической модели и сетевой модели данных. В отдельном разделе представлена исходная реляционная модель данных, определенная Эдгаром Коддом. Описаны основные черты трех современных моделей данных, системы типов данных которых позволяют сохранять в базе данных и обрабатывать данные произвольно сложной структуры: объектно-ориентированная модель данных, модель данных SQL и истинно реляционная модель данных.


Скорее всего, потенциальные читатели этого курса работают или будут работать с какой-либо SQL-ориентированной СУБД. Любая компания, производящая подобные СУБД, называет их реляционными системами. Очень важно отчетливо понимать, какие свойства таких систем действительно являются реляционными, а что в них не вполне соответствует исходным, ясным и строгим идеям реляционного подхода и даже противоречит им. Это поможет более правильно организовывать базы данных и строить приложения в среде SQL-ориентированной СУБД.
В нескольких лекциях данного курса достаточно подробно обсуждаются возможности текущих стандартов языка SQL: SQL:1999 и SQL:2003. Но сначала читателям предлагается материал, который представляет реляционный подход в чистом виде. В данной лекции вводится понятийная основа реляционного подхода; определяются основные термины; исследуются фундаментальные следствия базовых определений. Рассматриваемая реляционная модель данных предназначена, прежде всего, для оценки соответствия различных реализаций СУБД общему реляционному подходу.
  Уже второй раз в этой лекции утверждается, что нормализованное n-арное отношение является единственной родовой структурой данных, используемой в реляционных БД. Пришло время пояснить, что мы имеем в виду под термином родовая структура. В языках программирования с развитыми системами типов обычно имеются конструкции, называемые родовыми типами, параметризуемыми типами, конструкторами типов, генераторами типов и т.д., позволяющие породить конкретный тип данных на основе его абстрактной (обычно, предопределенной) спецификации. Особенность таких типов состоит в том, что и основные операции конкретного типа определяются на уровне этой абстрактной спецификации. Одним из наиболее известных примеров является тип множества, например, в языке Pascal. В случае реляционной модели данных мы не говорим явно, что отношение является родовым типом, но, по существу, это именно так. Операции реляционной алгебры определяются на уровне абстрактного отношения и применимы к любым значениям-отношениям с конкретными заголовками.


В завершение лекции хочу отметить несколько моментов. Прежде всего, заметим, что алгебра Кодда была представлена не в ее оригинальной форме, а с некоторыми существенными коррективами, внесенными Кристофером Дейтом. С моей точки зрения, одной из наиболее значительных корректив было добавление тривиальной на первый взгляд операции переименования атрибутов. Когда Эдгар Кодд в конце 1960-х гг. впервые опубликовал свою алгебру, основное внимание в ней уделялось тому, как конструируются результирующие множества кортежей, т. е. что представляют собой тела результатов операций. Гораздо меньше внимания уделялось заголовкам отношений-результатов. Фактически Кодд пытался применить для именования атрибутов результатов операций точечную нотацию, используя для уточнения имен атрибутов имена исходных отношений-операндов. При наличии произвольно сложных и длинных алгебраических выражений этот путь, в лучшем случае, вел к порождению длинных и трудных для восприятия имен. Очевидно, что введение операции переименования атрибутов позволяет легко справиться с этой проблемой.
Далее, алгебра Кодда исключительно избыточна. Операции пересечения, декартова произведения и естественного соединения, на самом деле, являются частными случаями одной более общей операции, о которой пойдет речь в следующей лекции. Введение операции декартова произведения в качестве базовой операции алгебры может ввести в заблуждение неопытных студентов и читателей, не осознающих практическую бессмысленность этой операции.
Почему же мы начали обсуждение базовых манипуляционных механизмов реляционной модели данных с этой небезупречной и несколько устаревшей алгебры? Конечно, прежде всего, из уважения к заслугам доктора Эдгара Кодда, вклад которого в современную технологию баз данных невозможно переоценить. Более практические соображения, повлиявшие на наше решение начать обсуждение с алгебры Кодда, заключались в том, что семантика языка SQL во многом базируется именно на этой алгебре, и нам будет проще изучать SQL, предварительно познакомившись с ней.
  Здесь A.c и B.c представляют собой так называемые квалифицированные (уточненные) имена атрибутов (часто такой способ именования называют точечной нотацией). Мы будем использовать подобную нотацию в тех случаях, когда требуется явно показать, схеме какого отношения принадлежит данный атрибут.




Базисом Алгебры A являются операции реляционного отрицания (дополнения), реляционной конъюнкции (или дизъюнкции) и проекции (удаления атрибута). Реляционные аналоги логических операций определяются в терминах отношений на основе обычных теоретико-множественных операций и позволяют выражать напрямую операции пересечения, декартова произведения, естественного соединения и объединения отношений. Путем комбинирования базовых операций выражаются операции переименования атрибутов, соединения общего вида, взятия разности отношений. Алгебра A позволяет лучше осознать логические основы реляционной модели, хотя, безусловно, является в меньшей степени ориентированной на практическое применение, чем алгебра Кодда.
Как нам кажется, в методическом отношении Алгебра A важна, прежде всего, тем, что в ней реляционная операция естественного соединения является одной из базовых операций, в отличие от алгебры Кодда, где эта операция имела второстепенное значение. Это важно по той причине, что, как мы увидим в лекции 8, операция естественного соединения играет первостепенную роль в классическом подходе к проектированию реляционных баз данных на основе нормализации.
  Здесь необходимо пояснить, что отношение ЗАРП_20000 в действительности представляет собой литеральную константу соответствующего типа отношений. Мы не вводим здесь строгого понятия типа отношения; для понимания данного подраздела нужно всего лишь осознать, что по своей природе отношение ЗАРП_20000 и числовой литерал 20000.00 не различаются.
  Отношение ЗАРП_БОЛЬШЕ_20000 – это тоже литеральная константа того же типа отношения, что и ЗАРП_20000, однако мощность тела этого литерального отношения в общем случае (если бы мы не ввели ограничения на множество значений домена СЛУ_ЗАРП) могла бы быть очень большой.
  Особенность этого случая состоит в том, что число кортежей в теле литеральной константы ЗАРП_НЕ_22000 всего лишь на единицу меньше мощности множества значений домена СЛУ_ЗАРП. Конечно, эта мощность конечна, поскольку мы имеем дело с компьютерными типами данных, но в общем случае может быть очень большой. Поэтому принципиальная возможность выражения операции ограничения через операцию реляционной конъюнкции не означает, что было бы разумно реализовывать ее таким образом на практике.
  Конечно, тот же результат даст и выражение СЛУЖАЩИЕ_1 <AND> ((((СЛУЖАЩИЕ_1 <REMOVE> СЛУ_РУК) <REMOVE> СЛУ_ИМЯ) <REMOVE> СЛУ_ЗАРП) <RENAME> (СЛУ_НОМЕР, РУК_НОМ)).
  Конечно, в общем случае мощность тела такого константного отношения будет равна мощности соответствующего домена.
  Легко убедиться, что в общем случае, если мощность общего домена атрибутов A и B равняется n, то мощность тела константного отношения A_БОЛЬШЕ_B будет составлять (n+1)n/2.
  Это «константное» отношение, тело которого не зависит от текущего содержания тела отношения СЛУЖАЩИЕ.
  И конечно, в Алгебре A, как и в алгебре Кодда, должна присутствовать операция присваивания переменной отношения.


Этой лекцией мы завершаем обзор реляционной модели данных. В последних трех лекциях рассматривалась манипуляционная составляющая реляционной модели данных. Были представлены два варианта реляционной алгебры. Конечно, с формальной точки зрения можно было бы обойтись одним из вариантов, поскольку их выразительные средства эквивалентны. Но алгебра Кодда в большей степени базируется на теории множеств. Базовыми операциями являются переименование атрибутов, объединение, пересечение, взятие разности, декартово произведение, проекция и ограничение. Операция соединения общего вида, хотя и включается в алгебру, является вторичной и явно представляется через другие операции. Фундаментальная же в реляционном подходе операция естественного соединения выражается через соединение общего вида и в алгебру не включается. В терминах алгебры Кодда проще всего определяются алгебраические черты языка SQL, в частности общая семантика оператора SELECT (см. лекцию 17).
Базисом Алгебры A являются операции реляционного отрицания (дополнения), реляционной конъюнкции (или дизъюнкции) и проекции (удаления атрибута). Реляционные аналоги логических операций определяются в терминах отношений на основе обычных теоретико-множественных операций и позволяют выражать напрямую операции пересечения, декартова произведения, естественного соединения, объединения отношений. Путем комбинирования базовых операций выражаются операции переименования атрибутов, соединения общего вида, взятия разности отношений. Алгебра A позволяет лучше осознать логические основы реляционной модели, хотя, безусловно, является в меньшей степени ориентированной на практическое применение, чем алгебра Кодда.
Реляционному исчислению мы отвели меньше места, поскольку не ставили перед собой задачу определить какой-либо полноценный логический язык запросов. Цель состояла в том, чтобы показать возможность декларативной логической формулировки запросов. В этом случае выполнение запроса происходит путем интерпретации логической формулы, а не вычисления алгебраического выражения. Были рассмотрены два варианта реляционного исчисления, первый из которых – реляционное исчисление кортежей – был определен сравнительно полно, а для второго – реляционного исчисления доменов – были только отмечены и проиллюстрированы основные отличительные черты.


В этой лекции было введено понятие функциональной зависимости и исследовались важные свойства функциональных зависимостей. Одна из целей состояла в том, чтобы на основе некоторого множества функциональных зависимостей суметь построить минимальное эквивалентное множество функциональных зависимостей. Мы начали обсуждение с понятия замыканий множества функциональных зависимостей и аксиом Амстронга, теоретически позволяющих построить такое замыкание. Замыкание множества функциональных зависимостей содержит все функциональные зависимости, выводимые из функциональных зависимостей заданного множества. Рассмотренный далее алгоритм построения замыкания множества атрибутов над заданным множеством функциональных зависимостей упрощает задачу, позволяя определить принадлежность заданной функциональной зависимости к замыканию заданного множества функциональных зависимостей без потребности в реальном построении замыкания.
Далее мы занялись покрытиями множеств функциональных зависимостей и минимальными множествами функциональных зависимостей. Наиболее важным результатом этой части лекции является доказательство существования и наметки алгоритма построения минимального покрытия заданного множества функциональных зависимостей – минимального множества функциональных зависимостей, эквивалентного исходному множеству.
Наконец, последний раздел лекции был посвящен критерию декомпозиции отношения без потерь, т. е. такому способу проецирования заданного отношения на два отношения, при котором результат естественного соединения проекций в точности совпадает с исходным отношением. Достаточное (и очень естественное) условие декомпозиции без потерь обеспечивает теорема Хита.
  FD с минимальным детерминантом называется минимальной слева.


В этой лекции мы обсудили три начальные нормальные формы отношений – вторую и третью нормальные формы и нормальную форму Бойса-Кодда, – которые производятся путем декомпозиции без потерь исходного отношения на две проекции, где отсутствуют аномалии изменений, существовавшие в исходном отношении по причине наличия функциональных зависимостей с нежелательными свойствами.
Нормализация схемы базы данных способствует более эффективному выполнению системой управления базами данных операций обновления базы данных, поскольку сокращается число проверок и вспомогательных действий, поддерживающих целостность базы данных. При проектировании реляционной базы данных почти всегда добиваются второй нормальной формы всех входящих в базу данных отношений. В часто обновляемых базах данных обычно стараются обеспечить третью нормальную форму отношений. На нормальную форму Бойса-Кодда внимание обращают гораздо реже, поскольку на практике ситуации, в которых у отношения имеется несколько составных перекрывающихся возможных ключей, встречаются нечасто.
  Единственным возможным ключом отношения СЛУЖ_НОМ_ЗАДАН является {СЛУ_НОМ, СЛУ_ЗАДАН}, и в этом отношении отсутствуют нетривиальные FD.


Процесс проектирования реляционной базы на основе метода нормализации преследует две основных цели:
  • избежать избыточности хранения данных;
  • устранить аномалии обновления отношений.

Рассмотрим, насколько эти цели актуальны в современных условиях, когда объемы доступных носителей внешней памяти непрерывно возрастают, стоимость их падает, а современные серверы реляционных баз данных способны автоматически поддерживать целостность баз данных. Здесь следует отметить два важных обстоятельства.
Во-первых, теория реляционных баз данных и методы их проектирования активно развивались уже более 25 лет тому назад. Ситуация в области технологии аппаратуры и программного обеспечения тогда была совсем иной, чем сегодня, и хорошо нормализованные реляционные базы данных в значительной степени способствовали росту эффективности приложений.
Во-вторых, в то время реляционные базы преимущественно использовались в информационных системах оперативной обработки транзакций (On-Line Transaction Processing – OLTP). Характерные примеры таких систем мы отмечали в лекции 1 – банковские системы, системы резервирования билетов и мест в гостиницах. Системам категории OLTP свойственны частые обновления базы данных, поэтому аномалии обновлений, даже если их корректировка производится СУБД автоматически, могут заметно снижать эффективность приложения.
Сегодня на переднем крае приложений баз данных находятся системы категории оперативной аналитической обработки (On-Line Analytical Processing – OLAP). В подобных системах, в частности, системах поддержки принятия решений, базы данных в основном используются для выборки данных, поэтому аномалиями обновлений можно пренебречь, а объем этих баз настолько огромен, что можно пренебречь и избыточностью хранения.
Значит ли это, что подход к проектированию реляционных баз данных методом нормализации утратил свою роль? Нет!
Мир приложений баз данных в настоящее время огромен. Сегодня любое мало-мальски приличное предприятие использует хотя бы одно приложение баз данных – бухгалтерские, складские, кадровые системы.


Основной целью данной лекции было ознакомление с семантическими моделями данных на примере упрощенного варианта ER-модели. Представленный вариант ER-модели, с одной стороны, является достаточно развитым, чтобы можно было почувствовать общую специфику семантических моделей данных, а с другой стороны, не перегружен деталями и излишними понятиями, затрудняющими общее понимание подхода.
С практической точки зрения наибольшую пользу могут принести рассмотренные приемы перехода от ER-диаграмм к схеме реляционной базы данных. Особенно могут пригодиться рекомендации по представлению в реляционной схеме связей «многие ко многим», подтипов и супертипов сущности и взаимно исключающих связей.
  Как отмечалось в начале лекции 7, вопросы определения индексов и других вспомогательных структур данных относятся к этапу физического, а не логического проектирования данных. Конечно, на практике эти этапы часто перекрываются во времени. Заметим, кстати, что в SQL-ориентированных СУБД индексы для всех возможных и внешних ключей, как правило, создаются системой автоматически.
  Этот аспект тоже относится к этапу физического проектирования, поскольку связан с особенностями реализации конкретной СУБД.
  Хотя в большинстве SQL-ориентированных СУБД хранение неопределенных значений вызывает минимальные накладные расходы; это снова аспект физического проектирования.


Нельзя сказать, что проектирование баз данных на основе семантических моделей в любом случае ускоряет и/или упрощает процесс проектирования. Все зависит от сложности предметной области, квалификации проектировщика и качества вспомогательных программных средств. Но так или иначе этап диаграммного моделирования обеспечивает следующие преимущества:
  • на раннем этапе проектирования до привязки к конкретной РСУБД проектировщик может обнаружить и исправить логические недочеты проекта, руководствуясь наглядным графическим представлением концептуальной схемы;
  • окончательный вид концептуальной схемы, полученной непосредственно перед переходом к формированию реляционной схемы, а может быть, и промежуточной версии концептуальной схемы, должен стать частью документации целевой реляционной БД; наличие этой документации очень полезно для сопровождения и, в особенности, для изменения схемы БД в связи с изменившимися требованиями;
  • при использовании CASE-средств концептуальное моделирование БД может стать частью всего процесса проектирования целевой информационной системы, что должно способствовать правильной структуризации процесса, эффективности и повышению качества проекта в целом.

Мы также хотели показать, что в контексте проектирования реляционных БД структурные методы проектирования, основанные на использовании ER-диаграмм, и объектно-ориентированные методы, основанные на использовании языка UML, различаются, главным образом, лишь терминологией. ER-модель концептуально проще UML, в ней меньше понятий, терминов, вариантов применения. И это понятно, поскольку разные варианты ER-моделей разрабатывались именно для поддержки проектирования реляционных БД, и ER-модели почти не содержат возможностей, выходящих за пределы реальных потребностей проектировщика реляционной БД.
Язык UML принадлежит объектному миру. Этот мир гораздо сложнее (если угодно, непонятнее, запутаннее) реляционного мира. Поскольку UML может использоваться для унифицированного объектно-ориентированного моделирования всего чего угодно, в этом языке содержится масса различных понятий, терминов и вариантов использования, избыточных с точки зрения проектирования реляционных БД.


В этой лекции была кратко описана экспериментальная реляционная СУБД System R, оказавшая гигантское влияние на становление современной технологии баз данных. Были рассмотрены основные цели проекта System R, общая архитектура системы, основные структуры данных внешней памяти и интерфейс подсистемы управления внешней памятью.
Далее были обсуждены основные подходы к организации внешней памяти, применяемые в современных СУБД. Конечно, в любой конкретной SQL-ориентированной СУБД используется ряд собственных приемов организации хранения таблиц и индексов, но практически во всех случаях общие принципы похожи на те, которые описаны в разд. 12.2.


В этой лекции описаны основные принципы управления транзакциями в системах управления базами данных, различные методы, алгоритмы и протоколы, способствующие достижению целей управления транзакциями. Следует заметить, что существует достаточно развитая теория управления транзакциями с собственными средствами формализации постановки задач и доказательства корректности алгоритмов. Для обеспечения более простого понимания сути материала в него не включены все эти формализмы.
В лекции описаны два основных подхода к сериализации транзакций – на основе синхронизационных блокировок и временных меток. У каждого из этих подходов имеются свои достоинства и недостатки, но на практике существенно больше распространен метод синхронизационных блокировок. В заключение лекции были рассмотрены расширения этих подходов с применением версий объектов базы данных. Соответствующие алгоритмы и протоколы позволяют уменьшить число потенциальных конфликтов транзакций, но для их поддержки требуются дополнительные расходы внешней памяти и усложнение общей архитектуры СУБД.


В этой лекции рассматривались основные принципы и алгоритмы подсистем СУБД, предназначенных для управления буферами основной памяти, журнализации и восстановления базы данных после различных сбоев. Изложение велось без технических деталей, таких как возможные структуры данных журналов.
Заметим, что во многих современных производственных СУБД журнализация и восстановление основаны на применении семейства алгоритмов ARIES, разработанных в 1980-е гг. известным исследователем из компании IBM К. Моханом (C. Mohan). В этой лекции не приводится описание алгоритмов семейства ARIES, поскольку, по мнению автора, это перегрузило бы ее подробностями, не способствующими пониманию основных идей. Тем не менее, читателям, которых заинтересовала эта тема, полезно познакомится с этими алгоритмами, для чего можно воспользоваться, например, или оригинальными статьями Мохана и его коллег.


В этой лекции мы начали рассматривать средства языка SQL, позволяющие определять и динамически изменять схему базы данных. Наиболее важным для общего понимания языка является раздел – система типов языка SQL (и любой SQL-ориентированной базы данных). В последних стандартах языка SQL поддерживаются:
  • развитый набор предопределенных типов, включая ряд параметризованных типов;
  • генераторы типов массивов и мультимножеств, элементами которых могут быть значения предопределенных типов, типов коллекций, анонимных строчных типов строк и типов, определенных пользователями;
  • генератор анонимных строчных типов, в которых типом элемента строки может быть любой предопределенный тип, тип коллекции, анонимный строчный тип и тип, определенный пользователями;
  • определяемый пользователем структурный тип, в котором типом элемента структуры может быть любой предопределенный тип, тип коллекции, анонимный строчный тип и тип, определенный пользователями; для определяемых пользователем структурных и индивидуальных типов можно определять пользовательские операции.

Нельзя с уверенностью сказать, что система типов языка SQL настолько полна, что может удовлетворить любые потребности, но можно отметить, что в этой системе типов отсутствует единый логический подход и имеется избыточность. Возможно, это станет понятнее после обсуждения в конце курса средств объектно-реляционных расширений языка SQL.
Как должно быть ясно из этой лекции, механизм доменов в SQL играет вспомогательную роль. Это не совсем те (может быть, и совсем не те) домены, поддержка которых предполагается реляционной моделью. Фактически определение домена обеспечивает спецификацию ограничений и значений по умолчанию, выносимых за пределы определения столбца. В комитете по стандартизации SQL обсуждается идея полного отказа от поддержки механизма доменов и замены его на соответствующим образом адаптированный механизм индивидуальных типов (см. последнюю лекцию курса).
  Начиная с этого места мы будем приводить более или менее точный синтаксис конструкций языка SQL (не злоупотребляя излишествами).


В этой и предыдущей лекциях мы обсудили наиболее важные аспекты языка SQL, связанные с определением схемы базы данных, – типы данных SQL, средства определения доменов, базовых таблиц и ограничений целостности. Кроме того, были рассмотрены средства SQL, позволяющие динамически изменять и удалять определения этих объектов. Язык SQL устроен таким образом, что практически невозможно изложить какую-либо его часть независимо от других частей. И хотя эти две лекции по смыслу должны быть первыми среди лекций, посвященных SQL (было бы странно обсуждать операторы выборки строк из таблиц, вставки, изменения и удаления строк до обсуждения средств создания таблиц и ограничений целостности), нам пришлось забежать вперед и воспользоваться материалом следующих лекций для объяснения средств определения ограничений целостности. Надеюсь, что это не создало слишком больших неудобств для читателей, и отсутствие формальных определений удалось компенсировать наличием простых примеров.
  Не считая те ограничения целостности, которые (a) определены в составе определения данной базовой таблицы и (b) не ссылаются на какие-либо другие базовые таблицы.
  Это означает, что cand_pro_no является допустимым значением внешнего ключа.
  Не следует воспринимать этот и следующие абзацы как описание того, как на самом деле выполняются подобные запросы в SQL-серверах. Это наиболее прямолинейный и малоэффективный способ выполнения запроса (хотя, в принципе, его можно применять и на практике). Мы выбрали этот способ описания, поскольку он максимально соответствует подходу к описанию семантики языка SQL, применяемому в стандарте языка. Кстати, основным отличием более практичных способов выполнения запросов с соединением является стремление к тому, чтобы избежать явного декартова произведения.
  Конечно, в грамотных реализациях SQL при выполнении операции проверяются не все немедленно проверяемые ограничения целостности, а только те, которые в принципе могут быть нарушены данной операцией.
  Мы снова вынуждены забегать вперед. Средства SQL для управления транзакциями более подробно обсуждаются в следующих лекциях.
  Конечно, в грамотных реализациях SQL при завершении транзакции проверяются не все отложенно проверяемые ограничения целостности, а только те, которые в принципе могут быть нарушены данной транзакцией.
  Для некоторых ограничений целостности режим отложенной проверки не имеет смысла. К таким ограничениям относятся, например, ограничения домена, ограничения NOT NULL и ограничения возможного ключа (хотя при их определении допускается указание DEFFERABLE). Если же возможный ключ используется в некотором определении внешнего ключа, то в стандарте SQL требуется, чтобы ограничение этого возможного ключа было NOT DEFFERABLE.


В ходе чтения лекций, посвященных оператору SELECT языка SQL, мне неоднократно случалось слышать жалобы студентов на сухость начального материала и отсутствие иллюстрирующих примеров. Однако я не встречал ни одного учебного пособия по языку SQL, основанного на примерах (среди многочисленных изданий типа «SQL за 24 часа», «SQL для чайников» и даже «SQL для идиотов»), который действительно давал бы представление об SQL как языке, а не служил инструкцией армейского типа.
Сложность организации оператора выборки не позволяет сразу начинать с полноценных примеров, а для демонстрации примеров промежуточных конструкций требуется создание неприемлемо громоздкого контекста. Поэтому могу лишь принести извинения за некоторую сухость этой лекции.
С другой стороны, теперь мы уже вплотную подошли к тому этапу, на котором возможно использование иллюстраций, и в следующих лекциях их будет достаточно, хотя проиллюстрировать все интересные разновидности оператора SELECT все равно не представляется возможным, поскольку число вариантов близко к астрономическому.
  Мы использовали кавычки, поскольку таблицы, к которым применяются операции, в общем случае могут содержать строки-дубликаты, т.е. являться мультимножествами.
  Другими словами, при отсутствии спецификации CORRESPONDING требуется, чтобы заголовки таблиц-операндов совпадали за исключением, возможно, порядка следования столбцов.
  С учетом возможности неявного приведения типов.
  В следующей лекции мы более подробно обсудим подзапросы. Пока заметим, что row_subquery – это запрос, результирующая таблица которого состоит из одной строки.
  По крайней мере, так это следует понимать в соответствии с семантикой представлений в языке SQL. При реальной обработке запросов над представлениями такая явная «материализация» представления выполняется кране редко. Вместо этого используется ехника подстановки тела представления в тело запроса с гарантией того, что результат модифицированного запроса будет в точности таким же, что и резальтат исходного запроса над материализованным представлением. Но это уже относится к тематике оптимизации SQL-запросов, выходящей за пределы этого курса.
  Конструкция ALTER VIEW в языке SQL не поддерживается.


В этой лекции мы обсудили наиболее важные возможности языка SQL, связанные с выборкой данных. Даже простые примеры, приводившиеся в лекции, показывают исключительную избыточность языка SQL. Еще в то время, когда действующим стандартом языка был SQL/92, была опубликована любопытная статья, в которой приводилось 25 формулировок одного и того же несложного запроса. При использовании всех возможностей SQL:1999 этих формулировок было бы гораздо больше.
Можно спорить, хорошо или плохо иметь возможность формулировать один и тот же запрос десятками разных способов. На мой взгляд, это не очень хорошо, поскольку увеличивает вероятность появления ошибок в запросах (особенно в сложных запросах). С другой стороны, таково объективное состояние дел, и мы стремились обеспечить в этой лекции материал, достаточный для того, чтобы прочувствовать различные возможности формулировки запросов. Как показывают следующие две лекции, возможности, предоставляемые оператором SELECT, в действительности гораздо шире.


Думаю, что теперь читатели в состоянии в полной мере оценить мощность, разнообразие и избыточность средств языка SQL, предназначенных для формулировки запросов на выборку данных. Конечно, язык SQL (по крайней мере, ту часть SQL, которая обсуждается в этом курсе) нельзя считать языком программирования, но написание сложных запросов сродни программированию. И нельзя сказать, что SQL каким-либо образом дисциплинирует это «программирование». По всей видимости, в общем случае никто не может сказать, какая из формулировок одного и того же запроса является более правильной, это дело вкуса.
Зачастую десять студентов, одновременно формулирующих на SQL один и тот же запрос к одной и той же базе данных, выдают десять разных правильных решений. Один человек предпочитает формулировки запросов в классическом стиле, другой использует выражения запросов в разделе FROM, третий пытается сосредоточить все условия выборки в разделе HAVING. Люди с алгебраическими наклонностями предпочитают использовать выражения соединений. Приходилось встречать и формулировки со сложными вложенными подзапросами в списке выборки раздела SELECT.
Конечно, теоретически компилятор SQL должен быть в состоянии распознать все эквивалентные формулировки одного и того же запроса и выработать для всех них один и тот же наиболее эффективный план выполнения. Но чем больше разнообразие возможных формулировок, тем сложнее эта задача. Отсюда практический совет: не злоупотребляйте сложностью формулировки запроса. Полагайтесь на интуицию (и имеющиеся представления об особенностях используемой системы) и формулируйте запрос как можно проще.
И еще один практический совет. При формулировке запроса никогда не пользуйтесь имеющимися у вас данными о текущем состоянии базы данных, полагайтесь только на метаданные схемы базы данных. В противном случае вы сможете сформулировать запрос, выдающий в данный момент правильный результат, но этот запрос не будет эквивалентен никакому запросу, выдающему правильный ответ при любом состоянии базы данных.
  Конечно, предлагаемый русский вариант термина lateral слишком громоздок. По всей видимости, если этот механизм войдет в практику пользователей SQL, можно будет использовать качестве термина что-то вроде латеральной порождаемой таблицы. Но здесь для нас главным является не предложение хорошей новой технологии, а обеспечение понимания материала.
  Тем самым ссылка на LD-таблицу не может быть первой в списке раздела FROM. Кстати может возникнуть естественный вопрос: почему разрешаются ссылки только на таблицы, находящиеся в списке раздела FROM только слева LD-таблицы? Стандарт отвечает на этот вопрос весьма просто и бесхитростно. Если разрешить использовать ссылки, находящиеся и слева, и справа от спецификации ссылки на LD-таблицу, то это может привести к зацикливанию при выполнении раздела FROM. Поэтому нужно было вбирать одно из направлений, и было выбрано направление слева направо.


Если вернуться к синтаксическим определениям подраздела лекции 17, то можно убедиться, что в последних четырех лекциях мы рассмотрели все варианты организации оператора SELECT языка SQL (за исключением конструкций collection_derived_table и ONLY (table_or_query_name), относящихся к объектным расширениям языка SQL).
Для общего понимания языка на модельном уровне более важными являются предыдущие три лекции. Данная лекция включена в курс, скорее, с целью общего ознакомления читателей с новыми возможностями оператора выборки, чем с целью их подробного описания. С большой вероятностью средства формулировки аналитических и рекурсивных запросов языка SQL будут пересматриваться при подготовке следующих вариантов стандарта языка.


В этой лекции мы обсудили важные аспекты языка SQL, относящиеся к механизмам обновления данных. В разделе были рассмотрены операторы прямого SQL, предназначенные для вставки, модификации и удаления данных из существующих таблиц. Операторы UPDATE и DELETE этой категории иногда называют поисковыми, поскольку в них включаются условия на строки таблицы, которые должны быть модифицированы или удалены. В языке SQL определены так-же позиционные операторы модификации и удаления строк, а также динамические позиционные варианты данных операторов, но для их обсуждения требуется общее рассмотрение встраиваемого и динамического SQL, что выходит за рамки данного курса. На мой взгляд, поисковые версии операторов модификации и удаления хорошо характеризуют соответствующие возможности языка SQL. Кроме того, оператор INSERT, представленный в этой лекции, специфицирован в языке SQL только в таком варианте.
Раздел посвящен обсуждению возможностей языка SQL, связанных с применимостью операций обновления базы данных через виртуальные таблицы, в том числе через представления. Мы рассмотрели ограничения языка SQL/92, накладываемые на виртуальные таблицы, к которым применимы операции обновления. Отмечалось, что эти ограничения являются достаточными, но не необходимыми для применения операций обновления. Был описан подход стандарта SQL:1999, где предлагаются рекомендации, но не требования, которых следует придерживаться реализациям SQL, чтобы соответствовать стандарту.
Наконец, в разделе рассматривался механизм триггеров. В первом подразделе упоминались основные понятия триггеров, которые были введены при выполнении проекта System R. Далее приводились основные синтаксические конструкции, предназначенные для определения триггеров, а также была описана их базовая семантика. В следующем подразделе обсуждались принципы выполнения триггеров, заложенные в стандарт SQL:1999. Наконец, в заключение раздела были рассмотрены имеющиеся взаимосвязи между ссылочными действиями и триггерами.
Один из основных выводов лекции состоит в том, что в стандарте SQL:1999 спецификации многих аспектов, относящихся к обновлению баз данных, обоснованы недостаточно убедительно. В ряде случаев разработчики стандарта ожидают улучшения спецификаций в следующих версиях стандарта.
Часть следующей лекции, относящаяся к средствам языка SQL, которые предназначены для управления транзакциями, также имеет непосредственное отношение к операторам обновления баз данных.
  Помимо прочего, этот факт означает, что определение в базе данных нового триггера может привести к неработоспособности существующих приложений, разработчики которых, вообще говоря, могут даже и не знать о появлении нового триггера.
  Здесь мы опять честно пересказали стандарт SQL:1999. И снова предложенное решение выглядит простым, но не убедительным.


В этой лекции были рассмотрены три темы, которые являются относительно независимыми, но относятся к средствам языка SQL, предназначенным для регулирования доступа пользователей к базам данных. На первый взгляд материал этой лекции проще материала предыдущих лекций, посвященных языку SQL. Наверное, это действительно так, если говорить про чисто языковую сложность соответствующих операторов SQL. Но в действительности (которую мы старательно обходили в основных разделах лекции) дело обстоит гораздо сложнее.
Как легко видеть, при распространении привилегий и ролей могут возникать произвольно сложные ориентированные графы связей между объектами базы данных, владельцами привилегий, привилегиями и ролями. Если изображать сплошными стрелками передачу привилегий, прерывистыми – передачу ролей, пунктирными – владение привилегиями, а точечными – владение ролями, то даже по отношению к одной привилегии pr для одного объекта o может появиться следующий граф связей (userID означает authID, отличный от имени роли), показанному на .


Рис. 22.9.  Простейший граф идентификаторов пользователя, имен ролей, объектов и привилегий
Как мог появиться такой граф? Пользователь с authID, равным userID1 (это мы предположили для упрощения, а вообще-то это могло быть и именем роли), создает объект o, становится его владельцем и тем самым обладателем привилегии pr по отношению к этому объекту. Пользователь userID1 предоставляет полномочие pr роли role1 (с правом передачи). Затем пользователю userID1 предоставляется роль role1 (с правом передачи), и он получает право исполнять эту роль. От имени роли role1 полномочие pr передается пользователю userID2 (с правом передачи), и этот же пользователь получает право исполнять роль role1 (с правом передачи). Пользователь userID2 передает роли role2 роль role1 и полномочие pr (с правом передачи). Наконец, от имени роли role2 полномочие pr и сама роль role2 передаются пользователю userID1.
Попробуйте теперь проследить, как будет выполняться операция
REVOKE pr ON o FROM role1 CASCADED


Если обратиться к истории, выяснится, что попытки расширения функциональности СУБД, изначально основанных на реляционном подходе, предпринимались уже на ранних стадиях разработки таких систем. Классическими примерами являются проекты System R компании IBM, где разработчики пытались обеспечить возможности работы со сложными объектами путем расширения SQL, и Ingres (университет Беркли), где Майкл Стоунбрейкер предлагал механизм определения пользовательских типов данных на основе представлений и хранимых процедур. Однако новый толчок к расширению SQL-ориентированных СУБД объектными свойствами был получен со стороны объектного мира после публикации Первого манифеста.
В ответном Втором манифесте представители индустрии развитых СУБД утверждали, что имеются реальные возможности добиться желаемой функциональности без коренной ломки традиционной технологии. Идеи Второго манифеста были воплощены в жизнь в нескольких ведущих SQL-продуктах, и использование объектных расширений позволило самим поставщикам обеспечить ряд законченных функциональных расширений своих систем. Однако ожидания большого спроса со стороны пользователей на сами инструменты объектных расширений не оправдались. Некоторые известные специалисты из области баз данных считают, что для этого еще не пришло время.
Развитие объектно-реляционного подхода нашло отражение в языке SQL. Гигантский стандарт SQL:1999 позволяет хотя бы сопоставлять отдельные реализации, хотя ни одна компания полностью его не поддерживает. Как можно заметить, разработчики стандарта SQL пошли на существенно большее сближение с объектно-ориентированным подходом к организации систем баз данных, чем это предполагалось во Втором манифесте. В особенности это проявляется в механизмах типизированных таблиц, ссылочных типов и ссылочных значений: типизированные таблицы похожи на экстенты классов, а ссылочные значения – на объектные идентификаторы. Однако во многом это сходство является внешним – за путевыми выражениями в стиле ODMG по-прежнему скрываются операции соединения таблиц.

Содержание раздела