Проектирование БД как сжатие информации.
Какую структуру БД считать оптимальной? Не смотря на серьезные сложности как теоретического, так и практического характера, центральной руководящей идеей проектирования служит очевидный
Основной принцип – не дублируй информацию (за очевидным исключением ключей-ссылок)! Каждая ее часть должна храниться в одном, и только одном месте - таблице, определение которой согласовано с логикой задачи. Сведения, которые могут быть выведены (вычислены) – не информация и не должны храниться вообще.
Кроме очевидной цели компактного хранения (а БД - это большие хранилища данных, которые могут содержать миллионы записей; при таких объемах выигрыш или проигрыш в один символ при хранении каждой записи может оказаться весьма ощутимым), недопустимость дублирования вызвана и не менее важной причиной сложности модификации - при наличии дублирования, при коррекции одной копии необходимо корректировать и все остальные (а для этого, как минимум, программист должен вспомнить - а где же они все же расположены?)
Вернемся к примеру с жителями. При ожидаемом реальном наличии большого числа "пересечений" в полях таблицы ДОМА (т.е. достаточно большого числа повторений названий городов и улиц), можно
а) завести справочные (кодировочные) таблицы УЛИЦЫ={<код_улицы, название_улицы>} и ГОРОДА={<код_города,название_города>}, сопоставляющую длинным названиям улиц и городов некоторые краткие коды с тем, чтобы иметь возможность хранить в таблицах ДОМА и ЛЮДИ более краткие ключи вида <номер_дома, код_улицы, код_города> или же б) связать улицы с номерами имеющихся на них домов, а города – с названиями имеющихся в нем улиц, определив структуру введенных таблиц следующим образом
ЛЮДИ={<код_дома,...(другие атрибуты людей)>} ДОМА={<код_дома, номер_дома, код_улицы,... (другие атрибуты домов)>}, УЛИЦЫ={<код_улицы, название_улицы, код_города>}, ГОРОДА={<код_города, название_города>},
Очевидно, что осуществив разбиение (декомпозицию) информации о связи между домами и улицами, а также улицами и городами (которую мы намеревались первоначально хранить в таблице ДОМА) и вынеся ее в отдельные таблицы УЛИЦЫ и ГОРОДА, мы получили новые связи “один-ко-многим” между таблицами УЛИЦЫ-ДОМА и ГОРОДА-УЛИЦЫ.
Приведенный пример показывает, что
соображения физической эффективности хранения и обработки данных могут потребовать уточнения (декомпозиции), но никак - не ломки! - начальной логической схемы. (Вспомним наш старый принцип - семантика основа прагматики!)
Будем считать в дальнейшем, что мы приняли последний вариант решения. Почему? Очевидно, такое сжатие будет тем более эффективным, чем больше его “коэффициент” - среднее количество дочерних записей, приходящихся на одну родительскую запись. В худшем случае – связи “один-ко-одному” – мы в реальности лишь увеличим объем хранимой информации за счет введения избыточных кодов. Таким образом, (весьма нелегкая в практическом воплощении) стратегия определения структуры БД должна преследовать цель максимизации коэффициента сжатия.
Что мы делали, с точки зрения математики?
Соединением (композицией) двух таблиц (отношений) PTÌX1´…´PK´… ´Xn , CTÌ Y1´…´FK´… ´Ym по связи PK,FK называют таблицу JÌ X1´…´PK´… ´Xn´ Y1´…´FK´… ´Ym, J={<x1,…,pk,…xn,y1,…,fk,…ym>: <x1,…,pk,…xn>Î PT & <y1,…,fk,…ym>Î CT & pk=fk} (слегка различные определения получим, если оставить в J лишь одно из равных значений pk,fk или исключить оба значения)
Декомпозиция – разбиение таблицы на две, композицией которых по некоторому отношению она является.
Теперь можно переформулировать наш основной принцип. - Осуществляй декомпозицию (с учетом кардинальности связи)
И все-таки, пока наш совет слишком общий для практического применения. Когда, в каких случаях можно и нужно осуществлять декомпозицию, какова стратегия декомпозиции?
Нормализация БД. Теоретическим фундаментом такой стратегии является понятие нормальной формы таблиц и, соответственно, интерпретация процесса проектирования как последовательного приведения к нормальным формам. Считается, что практически приемлемый результат дает приведение к первым 3 нормальным формам.
Первая н.ф. уточняет определение таблиц. Все поля таблиц должны быть уникальными атомами, а все содержательные отношения должны определяется с помощью внешних связей таблиц.
Под атомарностью имеется в виду неделимость логическая, т.е. зависящая от постановки задачи. Скажем, фамилия – строка символов, но она в большинстве случаев она неделима для нас как логическая единица, в то время как адрес – делим. Уникальность также понимается в логическом смысле. Поля могут быть одного типа, но они должны описывать разные атрибуты моделируемого объекта (в терминологии реляционной теории – принадлежать к разным доменам).
В отличие от изначального для реляционного подхода понятия отношения, таблицы как произвольного множества записей, в основе 2 и 3 нормальных форм (н.ф.) лежит понятие таблично задаваемой функции (графика, соответствия), взгляд на таблицу как график зависимости значений не ключевых полей от значений ключевых.
Пусть R – таблица, R Í T1´ … ´ Tn. Поле Ti зависит от поля Tj, если " r1,r12Î R (r1i = r2i à r1j = r2j). Аналогично определяется зависимость группы полей от группы полей (и выражений). По определению, все поля зависят от ключа.
Вторая н.ф. требует, чтобы в случае составных ключей ее аргументом служил весь ключ, а не отдельные входящие в него поля; т.е. для любой части ключа и любой части записи не существовало зависимости от части ключа.
Третья - то, чтобы ее аргументом служил только ключ, т.е. значения каждого не ключевого поля не зависели от значений никаких других полей, кроме ключевых. (В противном случае говорят о транзитивной зависимости)
Проиллюстрируем процесс нормализации на примере базы данных, описывающий факты купли-продажи: «Покупатели (Customer) делают заказы (Order) на товары (Product) продавцам (Employee)”
Первая нормальная форма. Атомарность.
Положим, что в контексте ситуации нас интересуют лишь следующие их характеристики «сущностей» Customer, Employee, Order и Product Customer – cName (имя покупателя), Employee - eName (имя продавца) Order – oTotal (сумма заказа), oDate (дата заказа) Product – pName (название товара), pPrice (цена товара), pAmount (количество проданного покупателю товара)
Положим также, что каждая из основных сущностей имеет некоторый естественно определяемый первичный ключ: Cust_Id – скажем, номер паспорта покупателя Emp_Id – табельный номер продавца Order_Id – учетный номер заказа Prod_Id – артикул товара
Изначально, имеем сложное 4-арное отношение между сущностями Customer, Employee, Order и Product, что соответствует самой простой и весьма далекой от оптимальной “плоской” структуре БД, состоящей из единственной таблицы.
Формально - нужно осуществить его декомпозицию (разбиение) на совокупность бинарных отношений, что мы и могли бы сделать, нормализуя исходную БД. Естественнее однако, попытаться определить в логических терминах отношения между сущностями. Если не формальное определение, то смысл последних явно следует из постановки задачи.
Customer/Order – Покупатель делает заказ Employee/Order – Продавец принимает/исполняет заказ Order/Product – Заказ состоит из (включает в себя) набора товаров (отметьте – все отношения “один-ко-многим”)
Все остальные отношения между сущностями явно вторичны, косвенны, не бинарны – скажем отношение продавец/покупатель явно подразумевает наличие заказа. (Здесь и далее мы стараемся делать самые слабые допущения относительно предметной области. Нетрудно представить ситуацию, когда присутствуют и другие отношения между сущностями. Скажем, в данной фирме каждый покупатель может быть “прикреплен” к конкретному продавцу, что соответствуют наличию прямой связи Employee/Customer).
Первые два отношения нетрудно реализовать добавлением в таблицы Customer и Employee ключевых полей CustId и EmpId, и добавлением соотвествующих полей - внешних ключей CustRef и EmpRef в таблицу Order. Ситуация с отношением Order/Product чуть сложнее. То, что сущность/понятие «заказ» включает в себя несколько экземпляров сущностей «товар» провоцирует на то, что структура таблицы Order должна включать в себя несколько ссылок на таблицу Product – скажем, ProdRef1,…, ProdRefn. Технически, это возможно, если известна явная константа – максимальное число товаров в заказе – скажем, не более 3. Но с точки зрения 1 НФ использование таких неявных отношений “один-ко-многим” недопустимо.
Замечание. Нормальные формы – лишь ориентир при проектировании. Реальная практика часто требует более тонкой классификации отношений и учета кардинальности связей. “Статичные” связи вида 1:Const и даже Const1:Const2 нередко на практике закладываются в определение таблиц. Пример – поквартальные или помесячные сводки – соответственно, связи вида 1:4 и 1:12. Категорически запрещается лишь фиксировать в структуре таблицы лишь отношения с переменной кардинальностью.
“Лобовой” способ удовлетворить 1РФ – превратить статичную структуру полей в динамическую структуру записей, переструктуриров таблицу Orders так, что бы «дублирующие сущность» поля Product1,Product2,… стали записями этой таб лицы:
Однако, это приводит к тому, что теперь группа полей зависят от OrderId (собственно заказа), а другая часть – от OrderId,ProdId (отдельного пункта заказа), что противоречит 2НФ. Нужно оставить лишь поля – атрибуты самого заказа, выделив все лишнее – атрибуты экземпляра товара, пункта заказа – в отдельную таблицу. Это заставляет нас выделить явно отношение включения между заказом и экземляром товара (OrderItem).
Наконец, посмотрим на таблицу oItem. Является ли пара Order_Ref, Prod_Id первичным ключом, т.е. могут ли в одном заказе одинаковые товары? Положим, что да. Для идентификации пункта добавим поле item_no – номер пункта заказа. Тогда Order_Ref, Item_No – первичный ключ, он определяет товар (снова - в том лишь смысле, что для данного заказа и номера, существует единственный товар этого заказа с таким номером). Но цена товара определяется самим товаром, т.е. Prod_Id, не входящим в первичный ключ. Нарушено требование 3 н.ф. Выносим отношение Prod_Id/Price в отдельную таблицу Product и добавляем связь между oItem и Product. Логически, это связь - отношение принадлежности между товаром и экземпляром товара.
Модификация БД. Процедурные и декларативные СУБД. Нарушения целостности.
Некоторые проблемы можно а) предупредить или б) решить на раннем этапе проектирования.
Итак, если логически реляционные БД – совокупность таблиц, связанных отношениями, декомпозиция некоторого отношения R на бинарные, то, с точки зрения реализации – это просто набор таблиц (файлов записей).
Не удивительно поэтому, что с точки зрения реализации, модификация (преобразование состояния) БД – преобразования таблиц, сводящиеся в свою очередь, к преобразованиям записей соответствующих файлов. В процедурно-реляционно, «навигационных» языках (например, в языках популярного семейства языков СУБД, ориентированных на «малые» БД для персональных компьютеров xBase-dBase-FoxPro) алгоритмы преобразования записей таблиц осуществляются программистом, в декларативно (“собственно”) реляционных языках (пример – язык SQL, изначально – командный язык мэйнфреймов, «больших компьютеров» фирмы IBM) программист задает лишь спецификацию таких преобразований. С точки зрения реализации, преобразование БД есть либо - добавление (insert, append) - удаление (delete) - преобразование/модификация значения (replace, update)
Соотвественно, в процедурных языках БД присутствуют команды добавления, удаления записей и модификации значений полей записей, в декларативных языках – команды добавления таблицы к таблице, удаления подтаблицы и изменения значений в (под)таблице.
Конкретную структуру и синтаксис команд классического декларативного языка мы рассмотрим ниже, сейчас отметим более существенный момент.
Проблема. Очевидно, любая модификация БД должна сохранять ее семантику (т.е. отношение R), преобразовывать одно корректное (т.е. верное, с точки зрения предметной области) состояние базы в другое. Реализация преобразований допускает некорректные состояния. В этом случае говорят о нарушении целостности данных БД.
Разумеется, это не есть специфическая для СУБД проблема, но именно здесь она преобретает наибольшую остроту. В отличие от процедурного программирования, СУБД изначально ориентированы на долговременное хранение данных и их корректность имеет здесь наивысший приоритет.
Нарушение целостности может происходить по 2 причинам. Первая из них связана с очень слабым аппаратом описания типов данных. Это может проявляться в следующих нарушениях целостности:
0) Нарушения “уровня столбца” (пример – уникальность, но не упорядоченность!) 1) Нарушения “уровня поля”, неточное описание доменов - областей допустимых, с точки зрения логики предметной области, значений полей.
Пример. Описание прямоугольника R={<x,y>: x Î [1,3] & y Î[1,2]} в качестве таблицы (именованного отношения) как подмножества D2 (D – множество вещественных чисел) – что верно, но не точно, поскольку технически допустима, например, запись {xà0,yà0}
2) Нарушения “уровня записи”. Неточное описание таблицы как отношения, взаимосвязи значений полей.
Пример. Описание круга R={<x,y>: x2+ y2£1} как подмножества D2 Отметьте – ситуация действительно отличается от 1). Даже точное описание доменов полей – R Ì [-1,1] 2- не спасает от возможных ошибок.
Принятое решение – описывать таблиц более точно, за счет добавления к определению таблиц предикатов, ограничивающих множества допустимых состояния полей и записей. Такие предикаты называют правилами допустимости (значений)– validation rules.
Нарушения “уровня связей”. Второй тип ошибок следует непосредственно из реализации. Команды СУБД преобразуют таблицы, а не связи, в то время как любое нетривиальное преобразование предполагает согласованное преобразование двух и более таблиц. Корректное изменение состояния таблицы не означает корректного изменения состояния БД.
Скажем, логическое действие “удалить из БД информацию о данном заказе” означает не только удаление соответствующей записи из таблицы Orders, но и удаление ее дочерних записей (пунктов заказа) из таблицы Items и даже, возможно, удаление информации о покупателе, сделавшем этот заказ в случае, если в БД больше нет информации о его заказах.
Данные – не только область допустимых значений. Описание данных предполагает и описание класса допустимых преобразований.
Удивительно, насколько это фундаментальное и общепринятое по отношению к типам данных положение с трудом проникает в область БД - по существу, частного случая типа данных. По всей видимости, в практике современных СУБД пока не делалось серъезной попытки анализа и классификации класса семантических преобразований, сохраняющих декомпозицию многоместных отношений (но – см. далее понятие трансакции). Но эволюция в нужном направлении очевидна.
В современных СУБД рассматривается класс преобразований двух связанных отношением таблиц, сохраняющих ссылочную целостность (referential integrity). Преобразование двух связанных отношением “один-ко-многим” таблиц не сохраняет ссылочную целостность, если после его применения в дочерней таблице остаются “сироты”, т.е. записи с несуществующим в родительской таблице значением внешнего ключа.
Различают несколько стандартных типов сохранения ссылочной целостности. К "операционной" эволюции реляционных БД. Технология клиент-сервер.
Итак, с точки зрения изначальной логики строения информации, база данных (БД) естьформальная модель некоторой предметной области в виде совокупности таблиц, связанных отношениями.
С точки зрения технологии "клиент-сервер", это традиционное определение нуждается в существенном добавлении - отражения логики практически возможного и логически допустимого изменения данных, реализуемой с помощью хранимых, вместе со значениями данных, процедур.
Эта точка зрения отражает еще более фундаментальный сдвиг в методологии программирования, нашедший на сегодня свое наиболее полное выражение в концепции абстрактного типа данных (или - класса, в объектно-ориентированном программировании, компонента в COM-).
Таким образом, понятие данных приобретает существенно динамический характер. С другой стороны, понятие абстрактного типа данных статично в том смысле, что система типов должно быть предварительно определена, хотя бы в виде абстрактной схемы, до разработки конкретных алгоритмов, с учетом всех возможных в дальнейшем случаев их использования. Такая существенная перемена приоритетов выдвигает на передний, центральный план этапы концептуального анализа и проектирования, с использованием соответствующих логико-математических методов. По статистическим оценкам, соотношение между этапами проектирования и собственно кодирования составляет около 80/20 - пропорция, обратная по отношению к традиционным методам!
Для того, чтобы в процессе модификации - а именно, вставки (insert), обновления (update) и удаления (delete) записей - БД не перестала быть целостной, т.е. не перестала адекватно отражать реальное содержание предметной области, необходимо выполнение следующих требований - правил целостности, или "бизнес-правил":
- таблицы БД не должны содержать нереальных данных, которые могут появиться как следствие ошибок программ обработки БД или некорректного ввода. Для этого в определение таблиц БД добавляют правила проверки (validation rules) значений поля или группы полей, определяющие необходимые условия их корректности;
так, например, значение поля номер_дома в таблице ДОМА должен принадлежать некоторому допустимому интервалу натуральных чисел – скажем, от 1 до 1000 (при более точном моделировании мы могли бы отражать встречающиеся в реальности номера домов вида натуральное-буква и сформулировать более сложное условие проверки корректности значения поля);
В том - крайне нежелательном и опасном! - случае, когда задача моделирования подразумевает наличие связи между таблицами, но фактически некоторая запись дочерней таблицы не ссылается ни на одну запись родительской таблицы (т.е. содержит отсутствующий в родительской таблице значение ключа), то такую запись называют сиротой (orphan). По соглашению, запись с неопределенным явно, т.е. равным NULL, ключом сиротой не считается.
Так, в нашем примере запись в таблице ЛЮДИ будет сиротой, если она содержит ссылку на не существующий адрес дома – отсутствующее в таблице ДОМА значение поля КодДома. Запись со значением ссылки NULL ("временно не имеющий места жительства") сиротой не будет.
- БД должна удовлетворять условию ссылочной целостности (referential integrity), т.е. в таблицы БД, - в результате тех же причин - не должны попадать записи-"сироты". Следовательно, модификация связанных таблиц должна быть согласованной. К наиболее простым и популярным вариантам такого согласования относят ситуации, когда модификация записи родительской таблицы является а) каскадной (cascades), т.е. продолжается на соответствующие записи дочерней таблицы; b) нулевой (nulls), т.е. устанавливающей ключи дочерних записей в NULL; c) ограниченной (restricted), т.е. возможной и исполняемой лишь в тех случаях, когда у нее нет ни одной дочерней записи.
Как и правила проверки, варианты сохранения ссылочной целостности БД также являются частью ее определения. Обеспечивающие целостность стандартные хранимые процедуры называются триггерами. [2]Разумеется, более сложные варианты согласования модификации двух и более таблиц могут потребовать реализации соответствующих пользовательских процедур-триггеров.
Так, в нашем примере наиболее естественно принять ограниченный вариант удаления – информация о доме не может быть удалена, пока таблица ЛЮДИ содержит хотя бы одну запись о человеке, в этом доме проживающем, и каскадный вариант модификации значений – изменение первичного ключа в любой записи таблицы ДОМА (т.е. одного из полей номер_дома, код_улицы, код_города) должно автоматически изменять атрибуты соответствующих записей дочерней таблицы ЛЮДИ.
С точки зрения реляционного подхода, все команды СУБД рассматриваются как преобразователи одной или нескольких таблиц, результатом которых снова является таблица (новая или обновленная старая):
T:= y(T1,…,Tn)
à (Стандартный) SQL – фактически, язык, состоящий из одних присваиваний.
К командам модификации (редактирования таблиц) БД относят команды вставки, удаления и изменения групп записей таблицы.
Представления.
В отличие от них, результатом команды запроса к БД является абстрактная, "виртуальная" таблица, не существующая физически в виде постоянно хранимого файла, но лишь отражающей текущее состояние реально физически хранимых, или – базовых таблиц БД. Цель использования таких таблиц очевидна – отобразить в развернутом, полном и доступном для пользователя виде – причем разном, для разных групп пользователей - интересующего именно его минимально достаточную по объему информацию о реальных объектах предметной области по компактно закодированной информации, содержащейся в базовых таблицах.
Так, естественная, для большинства пользователей, информация о домах должна включать не о введенных нами в целях экономии хранения кодах улиц и городов, но об их реальных названиях, хранящихся в базовых справочных таблицах УЛИЦЫ и ГОРОДА и, конечно, другие атрибуты домов из базовой таблицы ДОМА. В одних случаях, эта информация должна быть полной, включающей атрибуты всех проживающих в этих домах людей, в других - содержать лишь количество проживающих, относится лишь к одному городу и проч.
В реальности, каждая группа пользователей определяет некоторую специфическую схему сущностей и связей, которая и является, с точки зрения данной группы, логическим содержимым БД. С точки зрения реализации, такая "виртуальная БД" есть набор именованных запросов или представлений, связываемых с данной группой пользователей. Итак, представления (views) – это абстрактные (пользовательские) таблицы, определение (но не содержимое!) которых храниться в виде именованных команд запроса как часть БД. Подобно базовым таблицам, представления могут служить аргументами других запросов и представлений, позволяя таким образом программисту определять сложные родо-видовые иерархии объектов предметной области.
Так, в нашей модели-примере естественно определить представление ДОМА1 – именованном запросе, “хранящем” раскодированную по таблицам ДОМА, УЛИЦЫ и ГОРОДА полную информацию о домах в виде, естественном для пользователя БД, и представление ЛЮДИ1, “содержащую” (с точки зрения пользователя БД) информацию о людях, включающую ссылки на представление ДОМА1 и базовую таблицу ЛЮДИ. В свою очередь, эти представления могут служить базой более конкретных представлений ЖИТЕЛИ_КАЗАНИ и ЖИТЕЛИ_ЦЕНТРА.
В какой степени можно относиться к абстрактным таблицам также, как к реальным, физически существующим? С точки зрения пользователя, “содержимое” модифицируемых представлений можно редактировать с помощью команд модификации – но поскольку такового, в реальности, не существует, последнее может означать лишь подходящую модификацию базовых таблиц
Так, изменение, номера дома в некоторой записи представления ЖИТЕЛИ_ЦЕНТРА в реальности может означать лишь изменение значения дочернего ключа код_дома в таблице ЛЮДИ.[3]
По существу, модификация, т.е. преобразование представления T, основанном на запросе S к базовым таблицам T1,...,Tn, T=S(T1,..,Tn), к некоторому новому состоянию T’, означает требование к СУБД найти такое модификацию (преобразование) базовых таблиц к новому состоянию T1’,...,Tn’, которое вело бы к желаемому содержимому представления, T’=S(T1’,..,Tn’).
Модификация представления в действительности означает модификацию данных базовой таблицы
Понятно, что в целом такое обратное преобразование технически трудно реализуемо и, даже теоретически, может быть неоднозначным или просто не существовать; помимо этого, различные СУБД накладывают дополнительные ограничения на критерий модифицируемости представлений, исходя из соображения эффективности генерации требуемой модификации.
Пример неосуществимости модификации представления. Заведем в нашей модели-примере представление, содержащее единственное поле – средний доход людей, информация о которых хранится в таблице БД. Как повысить средний доход – т.е. изменить значения поля доход в таблице ЛЮДИ? Как подсказывает математика (и наш жизненный опыт), решение этой задачи далеко не однозначно.
Помимо фундаментальной роли в построении/определении логики программной системы, понятие представления служит для сокрытия реализации не только в смысле сокрытия реальной структуры БД, но и сокрытия реальных источников данных, которые могут быть как локальными (находится физически на клиенте), так и удаленными (находится на сервере). Этот факт существенно используется для создания и безопасного для реальных данных тестирования локального прототипа программной системы, оперирующего локальными представлениями (базирующихся на локальных копиях таблиц уже существующей или будущей серверной БД), после окончательной отладки превращаемого (полу)автоматической заменой ссылок в реальную систему, оперирующую с удаленными данными. Такое преобразование локального прототипа в реальное сетевое приложение называется подъемом (upsizing) БД.
Введенное ранее понятие целостности БД - важнейший случай более общего понятия безопасности данных, подразумевающего включение в рассмотрение не только логической схемы самой БД, но и некоторую схему всех аспектов ее использования - от физического размещения и сохранности данных до определения прав пользователей - относимым к вопросам ведения или администрирования БД. Не касаясь здесь сколь-нибудь подробно этих вопросов, отметим лишь как существенно бóльшую безопасность данных, так и бóльшую сложность задач администрирования при использовании технологии "клиент-сервер"[4]. Одним из наиболее важных программных средств обеспечения безопасности данных является механизм поддержки транзакций.
Транзакция - логически единая операция по модификации базовых таблиц, состоящая из одной или нескольких команд СУБД, переводящая БД из одного целостного, корректного, с точки зрения предметной области, состояния в другое, также логически корректное. Поддержка транзакций гарантирует, что входящие в транзакцию команды либо выполнятся полностью, либо – если последнее невозможно по какой-либо причине (сбой энергоснабжения, конфликт действий пользователей в многопользовательской/ сетевой БД и пр.) – полное восстановление состояния БД на момент начала транзакции (или иной выбранной программистом контрольной точки соответствующей процедуры).
Примером транзакции может служить триггер каскадного удаления записи родительской таблицы, с последующим удалением записей дочерних таблиц. Все удаления должны быть либо осуществлены полностью, либо не осуществлены вообще – в противном случае в БД могут появиться записи-сироты.
Подобно традиционному понятию процедуры, транзакция – логическая операция, реализуемая с помощью команд языка. Отличие - в явном допущении возможности лишь частичного выполнения. Основной принцип транзакции - "все или ничего". Сбой при выполнении любой команды ведет к откату – невыполнению всей транзакции.
Помимо проблем логической целостности и компактного хранения данных, проблемы обеспечения высокой скорости доступа к данным также играют в СУБД немаловажную роль. Эти проблемы решаются в основном, за счет применения тех или иных вариантов алгоритмов быстрого дихотомического поиска в таблицах - требующих компактного хранения нужного порядка расположения записей таблиц в отдельных индексных файлах. Исходя из предполагаемой частоты тех или иных запросов, пользователь СУБД может затребовать создания ускоряющих выполнение этих запросов индексных файлов. В силу своей особой роли ключевые поля таблиц, как правило, индексируются автоматически.
Итак, с точки зрения логики моделирования
База данных = (Базовые) Таблицы + Отношения + Правила целостности + Представления
а также, с точки зрения реализации - обеспечивающие выполнения правил целостности хранимые процедуры (в том числе триггеры) и ускоряющие обработку индексные файлы.
Почему SQL? Введение в технологию "клиент-сервер".
Как показывает практика, системы управления баз данных (СУБД) составляют наиболее значительную часть всех используемых программных систем – при этом часть, все более увеличивающуюся в связи с развитием локальных и, особенно, глобальных компьютерных сетей. Язык структурированных запросов SQL (Structured Query Language)[5] фактически играет роль стандарта языка коммуникации сетевых СУБД, часто работающих под управлением различных операционных систем и использующих разные форматы представления информации. "Встроенный" SQL не только является неотъемлемой частью любой современной СУБД, но и любой сколь-нибудь крупной системы программирования, ориентированной на использование технологии "клиент-сервер". Среди прочих достоинств SQL отметим максимальную компактность, обеспечивающую при этом полноценные средства обработки БД и логическую простоту, делающую SQL не только языком программирования, но и неоценимым средством проектирования и функционального описания достаточно больших программных систем. Сказанное объясняет несомненную важность изучения SQL. Недостатки SQL – обратная сторона его достоинств. Стандартность SQL не идеальна – в действительности, различные СУБД использует отличающиеся диалекты языка, что делает далеко не тривиальным перенос определения и данных БД из одной среды в другую - в частности, т.н. "подъем" (upsizing) БД из локальной среды в сеть. Компактность и декларативность языка, отсутствие в нем традиционных структур управления (циклов, условных операторов и пр.) усложняет переход на SQL программистов, привыкших к процедурному программированию в стиле языков семейства xBase/dBase. В целом, характерный для SQL более абстрактный и высокоуровневый реляционный подход, т.е. взгляд на обработку данных как преобразование таблиц "в целом", сильно отличается по своей логике от характерного для языков этого семейства навигационного подхода - преобразования отдельных записей таблиц.
Цель настоящего пособия скромна - не заменить достаточно богатую "толстую" литературу по SQL и технологиям СУБД в целом, но скорее - подготовить к ее чтению начинающего осваивать эту обширную область, выделив (даже в ущерб если не точности, то полноте изложения) одновременно наиболее существенное и минимально достаточное. Пособие включает краткое теоретическое введение в терминологию реляционных СУБД и технологии "клиент-сервер", синтаксис языка SQL, встроенного в язык MS Visual FoxPro и типовые задания по СУБД. Автор заранее благодарен за все критические замечания и пожелания коллег и студентов, направленные на улучшение данного пособия как по содержанию, так и стилю изложения. Он особенно благодарен Р.Тагирову и В.Байрашевой, уже сделавших ряд ценных предложений подобного рода. Диаграмма 1. Эволюция сетевых БД.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|