Понимание SQL
Шрифт:
МНОГО-СТОЛБЦОВЫЕ ВНЕШНИЕ КЛЮЧИ
В действительности, внешний ключ не обязательно состоит только из одного поля. Подобно первичному ключу, внешний ключ может иметь любое число полей, которые все обрабатываются как единый модуль. Внешний ключ и родительский ключ на который он ссылается, конечно же, должны иметь одинаковый номер и тип поля, и находиться в одинаковом порядке.
Внешние ключи состоящие из одного поля - те что мы использовали исключительно в наших типовых таблицах, наиболее общие. Чтобы сохранить простоту нашего обсуждения, мы будем часто говорить о внешнем ключе как об одиночном столбце. Это не случайно.
Когда поле - является внешним ключом, оно определеным образом связано с таблицей на которую он ссылается. Вы, фактически, говорите - "каждое значение в этом поле (внешнем ключе ) непосредственно привязано к значению в другом поле (родительском ключе )." Каждое значение (каждая строка ) внешнего ключа должно недвусмысленно ссылаться к одному и только этому значению (строке) родительского ключа. Если это так, то фактически ваша система, как говорится, будет в состоянии справочной целостности.
Вы можете увидеть это на примере. Внешний ключ snum в таблице Заказчиков имеет значение 1001 для строк Hoffman и Clemens. Предположим что мы имели две строки в таблице Продавцов со значением в поле snum=1001. Как мы узнаем, к которому из двух продавцов были назначены заказчики Hoffman и Clemens ? Аналогично, если нет никаких таких строк в таблице Продавцов, мы получим Hoffman и Clemens назначенными к продавцу которого не существует!
Понятно, что каждое значение во внешнем ключе должно быть представлено один, и только один раз, в родительском ключе.
Фактически, данное значение внешнего ключа может ссылаться только к одному значению родительского ключа не предполагая обратной возможности: т.е. любое число внешних ключей может ссылать к единственному значению родительского ключа. Вы можете увидеть это в типовых таблицах наших примеров. И Hoffman и Clemens назначены к Peel, так что оба их значения внешнего ключа совпадают с одним и тем же родительским ключом, что очень хорошо. Значение внешнего ключа должно ссылаться только к одному значению родительского ключа, зато значение родительского ключа может ссылаться с помощью любого колличества значений внешнего ключа. В качестве иллюстрации, значения внешнего ключа из таблицы Заказчиков, совпавшие с их родительским ключом в Продавцов таблице, показываются на Рисунке 19.1. Для удобства мы не учитывали поля не относящиеся к этому примеру.
SQL поддерживает справочную целостность с ограничением FOREIGN KEY.
Хотя ограничение FOREIGN KEY - это новая особенность в SQL, оно еще не обеспечивает его универсальности. Кроме того, некоторые его реализации, более сложны чем другие. Эта функция должна ограничивать значения которые вы можете ввести в вашу базу данных чтобы заставить внешний ключ и родительский ключ соответствовать принципу справочной целостности. Одно из действий ограничения Внешнего Ключа - это отбрасывание значений для полей ограниченных как внешний ключ который еще не представлен в родительском ключе. Это ограничение также воздействует на вашу способность изменять или удалять значения родительского ключа (мы будем обсуждать это позже в этой главе ).
Вы используете ограничение FOREIGN KEY в команде CREATE TABLE (или ALTER TABLE ), которая содержит поле которое вы хотите обьявить внешним ключом. Вы даете имя родительскому ключу на которое вы будете ссылаться внутри ограничения FOREIGN KEY. Помещение этого ограничения в команду - такое же что в для других ограничений обсужденных в предыдущей главе.
{}
Рисунок 19.1: Внешний Ключ таблицы Заказчиков с родительским ключом
Подобно большинству ограничений, оно может быть ограничением таблицы или столбца, в форме таблицы позволяющей использовать многочисленые поля как один внешний ключ.
Синтаксис ограничения таблицы FOREIGN KEY:
FOREIGN KEY <column list> REFERENCES
<pktable> [ <column list> ]
Первый список столбцов - это список из одного или более столбцов таблицы, которые отделены запятыми и будут созданы или изменены этой командой. Pktable - это таблица содержащая родительский ключ. Она может быть таблицей, которая создается или изменяется текущей командой.
Второй список столбцов - это список столбцов которые будут составлять родительский ключ. Списки двух столбцов должны быть совместимы, т.е.:
* Они должны иметь одинаковое число столбцов.
* В данной последовательности, первый, второй, третий, и т.д., столбцы списка столбцов внешнего ключа, должны иметь одинаковые типы данных и размеры, что и первый, второй, третий, и т.д., столбцы списка столбцов родительского ключа. Столбцы в списках обоих столбцов не должны иметь одинаковых имен, хотя мы и использовали такой способ в наших примерах чтобы делать связь более понятной.
Создадим таблицу Заказчиков с полем snum определенным в качестве внешнего ключа ссылающегося на таблицу Продавцов:
CREATE TABLE Customers
( cnum integer NOT NULL PRIMARY KEY
cname char(10),
city char(10),
snum integer,
FOREIGN KEY (snum) REFERENCES Salespeople
( snum );
Имейте в виду, что при использовании ALTER TABLE вместо CREATE TABLE, для применения ограничения FOREIGN KEY, значения которые Вы указываете во внешнем ключе и родительском ключе, должны быть в состоянии справочной целостности. Иначе команда будет отклонена. Хотя ALTER TABLE очень полезна из-за ее удобства, вы должны будете в вашей системе, по возможности каждый раз, сначала формировать структурные принципы, типа справочной целостности.
Вариант ограничения столбца ограничением FOREIGN KEY - по другому называется - ссылочное ограничение (REFERENCES), так как он фактически не содержит в себе слов FOREIGN KEY, а просто использует слово REFERENCES, и далее имя родительского ключа, подобно этому:
CREATE TABLE Customers
( cnum integer NOT NULL PRIMARY KEY,
cname char(10),
city char(10),
snum integer REFERENCES Salespeople (snum));