Модели баз данных

  Банников Н.А. www.stikriz.narod.ru Почта На главную страницу  

Рейтинг@Mail.ru

Концептуальная модель

                Концептуальная модель наиболее полно отвечает потребностям проектирования баз знаний и построена на ряде принципов, которые мы сейчас рассмотрим. Есть две большие области понятий в концептуальной модели. Обе они построены по принципу иерархического дерева. Первая область – это дерево типов данных, вторая – дерево данных. Дерево типов описывает структуру данных дерева данных, поэтому без дерева типов нет никакой логической целостности дерева данных. Для начала, рассмотрим простой пример с телевизионной камерой. Отраженный свет попадает в объектив камеры, там он разлагается на три составляющие: синий, красный, зеленый. Записывая уровень освещенности трех составляющих света 25 раз в секунду, мы можем составить представление об освещенности и отражающей способности предметов, которые мы снимаем. Теперь дадим основные определения.

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

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

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

                Тип – набор свойств и событий объекта, описанных как единый комплекс. При этом, в зависимости от уровня упрощений, у нас может быть свойством типа другой тип. Например, совокупность трех событий дает нам тип – снимаемый предмет на камеру.

                Объект – совокупность типов и свойств, объединенных в один тип, способный описать объект реального мира. В нашем примере один тип достаточен для описания объекта, снимаемого на камеру, но бывают случаи, когда одного типа недостаточно, или уровень упрощения слишком высок, чтобы можно было составить простую модель. Например, объект машина состоит из типов: кузов, рама, мотор, колеса и т.д. Эти типы, в свою очередь, тоже являются объектами, которые состоят из типов, например для колеса: обод, камера, покрышка и т.д. Для камеры: оболочка, ниппель, давление воздуха и т.д. Можно бесконечно углубляться в детализацию, но, как правило, это не требуется. Рассмотрим разные точки зрения пользователей на наши типы, в зависимости от состояния технологического процесса производства и продажи машины. Человек, который собирает колесо, рассматривает его как объект, состоящий из типов: оболочка, ниппель, давление воздуха. Он собрал колесо и передал его на главный конвейер. Далее колесо рассматривается как тип, входящий в состав объекта рама. На последней стадии сборки, нам уже не важно иметь в поле зрения свойство колесо, практически, мы потеряли его из видимости. Далее, мы рассматриваем тип рама, входящий как свойство в объект машина. Человек, который пришел покупать машину, может рассматривать его то, как объект то, как тип, входящий как свойство в объект материальное состояние и т.д. Из этих рассуждений видно, что концептуальная модель очень гибка и самодостаточна для описания внешнего мира. Мы можем двигаться от простого к сложному, описывая все, что входит в технологический процесс.

                Связь – это свойство типа или свойства типа, характеризующая взаимосвязь типов в дереве данных или способ изменения значения свойства объектного типа соответственно. Бывают три типа связей: включение в дереве данных, вставка из другого типа значения свойства типа и ссылка на экземпляр типа в дереве данных. Включение позволяет строить дерево данных. Вот пример. Объект офис состоит из свойств объектного типа – комнаты. Мы не можем описать любой офис прямо в типе офис, т.к. заранее неизвестно, сколько комнат в нем будет, поэтому мы описываем связь типа офис с типом комната. Теперь создав экземпляр типа офис, мы можем добавить к этому узлу дерева данных нужное количество ветвей типа комната. Или, например, накладная состоит из шапки и списка товаров. Мы можем рассматривать шапку как узел дерева данных, а список товаров, как ветви дерева данных, исходящие из этого узла. Вставка значения свойства типа из другого типа – это способ редактирования свойства типа, при котором значение одного из свойств типа вставляется из экземпляра свойства другого типа. Например, мы можем описать связь цвета панели инструментов в программе, которое будет редактироваться из списка цветов операционной системы. При этом связь устанавливается только на время редактирования, по завершении которого связь полностью разрывается. Ссылка характерна тем, что будучи один раз установлена, не разрывается после редактирования. Это похоже на вычисляемое свойство таблицы базы данных. Если Вы измените тип, на который установлена ссылка, то во всех экземплярах типов, где есть ссылка на этот тип будет произведено изменение.

                Наследование – это способ описания дерева типов. Вы можете описать тип литература, от которого наследовать типы: книга, журнал, статья. При этом поддерживается полиморфизм. Так, если в литературе есть свойство автор, произведя поиск по потомкам от литературы, Вы найдете все книги, журналы и статьи этого автора.

                Имея такие богатые возможности, концептуальная модель долгое время была не реализована. Мне удалось написать реализацию концептуального подхода. Авторами концептуальной модели были Смит и Смита – американские ученые, написавшие ряд статей в 1972 – 1976 годах, которые, по общему мнению, считались утопией. В сущности,  человек мыслит именно концептуально. Мы знаем, и какие характеристики есть у объекта, и значения этих характеристик. Мы знаем, что автобус и Жигули – это машины, а Жигули, Мерсы и Тойоты – это легковые автомобили. У нас в мозгах тоже есть дерево типов (наследование + описание свойств типа) и дерево данных (в сумку можно положить хлеб и огурцы).

Инфологическая модель данных "Сущность-связь"

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

Сущность – любой различимый объект. Самолет, машина, крыло, колесо – это сущности. Как и в концептуальной модели есть тип сущности и его экземпляр. Например, тип сущности – машина, а экземпляр – Москвич.

Атрибут – поименованная характеристика сущности. Например, у машины есть атрибуты: мотор, кузов, шасси и т.д. Атрибуты используются для определения того, какая информация должна быть собрана о сущности. Любой атрибут может быть сущностью, в зависимости от точки зрения на него. Так ошейник – это сущность, но на собаке – это уже ее атрибут.

Связь – ассоциирование двух или более сущностей.


Первый тип связи – связь ОДИН-К-ОДНОМУ (1:1): в каждый момент времени каждому представителю (экземпляру) сущности А соответствует 1 или 0 представителей сущности В. Например, работник и его ставка.

                В концептуальной модели можно было бы наследовать от типа работник тип строчка в ведомости, где добавить свойство сумма зарплаты, тогда указав должность работника можно узнать какие зарплаты получают работники, занимающие или занимавшие эту должность.


Второй тип – связь ОДИН-КО-МНОГИМ (1:М): одному представителю сущности А соответствуют 0, 1 или несколько представителей сущности В.

                В концептуальной модели это соответствует включению.

На основе этих двух видов связей, Вы можете составить более сложные связи.

Ключ – минимальный набор атрибутов, по значениям которых можно однозначно найти требуемый экземпляр сущности. Как правило – это первичный ключ в таблице базы данных. Теперь о внешних ключах:

Если сущность С связывает сущности А и В, то она должна включать внешние ключи, соответствующие первичным ключам сущностей А и В.

Если сущность В обозначает сущность А, то она должна включать внешний ключ, соответствующий первичному ключу сущности А.

К.Дейт определяет три основные класса сущностей: стержневые, ассоциативные и характеристические, а также подкласс ассоциативных сущностей – обозначения.

Стержневая сущность (стержень) – это независимая сущность. Например, при описании накладной, стержневой сущностью является шапка накладной.

Ассоциативная сущность (ассоциация) – это связь вида "многие-ко-многим". Например, товар в накладной – это связь с шапкой накладной и справочником наименований товара, справочником единиц измерения.

Характеристическая сущность (характеристика) – это связь вида "многие-к-одной" или "одна-к-одной" между двумя сущностями (частный случай ассоциации). Единственная цель характеристики в рамках рассматриваемой предметной области состоит в описании или уточнении некоторой другой сущности. Это что-то вроде перечисления. Например, Список поставщиков – это список указателей на отдельные записи из справочника организаций. При указании поставщика в накладной, Вы выбираете его из списка поставщиков, но реально указываете организацию из справочника организаций. Просто организация может быть и поставщиком, и покупателем, и налоговым органом, но Вам удобнее будет выбирать из более короткого списка.

Обозначающая сущность или обозначение – это связь вида "многие-к-одной" или "одна-к-одной" между двумя сущностями и отличается от характеристики тем, что не зависит от обозначаемой сущности. Например, зачисление народных депутатов в разные комитеты. Один народный депутат может входить в разные комитеты.

Реляционная модель

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

Э.Кодд предложил использовать для обработки данных аппарат теории множеств (объединение, пересечение, разность, декартово произведение). Он показал, что любое представление данных сводится к совокупности двумерных таблиц особого вида, известного в математике как отношение – relation.

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

Доменом называется множество атомарных значений одного и того же типа. В современных реляционных базах данных, в домен входят первичный ключ одной таблицы и поля другой таблицы по внешнему ключу к первой. Например, в списке товара накладной, в домен входят поля первичного ключа справочника наименований и поле списка товара, в которое образует внешний ключ по первичному ключу справочника наименований.

Заголовок домена в данном примере – это справочник наименований с рядом атрибутов, например ед. измерения, максимального процента наценки (для медикаментов и детских товаров) и т.д.

Тело домена состоит из меняющегося во времени множества кортежей. Проще говоря, тело – это строчки в таблице со списком товара, а кортежи – это значения в столбике внешнего ключа.

Степень отношения – это число атрибутов домена. Отношение степени один называют унарным, степени два – бинарным, степени три – тернарным, ..., а степени n – n-арным. Повышение степени отношения влечет за собой увеличение дублирующейся информации, хранимой в базе данных, т.к. в теле домена нужно хранить большее количество значений, указывающих на заголовок. Поэтому лучше, если Вы будете использовать суррогатные ключи вместо естественных. Естественный ключ естественным образом описывает первичный ключ заголовка. Например, для платежного поручения первичный ключ мог бы содержать отчетный год, номер и плательщика. Если список платежных поручений нужно было бы рассматривать как заголовок домена, то все эти атрибуты копировались бы в теле домена. Поэтому лучше использовать суррогатные ключи, которые формируют как случайное целое число или как последовательность целых чисел. Поэтому всегда получается унарная степень отношения.

Кардинальное число или мощность отношения – это число его кортежей. Кардинальное число отношения изменяется во времени в отличие от его степени. Практически кардинальное число – это количество строк в заголовке.

Итак:

Отношение – Таблица,
Кортеж – Строка,
Атрибут – Столбец, поле.

Нормализация – это разбиение таблицы на две или более, обладающих лучшими свойствами при включении, изменении и удалении данных. Окончательная цель нормализации сводится к получению такого проекта базы данных, в котором каждый факт появляется лишь в одном месте, т.е. исключена избыточность информации. Это делается не столько с целью экономии памяти, сколько для исключения возможной противоречивости хранимых данных и предсказуемости поведения системы во время эксплуатации. Последний факт полезен для понимания структуры данных пользователем, а значит ускорения обучаемости и исключения случайных ошибок в работе.

Каждая таблица в реляционной БД удовлетворяет условию, в соответствии с которым в позиции на пересечении каждой строки и столбца таблицы всегда находится единственное атомарное значение, и никогда не может быть множества таких значений. Любая таблица, удовлетворяющая этому условию, называется нормализованной или первой нормальной формой. Т.е. нельзя вносить в одну ячейку таблицы информацию о двух и более атрибутах объекта. Фактически, ненормализованные таблицы, даже не допускаются в реляционной БД.

Теория нормализации основывается на наличии той или иной зависимости между полями таблицы. Определены два вида таких зависимостей: функциональные и многозначные.

Функциональная зависимость. Поле В таблицы функционально зависит от поля А той же таблицы в том и только в том случае, когда в любой заданный момент времени для каждого из различных значений поля А обязательно существует только одно из различных значений поля В. Отметим, что здесь допускается, что поля А и В могут быть составными. Например, единица измерения списка товара в накладной зависит от наименования.

Полная функциональная зависимость. Поле В находится в полной функциональной зависимости от составного поля А, если оно функционально зависит от А и не зависит функционально от любого подмножества поля А.

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

Теперь можно дать академические определения нормальных форм:

Таблица находится в первой нормальной форме (1НФ) тогда и только тогда, когда ни одна из ее строк не содержит в любом своем поле более одного значения и ни одно из ее ключевых полей не пусто.

Таблица находится во второй нормальной форме (2НФ), если она удовлетворяет определению 1НФ и все ее поля, не входящие в первичный ключ, связаны полной функциональной зависимостью с первичным ключом.

Таблица находится в третьей нормальной форме (3НФ), если она удовлетворяет определению 2НФ и не одно из ее не ключевых полей не зависит функционально от любого другого не ключевого поля.

Таблица находится в нормальной форме Бойса-Кодда (НФБК), если и только если любая функциональная зависимость между его полями сводится к полной функциональной зависимости от возможного ключа.

Полной декомпозицией таблицы называют такую совокупность произвольного числа ее проекций, соединение которых полностью совпадает с содержимым таблицы.

Таблица находится в пятой нормальной форме (5НФ) тогда и только тогда, когда в каждой ее полной декомпозиции все проекции содержат возможный ключ. Таблица, не имеющая ни одной полной декомпозиции, также находится в 5НФ.

Четвертая нормальная форма (4НФ) является частным случаем 5НФ, когда полная декомпозиция должна быть соединением ровно двух проекций. Весьма не просто подобрать реальную таблицу, которая находилась бы в 4НФ, но не была бы в 5НФ.

                Пояснить определения нормальных форм легче на конкретных примерах, поэтому более детальный разговор о нормализации мы отложим на потом, когда будем разрабатывать реальную базу данных.

Язык SQL, быстрый старт.

                Рассмотрим простой пример базы данных платежных поручений. Именно платежные поручения были взяты мной, т.к. это достаточно короткий пример, чтобы можно было не расплываться по древу во время повествования, здесь можно показать на примере все нормальные формы таблицы, можно показать основные принципы работы в Delphi при создании программ баз данных.

                Вот как может выглядеть таблица с платежными поручениями в первой нормальной форме:

 

Наименование поля

Тип

Размер

Пояснения

Отчетный год

S

 

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

Номер

I

 

 

Дата

D

 

 

Сумма

F

 

 

ИНН плательщика

A

10

 

Наименование организации плательщика

B

 

Текст

Наименование банка плательщика

B

 

Текст

Расчетный счет плательщика в банке

A

20

 

Бик банка плательщика

A

9

 

Кор. Счет банка плательщика

A

20

 

ИНН получателя

A

10

 

Наименование организации получателя

B

 

Текст

Наименование банка получателя

B

 

Текст

Расчетный счет получателя

A

20

 

Бик банка получателя

A

9

 

Кор. Счет банка получателя

A

20

 

Вид оплаты

A

6

 

Назначение платежа

A

6

 

Код

A

6

 

Срок платежа

D

 

Как правило, не заполняется

Очередность платежа

A

6

 

Назначение платежа

A

6

Здесь храниться код назначения, что-то вроде: 6, 2, 4 и т.д.

 

Условные обозначения типов:      A – строка;

                                                               S – короткое целое;

I – целое число;

F – дробное число;

D – дата;

B – BLOB массив, например текст.

                Таблица в первой нормальной форме, но у нас многие значения в строке с платежкой будут повторяться. Давайте приведем ее ко второй нормальной форме. Сразу договоримся не включать в рассмотрение поля, начиная с вида оплаты и ниже. Почему? Далее я поясню, что бывают исключения из правил. Как говориться нормализуй, но не переусердствуй!

Таблица находится во второй нормальной форме (2НФ), если она удовлетворяет определению 1НФ и все ее поля, не входящие в первичный ключ, связаны полной функциональной зависимостью с первичным ключом.

                Информацию о плательщике и получателе вынесем в отдельную таблицу организаций, т.к. структура этой информации одинакова. Сразу договоримся, что будем использовать для связи таблиц суррогатные ключи на основе последовательности целых чисел.

Список платежных поручений

 

Наименование поля

Тип

Размер

Пояснения

Отчетный год

S

 

Отчетный год, номер и код плательщика – это первичный ключ списка платежных поручений.

 

Внешний ключ к по первичному ключу справочника организаций

Номер

I

 

Плательщик

I

 

Получатель

I

 

Внешний ключ к по первичному ключу справочника организаций

Дата

D

 

 

Сумма

F

 

 

Вид оплаты

A

6

 

Назначение платежа

A

6

 

Код

A

6

 

Срок платежа

D

 

Как правило, не заполняется

Очередность платежа

A

6

 

Назначение платежа

A

6

Здесь храниться код назначения, что-то вроде: 6, 2, 4 и т.д.

 

Справочник организаций

 

Наименование поля

Тип

Размер

Пояснения

Код организации

I

 

Первичный ключ

ИНН организации

A

10

 

Наименование организации

B

 

Текст

Наименование банка организации

B

 

Текст

Расчетный счет организации в банке

A

20

 

Бик банка организации

A

9

 

Кор. Счет банка организации

A

20

 

 

                Как будто все хорошо. Мы можем указать в списке платежек код плательщика и код получателя, но теперь справочник организаций не удовлетворяет второй нормальной форме. Приведем ко второй нормальной форме справочник организаций. Для этого выделим информацию о банках в справочник банков. Опять используем суррогатный ключ.

 

Справочник организаций

 

Наименование поля

Тип

Размер

Пояснения

Код организации

I

 

Первичный ключ

ИНН организации

A

10

 

Наименование организации

B

 

Текст

Код банка организации

I

 

Внешний ключ к по первичному ключу справочника банков

Расчетный счет организации в банке

A

20

 

 

Справочник банков

 

Наименование поля

Тип

Размер

Пояснения

Код банка

I

 

Первичный ключ

Наименование банка

B

 

Текст

Бик банка

A

9

 

Кор. Счет банка

A

20

 

 

Итак, вроде бы, все таблицы во второй нормальной форме. Посмотрим, что можно сделать дальше.

Таблица находится в третьей нормальной форме (3НФ), если она удовлетворяет определению 2НФ и не одно из ее не ключевых полей не зависит функционально от любого другого не ключевого поля.

                Для начала запишем наши определения таблиц в виде, более приближенном к тому, с чем имеет дело программист.

 

Список платежных поручений

Наименование поля

Тип

Размер

Пояснения

Year_Now

S

 

Первичный ключ - отчетный год, номер и код плательщика

Number

I

 

ID_Plat

I

 

ID_Pol

I

 

Код  получателя

Date_Now

D

 

Дата

Balance

F

 

Сумма

Opl_Type

A

6

Вид оплаты

Nazn_Type

A

6

Назначение платежа

Kod_Type

A

6

Код

Date_Plat

A

 

Срок платежа

Och_Type

A

6

Очередность платежа

Naznachenie

B

6

Назначение платежа

 


 

Справочник организаций

Наименование поля

Тип

Размер

Наименование поля

ID_Num

I

 

Код организации, первичный ключ

INN

A

15

ИНН организации

Short_Name

A

40

Короткое наименование организации

Full_Name

В

 

Юридическое имя организации

OKONH

A

10

ОКОНХ

OKPO

A

15

ОКПО

ID_Bank

I

 

Код банка организации

PC_In_Bank

A

25

Расчетный счет организации в банке

 

Справочник банков

Наименование поля

Тип

Размер

Пояснения

ID_Num

I

 

Код банка, первичный ключ

Short_Name

A

40

Короткое наименование банка

Full_Name

B

 

Наименование банка

BIK

A

15

Бик банка

KC1

A

25

Кор. Счет банка

KC2

A

25

Кор. Счет банка для валютных платежей

KC3

A

25

Кор. Счет банка банка для валютных платежей

KC4

A

25

Кор. Счет банка банка для валютных платежей

 

                Заметьте, что я изменил размеры полей некоторых таблиц и добавил несколько новых полей в таблицы. Увеличение длины строкового поля продиктовано стремлением к возможности подстраиваться к новым условиям при изменении отчетности. Так уже несколько раз было. На моей памяти уже три раза за два года. Поля OKONH и OKPO добавлены как информационные. Они ни как не участвуют в процессе создания платежки, но почему бы ни хранить их в справочниках, ведь платежка – это оплата по договору или по накладной, а для их составления неплохо знать ОКОНХ и ОКПО организации. В справочник банков было добавлено еще три корсчета. Это связано с тем, что валютный платеж проходит не напрямую из банка в банк, а через несколько посредников. В таком случае, нужно внести в наименование банка все наименования посредников и напечатать их корреспондентские счета. Это несколько неправильно с точки зрения нормализации, но сравним плату за нормализацию с потерями от ненормальной формы. При соблюдении нормальной формы, нам потребуется создать новую таблицу с корреспондентскими счетами банка, и указывать их все для создания валютной платежки, т.е. хранить эту информацию в списке платежек. Это увеличит потребность в системных ресурсах. Т.к. банков будет явно меньше, чем платежек, то оставив лишних три поля в таблице справочника банков, мы наоборот сэкономим системные ресурсы, тем более, что можно объявить поля как VARCHAR(25). Эти же  рассуждения справедливы и для полей Opl_Type, Nazn_Type, Kod_Type, Och_Type. Выделив их в отдельную таблицу, мы только усложним структуру базы данных, а эта плата неприемлемо высока.

Теперь, обратим внимание на справочник организаций. Здесь поле с расчетным счетом в банке зависит от кода банка. Это значит, что нужно перевести таблицу в третью форму нормализации. Выделим код банка и расчетный счет в отдельную таблицу.

 

Справочник организаций

Наименование поля

Тип

Размер

Наименование поля

ID_Num

I

 

Код организации, первичный ключ

INN

A

15

ИНН организации

Short_Name

A

40

Короткое наименование организации

Full_Name

В

 

Юридическое имя организации

OKONH

A

10

ОКОНХ

OKPO

A

15

ОКПО

ID_Rec

I

 

Код реквизита в банке по умолчанию

 

Справочник реквизитов организации

Наименование поля

Тип

Размер

Наименование поля

ID_Num

I

 

Код

ID_Company

I

 

Код организации

ID_Bank

I

 

Код банка организации

PC_In_Bank

A

25

Расчетный счет организации в банке

 

                Опять используем суррогатный первичный ключ. Связь таблиц организации и ее реквизитов организуем по внешнему ключу ID_Company. Обратите внимание, что формально соблюдая законы нормализации, мы получили более правильное представление об организации. Добиваясь третьей нормальной формы, мы пришли к тому, что организация может иметь несколько счетов в одном банке или в нескольких банках, что, вообще-то говоря, соответствует реальному положению дел. Поле ID_Rec оставлено в справочнике организаций, чтобы при создании новой платежки, автоматически выбирались реквизиты по умолчанию. Теперь, нам нужно пересмотреть список платежек, т.к. в этой таблице нет информации о реквизитах организации.      


 

Список платежных поручений

Наименование поля

Тип

Размер

Пояснения

Year_Now

S

 

Первичный ключ - отчетный год, номер и код плательщика

Number

I

 

ID_Plat

I

 

ID_Rec_Plat

I

 

Код реквизита плательщика

ID_Pol

I

 

Код  получателя

ID_Rec_Pol

I

 

Код реквизита получателя

Date_Now

D

 

Дата

Balance

F

 

Сумма

Opl_Type

A

6

Вид оплаты

Nazn_Type

A

6

Назначение платежа

Kod_Type

A

6

Код

Date_Plat

D

 

Срок платежа

Och_Type

A

6

Очередность платежа

Naznachenie

B

6

Назначение платежа

 

Полной декомпозицией таблицы называют такую совокупность произвольного числа ее проекций, соединение которых полностью совпадает с содержимым таблицы.

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

Таблица находится в пятой нормальной форме (5НФ) тогда и только тогда, когда в каждой ее полной декомпозиции все проекции содержат возможный ключ. Таблица, не имеющая ни одной полной декомпозиции, также находится в 5НФ.

                Обратите внимание на то, что поля ID_Plat, ID_Rec_Plat, ID_Pol, ID_Rec_Pol связывают список платежек со справочниками по первичному ключу, а это и есть пятая нормальная форма. На этом можно было бы остановиться, но я думаю, что пользователю неудобно выбирать плательщика и получателя из справочника организаций, т.к. справочник организаций – это и плательщики, и получатели вместе. База данных с организациями, возможно, будет использоваться как справочник и в других программах, поэтому, там могут появиться и другие организации, которые не имеют никакого отношения к получателям и плательщикам.  Эти рассуждения подвигают нас к тому, чтобы создать еще две таблицы с плательщиками и получателями. В этих таблицах будут храниться только коды плательщиков и получателей соответственно.             

 

Справочник плательщиков

Наименование поля

Тип

Размер

Наименование поля

ID_Company

I

 

Код организации, первичный ключ

Name

A

10

Поле для сортировки по наименованию

 

Справочник получателей

Наименование поля

Тип

Размер

Наименование поля

ID_Company

I

 

Код организации, первичный ключ

Name

A

10

Поле для сортировки по наименованию

 

                Теперь, соберем все вместе. Я рекомендую Вам всегда писать текстовый файл с определением базы данных. После его распечатки, Вы найдете множество глупостей, которые сделали из за невнимательности. На бумаге информация воспринимается лучше. Тем более, недопустимо создавать базу данных налету без предварительной документации. Не надо считать себя великим гением, способным по ходу дела, без охвата всех фактов, налету составить базу данных. А исправлять наспех состряпанное всегда сложнее, чем сразу сделать как нужно.

База данных платежного поручения

 

Справочник банков Banks

Наименование поля

Тип

Размер

Пояснения

ID_Num

I

 

Код банка, первичный ключ

Short_Name

A

40

Короткое наименование банка

Full_Name

B

 

Наименование банка

BIK

A

15

Бик банка

KC1

A

25

Кор. Счет банка

KC2

A

25

Кор. Счет банка для валютных платежей

KC3

A

25

Кор. Счет банка банка для валютных платежей

KC4

A

25

Кор. Счет банка банка для валютных платежей

 

Справочник организаций Companys

Наименование поля

Тип

Размер

Наименование поля

ID_Num

I

 

Код организации, первичный ключ

INN

A

15

ИНН организации

Short_Name

A

40

Короткое наименование организации

Full_Name

В

 

Юридическое имя организации

OKONH

A

10

ОКОНХ

OKPO

A

15

ОКПО

ID_Rec

I

 

Код реквизита в банке по умолчанию

 

Справочник реквизитов организации Rec_Company

Наименование поля

Тип

Размер

Наименование поля

ID_Num

I

 

Код

ID_Company

I

 

Код организации

ID_Bank

I

 

Код банка организации

PC_In_Bank

A

25

Расчетный счет организации в банке

 

 

Справочник плательщиков Plat

Наименование поля

Тип

Размер

Наименование поля

ID_Company

I

 

Код организации, первичный ключ

Name

A

10

Поле для сортировки по наименованию

 

Справочник получателей Pol

Наименование поля

Тип

Размер

Наименование поля

ID_Company

I

 

Код организации, первичный ключ

Name

A

10

Поле для сортировки по наименованию

 

Список платежных поручений          Plat_Por

Наименование поля

Тип

Размер

Пояснения

Year_Now

S

 

Первичный ключ - отчетный год, номер и код плательщика

Number

I

 

ID_Plat

I

 

ID_Rec_Plat

I

 

Код реквизита плательщика

ID_Pol

I

 

Код  получателя

ID_Rec_Pol

I

 

Код реквизита получателя

Date_Now

D

 

Дата

Balance

F

 

Сумма

Opl_Type

A

6

Вид оплаты

Nazn_Type

A

6

Назначение платежа

Kod_Type

A

6

Код

Date_Plat

D

 

Срок платежа

Och_Type

A

6

Очередность платежа

Naznachenie

B

6

Назначение платежа

 

                Теперь, нужно создать эти таблицы. Эту базу данных можно было бы создать, используя Paradox, но нам нужно научиться работать с SQL базами данных, поэтому мы будем писать SQL базу данных для Interbase Server. Для работы нам понадобиться локальный или удаленный доступ к серверу Interbase. Я рекомендую создавать таблицы локально, а потом переносить их на сервер. Чтобы у Вас было меньше проблем, создайте пользователя в локальном Interbase с таким же именем, как и на серверном варианте. Т.е. Вы должны узнать у администратора Interbase Server имя пользователя и пароль, который он даст Вам для доступа к сетевому серверу, а затем Вы можете создать точно такого же пользователя локально. Сразу позаботьтесь о безопасности. При установки локального Interbase Server поменяйте пароль по умолчанию masterkey на что-нибудь более секретное, а затем только создавайте новых пользователей. Далее, мы подключимся к локальному серверу с именем пользователя как в сетевом варианте, а не SYSDBA и создадим таблицы. Для создания таблиц лучше использовать InterBase Interactive SQL. Эта программа поставляется вместе с сервером и клиентом InterBase. Вот список команд, необходимых для создания таблиц. По ходу дела я рассмотрю их все.

CREATE DATABASE " …\PlatPor.gdb"

USER "…" PASSWORD "…"

PAGE_SIZE =  8192

DEFAULT CHARACTER SET "WIN1251"

Эта команда создаст файл базы данных по указанному пути с указанными параметрами. Выберите в меню InterBase Interactive SQL строку меню File/CreateDatabase… Здесь нужно указать имя файла базы данных с реальными путем, именем пользователя и паролем.


 

                Нажмите кнопку OK, и файл базы данных будет создан. Строчка PAGE_SIZE =  8192 говорит о размере страницы в файле базы данных. Можно указывать размер, равный максимальному размеру объекта базы данных, т.е. размер самой большой строки без BLOB полей, но это неразумно, лучше использовать размер побольше, чтобы в одной странице было несколько объектов. Дело в том, что страница считывается в память только целиком, так что можно рассматривать размер страницы как минимальный размер буфера потока, связанного с файлом базы данных. Строчка DEFAULT CHARACTER SET "WIN1251" означает, что символы в полях будут хранится в кодировке WIN1251. Эта строчка обязательна, если Вы хотите использовать русские буквы в текстах и строках при работе с Windows NT сервером. Теперь, пора начать создавать таблицы. Таблицы создаются, начиная со справочников, т.е. с заголовков доменов. Т.к. в списке платежек используется справочник организаций, а в справочнике организаций используется справочник реквизитов организаций, а в справочнике реквизитов организаций используется справочник банков, а в справочнике банков не используются другие справочники, то со справочника банков и начнем.

CREATE TABLE BANKS

(

 ID_NUM INTEGER NOT NULL,

 SHORT_NAME VARCHAR(40),

 FULL_NAME BLOB,

 BIK VARCHAR(15),

 KC1 VARCHAR(25),

 KC2 VARCHAR(25),

 KC3 VARCHAR(25),

 KC4 VARCHAR(25),

 PRIMARY KEY (ID_NUM)

);

                Этот запрос создает таблицу, в списке параметров идет перечисление полей, их тип и размер, если нужно, то можно указать значение по умолчанию, например: SHORT_NAME VARCHAR(40) DEFAULT “Новая организация”, но нам это, пока, не нужно. В конце запроса указано поле первичного ключа. Если в состав первичного ключа входят несколько полей, то их имена разделяют запятыми. Обратите внимание, что первичный ключ объявлен как NOT NULL, т.е. ему обязательно должно быть присвоено значение. Это обязательное правило.

CREATE INDEX BANKS_NAME ON BANKS(SHORT_NAME);

                Этот запрос создает индекс в таблице банков по полю с коротким именем. Этот индекс нам понадобится для более быстрого выполнения сортировки и поиска по короткому имени банка.

CREATE GENERATOR BANKS_GEN;

                Для присвоения значения суррогатному ключу, мы будем использовать т.н. генератор. Это просто какая-то переменная, доступ к которой пользователи одновременно получить не могут, поэтому в ней можно хранить последнее значение суррогатного ключа, а когда нужно вставить новую запись, увеличить его значение на единицу, и присвоить ключевому полю. Если в это время другой пользователь тоже вставляет новую запись, то его процесс приостановится, пока первый пользователь не закончит работу с генератором.

SET GENERATOR BANKS_GEN TO 50;

                Здесь мы устанавливаем начальное значение генератору. Цифра 50 была выбрана не случайно, т.к. кроме вызова процедуры на обновление счетчика, другие программисты могут использовать триггеры. Им будет нужно для работы хотя бы несколько номеров вначале последовательности, и они будут Вам очень благодарны за предоставленную возможность иметь эти номера.

CREATE PROCEDURE SET_BANKS_NUM

RETURNS (NUM INTEGER)

AS

BEGIN

 NUM = GEN_ID(BANKS_GEN, 1);

END;

                А вот и процедура, которая будет вызываться всякий раз при добавлении новой записи. Процедура, как явствует из описания, возвращает переменную с именем NUM целого типа. Эта переменная инициализируется вызовом стандартной процедуры InterBase, которая просто складывает значение генератора с единицей, и возвращает полученное значение.

                Запросы в InterBase Interactive SQL нужно заводить по частям. Отдельные запросы отделяются точкой с запятой. Вот пример работы с InterBase Interactive SQL.


 

                В нижней части окна виден предыдущий запрос, а в верхней части окна введен новый. Чтобы выполнить его, нажмите кнопку с подсказкой Execute query или выберите соответствующий пункт меню. В конце работы, выберите пункт меню File/Commit Work для принятия изменений в базе данных. Теперь, двигаемся дальше.

CREATE TABLE COMPANYS

(

 ID_NUM INTEGER NOT NULL,

 SHORT_NAME VARCHAR(40),

 FULL_NAME BLOB,

 INN VARCHAR(15),

 OKONH VARCHAR(10),

 OKPO VARCHAR(15),

 ID_REC INTEGER,

 PRIMARY KEY (ID_NUM)

);

 

CREATE INDEX COMPANYS_NAME ON COMPANYS(SHORT_NAME);

CREATE GENERATOR COMPANYS_GEN;

SET GENERATOR COMPANYS_GEN TO 50;

CREATE PROCEDURE SET_COMPANYS_NUM

RETURNS (NUM INTEGER)

AS

BEGIN

 NUM = GEN_ID(COMPANYS_GEN, 1);

END;

                Пока, ничего нового нет, все как в справочнике банков.

CREATE TABLE  REC_COMPANY

(

 ID_NUM INTEGER NOT NULL,

 ID_COMPANY INTEGER,

 ID_BANK INTEGER,

 RC_IN_BANK VARCHAR(25),

 PRIMARY KEY (ID_NUM),

 FOREIGN KEY (ID_COMPANY) REFERENCES COMPANYS(ID_NUM),

 FOREIGN KEY (ID_BANK) REFERENCES BANKS(ID_NUM)

);

CREATE INDEX REC_COMPANY_RC ON REC_COMPANY(RC_IN_BANK);

                Конструкция FOREIGN KEY объявляет внешний ключ. Здесь указано, что поле ID_COMPANY связано ссылочной целостностью с полем ID_NUM таблицы COMPANYS. То же самое и для банков.

ALTER TABLE COMPANYS

ADD FOREIGN KEY (ID_REC) REFERENCES REC_COMPANY(ID_NUM);

                Конструкция ALTER TABLE позволяет изменять уже существующую таблицу. В последнем запросе мы просто добавили внешний ключ в таблицу COMPANYS по полю ID_REC к таблице REC_COMPANY по полю ID_NUM. Мы не могли это сделать раньше, т.к. таблицы REC_COMPANY тогда еще не было. Теперь создадим следующие таблицы.

CREATE TABLE  PLAT

(

 ID_COMPANY INTEGER NOT NULL,

 PRIMARY KEY (ID_COMPANY),

 FOREIGN KEY (ID_COMPANY) REFERENCES COMPANYS(ID_NUM)

);

CREATE TABLE  POL

(

 ID_COMPANY INTEGER NOT NULL,

 PRIMARY KEY (ID_COMPANY),

 FOREIGN KEY (ID_COMPANY) REFERENCES COMPANYS(ID_NUM)

);

CREATE TABLE  PLAT_POR

(

 YEAR_NOW SMALLINT NOT NULL,

 ID_PLAT INTEGER NOT NULL,

 NUMBER INTEGER NOT NULL,

 ID_REC_PLAT INTEGER,

 ID_POL INTEGER,

 ID_REC_POL INTEGER,

 DATE_NOW DATE,

 DATE_PLAT DATE,

 BALANCE DOUBLE PRECISION,

 OPL_TYPE VARCHAR(6),

 NAZN_TYPE VARCHAR(6),

 KOD_TYPE VARCHAR(6),

 OCH_TYPE VARCHAR(6),

 NAZNACHENIE BLOB,

 PRIMARY KEY (YEAR_NOW, ID_PLAT , NUMBER),

 FOREIGN KEY (ID_PLAT) REFERENCES COMPANYS(ID_NUM),

 FOREIGN KEY (ID_REC_PLAT) REFERENCES REC_COMPANY(ID_NUM),

 FOREIGN KEY (ID_POL) REFERENCES COMPANYS(ID_NUM),

 FOREIGN KEY (ID_REC_POL) REFERENCES REC_COMPANY(ID_NUM)

);

CREATE INDEX PLAT_POR_DATE ON PLAT_POR(YEAR_NOW, ID_PLAT, DATE_NOW);

CREATE INDEX PLAT_POR_YEAR ON PLAT_POR(YEAR_NOW, ID_PLAT , BALANCE);

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

                Рассмотренные нами запросы – это не полный список, который программист должен знать для уверенной работы по созданию баз данных. Вот еще несколько возможностей:

ALTER TABLE /Имя таблицы/

DROP /Имя поля/

                Так удаляют поле таблицы.

ALTER TABLE /Имя таблицы/

ADD /Имя поля, тип, размер, значение по умолчанию, если нужно (см. выше)/

                Так можно добавить поле таблице.

DROP TABLE /Имя таблицы/

                Так можно удалить всю таблицу. На этом, мы закончим. Я думаю, что старт дан, а более подробно Вы познакомитесь с методами создания баз данных из специальной литературы.

 

    Банников Н.А. www.stikriz.narod.ru почта 2000 г.

 

Сайт создан в системе uCoz