Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СИСТЕМОТЕХНИЧЕСКОЕ ПРОЕКТИРОВАНИЕ.doc
Скачиваний:
73
Добавлен:
01.05.2014
Размер:
1.47 Mб
Скачать

Ссылочная целостность

Внешние и родительские ключи:

внешний_ключ.<имя>

для

<имя объекта> ; ;

contain

<список атрибутов>; ;

references

<имя объекта> ;

<список атрибутов>

end

В функциональной модели данных информация для поддержания ссылочной целостности косвенно присутствует. Пусть задана спецификация двух атрибутов q1 и q2 , которая задает связи четырех объектов A, B, C и M:

q1(р1 : А, р2 : В) : С;

q2(р1 : А, р2 : В) : М

end

Пусть также задана структура обектов A, B, C и M:

A

own

atr.a1 type t1 ; ; ; a2; ; ;

unique_key.MainA contain a1

end

B

own

atr.b1 type t2 ; ; ; b2; ; ;

unique_key.MainB contain b1

end

C

own

atr.c1 type t3 ; ; ; c2; ; ;

unique_key.MainC contain c1

end

M

own

atr.m1 type t4 ; ; ; m2; ; ;

unique_key.MainM contain m1

end

Если t1, t2, t3, t4 - простые типы, то можно сформировать объект Q, который имеет следующую структуру:

Q

own

atr.p1 type t1 ; ; ; p2 type t2 ; ; ; q1 type t3 ; ; ; q2 type t4 ; ; ; ; ;

unique_key.MainQ contain p1 ; p2

end

В соответствии со спецификацией объектов A, B, C, M и Q для объекта Q должны быть объявлены внешние ключи:

create table Q ( p1 ........., p2 ............., q1 ........., q2 .........,

primary key (p1, p2),

foreign key (p1) references A(a1),

foreign key (p2) references B(b1),

foreign key (q1) references C(c1),

foreign key (q2) references M(m1));

Как видно из приведенного примера использование строгой типизации атрибутов позволяет формально подойти к формированию внешних ключей.

Направленность внешних ключей

Внешний ключ имеет строгую ориентацию от таблицы, в которой он объявляется, к таблице, в которой декларируется родительский ключ (видсвязи 1->1). Обратная связь обычно имеет вид 1->0M. Таким образом внешний ключ задает подчиненность таблиц: родительская таблица является главной, а таблица - владелец внешнего ключа подчиненной.

Родительский ключ - подмножество primary key

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

Внешеий ключ вариант подмножество primary key

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

Анализ вариантов взаимосвязи primary key с несколькими внешними ключами

  • Каждый элемент primary key является внешним ключом

  • Все без одного элементы primary key сотавляют один внешний ключ

  • Несколько (>1) элементов из primary key не являются и не входят в состав внешнего ключа, а оставшиеся являются внешним ключом

  • Ни один из элементов primary key не является и не входит в состав внешнего ключа

Объект, в котором каждый элемент primary key является внешним ключом, отражает свойства, присущие взаимосвязи относительно независимых объектов с соответствующими родительскими ключами.

Объект, в котором n - 1 из n атрибутов primary key сотавляют один внешний ключ, отражает список внутренних элементов родительского объекта с внутренним идентификатором, который задается атрибутом n. Данный вариант взаимосвязи задает декомпозицию элементов объекта с родительскми ключом.

Объект, в котором n -m из n атрибутов primary key сотавляют один внешний ключ, отражает список внутренних элементов родительского объекта с внутренним идентификатором, который задается оставшимися m атрибутами. Данный вариант взаимосвязи, как и предыдущий, задает декомпозицию элементов объекта с родительскми ключом.

Объект, в котором ни один из элементов primary key не является и не входит в состав внешнего ключа, можно назвать базовым (основным).

Ранжирование взаимосвязей

1. Связь объектов по общему родительскому ключу :

2. Связь через внешний ключ, который не является частью primary key (внешняя связь):

Ob external Ob = ((Ob own Atr) and not (Ob primary_key Atr)) Atr type Ob 

 (Ob primary_key Atr) Atr type Ob)t

3. Связь через внешний ключ, который является частью primary key

  • Каждый элемент primary key является внешним ключом (элемент группы) :

Ob com_key Ob = ((Ob primary_key Atr)) Atr type Ob 

 (Ob primary_key Atr) Atr type Ob)t - наличие общих элементов в primary key объектов; (Ob com_key Ob) not  Ob com_key Ob) t

связи объектов через внешние ключи

  • Все без одного элементы primary key сотавляют один внешний ключ (состав)

  • Несколько (>1) элементов из primary key не являются и не входят в состав внешнего ключа, а оставшиеся являются внешним ключом (состав)

Ob own Atr ; Atr type Ob ; Ob primary_key Atr

Наличие функциональной взаимосвязи общего вида:

Ob funct Ob = Ob own Atr Atr type Ob Ob own Atr Atr type Ob)t

Формирование внешних ключей на основе типизации атрибутов и указания первичных ключей объектов.

Указанная информация позволяет сформулировать только необходимые условия для внешних ключей. Рассмотрим пример. Пусть заданы следующие объекты:

Ob.Q1(.... ;A1i : T1; A1i+1 : T2; ... ) , где A1i b A1i+1 не являются элементами первичного ключа;

Ob.Q2(primary_key(A21: T1));

Ob.Q3(primary_key(A31: T2));

Ob.Q4(primary_key(A41: T1; A42: T2)).

Возвожно несколько вариантов объявления внешних ключей для Ob.1 :

1. Q1(... foreign key (A1i) references Q2(A21),

foreign key (A1i) references Q3(A31))

2. Q1(... foreign key (A1i,A1i+1) references Q4(A41, A42))

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

Если допустить у обекта наличие составных атрибутов, то проблемы неоднозначности формирования внешних ключей снимаются. Возвращаясь к примеру переопределим объект Q1 следующим образом:

1. Q1(....; Ai : Q2; Ai+1 : Q3;....);

2. Q1(....; Ai : Q4; ....).

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

Q1(...; Ai : T1; Ai+1 : T2; ...);

table Q1( ... , Ai <базовый тип>, Ai +1 <базовый тип>,

foreign key (A1i) references Q2(A21),

foreign key (A1i+1) references Q3(A31)).

В данном случае внешние ключи формируются на основании первичного ( до подстановки ) определения Q1.

Для второго варианта определения Q1 получим следующее:

Q1(...; Ai : T1; Ai+1 : T2; ...);

table Q1( ... , Ai <базовый тип>, Ai +1 <базовый тип>,

foreign key (A1i, A1i+1) references Q4(A41, A42)).

Для второго варианта правая часть определения внешненго ключа соответствует первичному определению Q1 (до подстановки). Однако левая часть определения требует знания состава полей таблицы, который полностью формируется только после выполнения подстановки.

Рассмотрим на примере случай формирования внешних ключей, являющихся подмножеством первичного ключа.

объект.Проект[Ид_проекта : Код_проекта; ...... primary _key.Pr[Ид_проекта]];

Объект_работы[Ид_объекта : Код_оъекта;

......

primary_key.Pr[Ид_объекта]];

Вид_работа[Ид_работы : Код_работы; ...... primary _key.Pr[Ид_работы]];

Объем_работ;

Подразделение[Ид_подразделения : Код_подразделения, ...... unique_key.Pr[Ид_подразделения]];

Ед_измерения_объема работ

end

Рассмотрим следующий состав атрибутов :

Проекты_для_объекта(Объект : Объект_работы) : Проект;

Структура_объекта(Объект : Объект_работы) : Объект_работы;

Объем_работ_по_смете(По_проекту : Проект,Объект : Объект_работы,

Работа: Вид_работы) : Объем_работ;

Исполнители(По_проекту : Проект,Объект : Объект_работы,

Работа: Вид_работы) : Подразделение;

Объем_выполнения_по_графику(По_проекту : Проект, Объект : Объект_работы,

Работа: Вид_работы, Срок_выполнения : Дата) : Объем_работ;

Проведем преобразования по требованиям нормализации без подстановки базовых типов:

Объект_работы[Ид_объекта : Код_оъекта;

Структура_объекта: Объект_работы;

......

primary_key.Pr[Ид_объекта]]; (1.1)

Сметы[По_проекту : Проект;

Объект : Объект_работы;

Работа: Вид_работы;

Объем_работ_по_смете : Объем_работ;

Исполнители : Подразделение ;

unique_key.Ключ_сметы[По_проекту; Объект ; Работа ]]; (1.2)

График_выполнения[По_смете : Сметы;

Срок_выполнения : Дата;

Объем_выполнения_по_графику : Объем_работ;

unique_key.Ключ_сметы[По_смете; Срок_выполнения ]];

Атрибут Проекты_для_объекта(Объект : Объект_работы) : Проект =

Объем_работ_по_смете(По_проекту , @Объект ); (1.3)

Проведя подстановку первичных ключей с простыми типами по требованиям нормализации получим следующие структуры:

Объект_работы[Ид_объекта : Код_оъекта;

Структура_объекта: Код_объекта;

......

unique_key.Pr[Ид_объекта]]; (2.1)

Сметы[По_проекту : Код_проекта;

Объект : Код_объекта;

Работа: Код_работы;

Объем_работ_по_смете : Объем_работ;

Исполнители : Код_подразделения ;

unique_key.Ключ_сметы[По_проекту; Объект ; Работа ]]; (2.2)

График_выполнения[По_проекту : Код_проекта;

Объект : Код_объекта;

Работа: Код_работы;

Срок_выполнения : Дата;

Объем_выполнения_по_графику : Объем_работ;

unique_key.Ключ_сметы[По_проекту; Объект ;

Работа; Срок_выполнения ]]; (2.3)

По данной спецификации построить однозначно внешние ключи не удасться. Однако предыдущая спецификация (до подстановки атрибутов простых типов) позволит при формировании таблиц однозначно объявить внешние ключи.

В соответствии с приведенными спецификациями создаем следующие реляционные таблицы :

create table

Объект_работы(Ид_объекта integer,

Структура_объекта integer,

......

primary key(Ид_объекта),

foreign key (Структура_объекта) references

Объект_работы(Ид_объекта)); (3.1)

В соответствии со спецификацией (1.1) объект Объект_работы имеет один атрибут сложного типа Структура_объекта: Объект_работы. Поэтому для него объявляется один внешний ключ foreign key (Структура_объекта) references

Объект_работы(Ид_объекта). В состав атрибутов внешнего ключа включен всего один атрибут Структура_объекта, так как при подстановке (спецификация 2.1) количество полей для ссылки не увеличилось (Объект_работы имеет простой первичный ключ).

create table

Сметы(По_проекту integer,

Объект integer,

Работа integer,

Объем_работ_по_смете float,

Исполнители integer,

primary key(По_проекту, Объект, Работа),

foreign key (Объект) references

Объект_работы(Ид_объекта),

foreign key (По_проекту) references

Проект(Ид_проекта));

foreign key (Работа) references

Виды_работ(Ид_работы),

foreign key (Исполнители) references

Подразделения(Ид_работы));

В соответствии со спецификацией (1.2) объект Сметы имеет 4 атрибута сложного типа . Поэтому для него объявляется 4 внешних ключа foreign key . В состав атрибутов каждого внешнего ключа включен всего один атрибут , так как при подстановке (спецификация 2.2) количество полей для ссылки не увеличилось (Объект_работы, Проект, Вид_работы, Подразделение имеют простой первичный ключ).

create table

График_выполнения(По_проекту integer,

Объект integer,

Работа integer,

Срок_выполнения date,

Объем_выполнения_по_графику float,

primary key (По_проекту, Объект ,

Работа, Срок_выполнения),

foreign key (По_проекту, Объект ,Работа) references

Сметы (По_проекту, Объект, Работа));

В соответствии со спецификацией (1.3) объект График_выполнения имеет 1 атрибут сложного типа По_смете : Сметы . Поэтому для него объявляется 1 внешний ключ . В состав атрибутов внешнего ключа включены 3 атрибута , так как при подстановке (спецификация 2.3) количество полей для ссылки увеличилось (объект Сметы имеет сложный первичный ключ).

