Многие СУБД не поддерживают связи "многие-ко-многим" на уровне индексов и ссылочной целостности (см. следующий подраздел), хотя и позволяют реализовывать ее в таблицах неявным образом. Аналогично, мнногие CASE-средства (программы для разработки структуры базы данных в виде диаграмм и генерации на их основе физической базы данных) также нe позволяют определять эту связь между таблицами проектируемой базы даннь1Х. Считается, что всякая связь "многие-ко-многим" может быть заменена на одну или более связь "один-ко-многим". Хотя это так, по мнению автора, целесообразность применения такой связи должна рассматриваться прежде всего в контексте разрабатываемой базы данных и приложения для работы с ней, и там, где это удобно, такая связь должна реализовываться.

1.4.4. Связь между записями одной таблицы

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

Рассмотрим пример. Пусть необходимо в реляционной БД хранить древовидную структуру произвольного уровня, например, структуру организации (рис. 1.10.) В этом случае минимально достаточно таблицы реляционной БД (рис. 1.11), в которой каждому подразделению организации соответствует одна запись. Эта запись ссылается на запись, соответствующую подразделению более высокого уровня, в которое входит данное подразделение. И только в записи о подразделении самого высокого уровня нет подобной ссылки.

Нужно заметить, что автоматическое обеспечение связен записей внутри одной таблицы реляционными СУБД не поддерживается и эти связи нужно реализовывать программно. Несложно заметить, что удаление записи, на которую имеются ссылки (у нас это записи со значением поля "№ подразделения", кроме 4,5,6,8,9,11), должно блокироваться, поскольку в противном случае в таблице будут иметь место ссылки на несуществующие номера подразделений. Также нельзя изменять номера подразделений, на которые имеются ссылки - это разрушит достоверность данных. Такие действия необходимо реализовывать программно. Рассмотренный пример является частным случаем более общей проблемы - обеспечение ссылочной целостности между таблицами базы данных. Речь об этой проблеме пойдет вследующем разделе.

НЕ нашли? Не то? Что вы ищете?

1.5. Ссылочная целостность и каскадные воздействия

Рассмотрим наиболее часто встречающуюся в базах данных связь "один-ко-многим" (рис. 1.12). Как можно заметить, дочерняя и родительская таблицы связаны между собой по общему полю "Товар". Назовем это поле полем связи.

Таблица "Товары" Таблица "Отпуск товаров"

Товар

Ед. изм.

Цена ед.

Товар

Дата

Кол-во, ед.

Сахар

кг

5000

-|->

Сахар

10.01.97

100

Макароны

кг

7000

|->

Сахар

12.01.97

200

Куры

кг

10000

|->

Сахар

14.01.97

50

Фанта

бут. 1 л

6000

Макароны

10.01.97

1000

Макароны

11.01.97

500

Фанта

10.01.97

2000

Фанта

12.01.97

3000

Рис. 1.12. Связанные таблицы базы данных

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

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

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

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

в дочерней таблице "Отпуск товаров" для товара "Рафинад" (таблица "Товары") нет сведений о его отпуске со склада;

• некоторые записи таблицы "Отпуск товаров" содержат сведения об отпуске товара ("Сахар"), о котором нет информации в таблице "Товары".

Товар

Ед. изм.

Цена eд

Товар

Дата

Кол-во, ед.

Рафинад

кг

5

-|->

Сахар

10.01.97

100

Макароны

кг

7000

|->

Сахар

12.01.97

200

Куры

кг

10000

|->

Сахар

14.01.97

50

Фанта

бут.1 л

6000

Макароны

10.01.97

1000

Макароны

11.01.97

500

Фанта

10.01.97

2000

Фанта

12.01.97

3000

Таблица "Товары" Таблица "Отпуск товаров"

Рис. 1.13. Нарушение целостности базы данных - записи с товаром "Сахар" (таблица "Отпуск товаров") не имеют родительской записи

Разберем второй случай. Пусть в одной из записей таблицы "Отпуск товаров" значение поля связи "Сахар" изменилось на "Рафинад" (рис. 1.14). В результате:

• в дочерней таблице "Отпуск товаров" недостоверны сведения об отпуске со склада товара "Сахар" (таблица "Товары");

• одна из записей таблицы "Отпуск товаров" содержит данные об отпуске товара ("Рафинад"), сведения о котором (такие, как единица измерения и цена за единицу) отсутствуют в таблице "Товары". И в первом, и втором случаях мы наблюдаем нарушение целостности базы данных, поскольку информация в ней становится недостоверной. Следовательно, нужно блокировать действия, которые нарушают целостность связей между таблицами, которую называют ссылочной целостностью. Когда говорят о ссылочной целостности, имеют в виду совокупность связей между отдельными таблицами во всей БД. Нарушение хотя бы одной такой связи делает информацию в БД недостоверной.

Таблица "Товары" Таблица "Отпуск товаров"

Товар

ед. изм.

Цена ед.

Товар

Дата

Кол-во, ед.

Сахар

кг

5

-|->

Рафинад

10.01.97

100

Макароны

кг

7000

|->

Сахар

12.01.97

200

Куры

кг

10000

|->

Сахар

14.01.97

50

Фанта

бут.1 л

6000

Макароны

10.01.97

1000

Макароны

11.01.97

500

Фанта

10.01.97

2000

Фанта

12.01.97

3000

Рис. 1.14. Нарушение целостности базы данных - запись с товаром "Рафинад" (таблица "Отпуск товаров ") не имеет родительской записи

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

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

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

• при удалении записи в родительской таблице, следует удалить соответствующие записи в дочерней таблице.

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

Замечание 1. Существует другая разновидность каскадного удаления: при удалении родительской записи в записях дочерних таблиц значения полей связи обнуляются. Эта разновидность применяется редко.

Замечание 2. Обычно занесение записей в дочернюю таблицу осуществляется так: выбирается значение родительской записи (например, из выпадающего списка), значение поля связи фиксируется и затем автоматически заносится в поля связи дочерних записей. Метод, когда пользователь вручную заносит значения полей связи в дочерние записи, непопулярен: пользователь может внести одинаковое по смыслу, но разное по написанию значение ("Сахар", "сахар"). Много реже практикуется способ ввода дочерних записей без указания значения поля связи. Затем записи родительской и дочерних таблиц "связываются".

Каскадные изменения могут блокироваться: или одновременно изменения и удаления, или изменения или удаления по отдельности. Необходимость разрешения или запрещения каскадных изменений обычно реализуется в СУБД при определении связей между таблицами. Собственно, таким образом и происходит создание ссылочной целостности. Обычно в СУБД для реализации ссылочной целостности в дочерней таблице создают внешний ключ (см. ниже), ссылающийся на родительскую таблицу, и указывают вид каскадных

воздействий. В последующем СУБД сама при необходимости реализует каскадные воздействия данного вида для указанных таблиц.

1.6. Понятие внешнего ключа

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

1.7. Индексы и методы доступа

Порядковый № записи

Дата прихода товара

Наименование товара

Количество,

1

10.01.1997

Сахар

10

2

12.01.1997

Картофель

50

3

12.01.1997

Свекла

20

4

14.01.1997

Сахар

50

5

14.01.1997

Свекла

10

6

16.01.1997

Сливы

4

Рис. 1.15. Физическая структура таблицы

Индексы представляют собой механизмы быстрого доступа к данным в таблицах БД.

Сущность индексов состоит в том, что они хранят значения индексных полей (т. е. полей, по которым построен индекс) и указатель на запись в таблице. Например, если имеется таблица (рис. 1.15.), то с логической точки зрения индексы выглядят так (рис. 1.16):

По дате прихода товара

По наименованию товара

По количеству

Дата прихода

№ записи

Товар

№ записи

Количество.

№ записи

10.01.1997

1

Картофель

2

4

6

12.01.1997

2

Сахар

1

10

1

12.01.1997

3

Сахар

3

10

5

14.01.1997

4

Свекла

3

20

3

14.01.1997

5

Свекла

5

50

2

16.01.1997

6

Сливы

6

50

4

РисЛогическая структура индексов

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3