Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Проектирование БД как сжатие информации.




Какую структуру БД считать оптимальной? Не смотря на серьезные сложности как теоретического, так и практического характера, центральной руководящей идеей проектирования служит очевидный

 

Основной принципне дублируй информацию (за очевидным исключением ключей-ссылок)! Каждая ее часть должна храниться в одном, и только одном месте - таблице, определение которой согласовано с логикой задачи. Сведения, которые могут быть выведены (вычислены) – не информация и не должны храниться вообще.

 

Кроме очевидной цели компактного хранения (а БД - это большие хранилища данных, которые могут содержать миллионы записей; при таких объемах выигрыш или проигрыш в один символ при хранении каждой записи может оказаться весьма ощутимым), недопустимость дублирования вызвана и не менее важной причиной сложности модификации - при наличии дублирования, при коррекции одной копии необходимо корректировать и все остальные (а для этого, как минимум, программист должен вспомнить - а где же они все же расположены?)

 

Вернемся к примеру с жителями. При ожидаемом реальном наличии большого числа "пересечений" в полях таблицы ДОМА (т.е. достаточно большого числа повторений названий городов и улиц), можно

 

а) завести справочные (кодировочные) таблицы

УЛИЦЫ={<код_улицы, название_улицы>} и

ГОРОДА={<код_города,название_города>},

сопоставляющую длинным названиям улиц и городов некоторые краткие коды с тем, чтобы иметь возможность хранить в таблицах ДОМА и ЛЮДИ более краткие ключи вида

<номер_дома, код_улицы, код_города>

 
 

или же

б) связать улицы с номерами имеющихся на них домов, а города – с названиями имеющихся в нем улиц, определив структуру введенных таблиц следующим образом

ЛЮДИ={<код_дома,...(другие атрибуты людей)>}

ДОМА={<код_дома, номер_дома, код_улицы,... (другие атрибуты домов)>},

УЛИЦЫ={<код_улицы, название_улицы, код_города>},

ГОРОДА={<код_города, название_города>},

 


 

Очевидно, что осуществив разбиение (декомпозицию) информации о связи между домами и улицами, а также улицами и городами (которую мы намеревались первоначально хранить в таблице ДОМА) и вынеся ее в отдельные таблицы УЛИЦЫ и ГОРОДА, мы получили новые связи “один-ко-многим” между таблицами УЛИЦЫ-ДОМА и ГОРОДА-УЛИЦЫ.

 

Приведенный пример показывает, что

 

соображения физической эффективности хранения и обработки данных могут потребовать уточнения (декомпозиции), но никак - не ломки! - начальной логической схемы. (Вспомним наш старый принцип - семантика основа прагматики!)

 

Будем считать в дальнейшем, что мы приняли последний вариант решения. Почему? Очевидно, такое сжатие будет тем более эффективным, чем больше его “коэффициент” - среднее количество дочерних записей, приходящихся на одну родительскую запись. В худшем случае – связи “один-ко-одному” – мы в реальности лишь увеличим объем хранимой информации за счет введения избыточных кодов. Таким образом, (весьма нелегкая в практическом воплощении) стратегия определения структуры БД должна преследовать цель максимизации коэффициента сжатия.

 

Что мы делали, с точки зрения математики?

 

Соединением (композицией) двух таблиц (отношений) 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 – фактически, язык, состоящий из одних присваиваний.

 

К командам модификации (редактирования таблиц) БД относят команды вставки, удаления и изменения групп записей таблицы.

 


Поделиться:

Дата добавления: 2015-01-29; просмотров: 159; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты