ВНЕШНИЕ КЛЮЧИ КОТОРЫЕ ССЫЛАЮТСЯ ОБРАТНО К ИХ ПОДЧИНЕННЫМ ТАБЛИЦАМ
Как было упомянуто ранее, ограничение FOREIGN KEY может представить
им этой частной таблице, как таблицы родительского ключа. Далеко не бу-
дучи простой, эта особенность может пригодиться. Предположим, что мы
имеем таблицу Employees с полем manager(администратор). Это поле содер-
жит номера каждого из служащих, некоторые из которых являются еще и ад-
министраторами.
Но так как каждый администратор - в то же врем остается служащим, то
он естественно будут также представлен в этой таблице. Давайте создадим
таблицу, где номер служащего ( столбец с именем empno ), объявляется как
первичный ключ, а администратор, как внешний ключ, будет ссылаться
на нее:
CREATE TABLE Employees
(empno integer NOT NULL PRIMARY KEY,
name char(10) NOT NULL UNIOUE,
manager integer REFERENCES Employees);
( Так как внешний ключ это ссылаемый первичный ключ таблицы, список
столбцов может быть исключен. ) Имеется содержание этой таблицы:
EMPNO NAME MANAGER
_____ ________ _______
1003 Terrence 2007
2007 Atali NULL
1688 McKenna 1003
2002 Collier 2007
Как вы можете видеть, каждый из них( но не Atali ) , ссылается на другого
служащего в таблице как на своего администратора. Atali, имеющий наивысший номер в таблице, должен иметь значение установленное в NULL.
Это дает другой принцип справочной целостности. Внешний ключ, который
ссылается обратно к частной таблице, должен позволять значения = NULL.
Если это не так, как бы вы могли вставить первую строку ?
Даже если эта первая строка ссылается к себе самой, значение родительского
ключа должно уже быть установлено, когда вводится значение внешнего клю-
ча. Этот принцип будет верен, даже если внешний ключ ссылается обратно к
частной таблице не напрямую а с помощью ссылки к другой таблице, которая
затем ссылается обратно к таблице внешнего ключа. Например, предположим,
что наша таблица Продавцов имеет дополнительное поле которое ссылается на
таблицу Заказчиков, так, что каждая таблица ссылается на другую, как показано
в следующем операторе CREATE TABLE:
CREATE TABLE Salespeople
(snum integer NOT NULL PRIMARY KEY,
sname char(10) NOT NULL,
city char(10),
comm declmal,
cnum integer REFERENCES Customers);
CREATE TABLE Customers
(cnum integer NOT NULL PRIMARY KEY,
cname char(10) NOT NULL,
city char(10),
rating integer,
snum integer REFERENCES Salespeople);
Это называется - перекрестной ссылкой.
SQL поддерживает это теоретически, но практически это может составить
проблему. Люба таблица из этих двух, созданная первой является ссылоч-
ной таблицей которая еще не существует для другой. В интересах обеспечения перекрестной ссылки, SQL фактически позволяет это, но никакая таблица не будет пригодна для использования пока они обе находятся в процессе
создания. С другой стороны, если эти две таблицы создаются различными
пользователями, проблема становится еще более трудной.
Перекрестна ссылка может стать полезным инструментом, но она не без
неоднозначности и опасностей. Предшествующий пример, например, не сов-
сем пригоден для использования: потому что он ограничивает продавца оди-
ночным заказчиком, и кроме того совсем необязательно использовать перекрестную ссылку чтобы достичь этого. Мы рекомендуем чтобы вы были осторожны в его использовании и анализировали, как ваши программы управ-
лют эффектами модификации и удаления а также процессами привилегий
и диалоговой обработки запросов перед тем как вы создаете перекрестную
систему справочной целостности.
( Привилегии и диалоговая обработка запросов будут обсуждаться, соответственно, в