Книга: Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Внешние ключи
Внешние ключи
Следующим ограничением, которое часто используется в базах данных InterBase, является ограничение внешнего ключа. Это очень мощное средство для поддержания ссылочной целостности в базе данных, которое позволяет не только контролировать наличие правильных ссылок в базе данных, но и автоматически управлять этими ссылками!
Смысл создания внешнего ключа следующий: если две таблицы служат для хранения взаимосвязанной информации, то необходимо гарантировать, чтобы эта взаимосвязь была всегда корректной. Пример — документ "накладная", содержащий общий заголовок (дата, номер накладной и т. д.) и множество подробных записей (наименование товара, количество и т. д.).
Для хранения такого документа в базе данных создается две таблицы - одна для хранения заголовков накладных, а вторая - для хранения содержимого накладной - записей о товарах и их количестве. Такие таблицы называются главной и подчиненной или таблицей-мастером и деталь-таблицей.
Согласно здравому смыслу невозможно существование содержимого накладной без наличия ее заголовка. Другими словами, мы не можем вставлять записи о товарах, не создав заголовок накладной, а также не можем удалять запись заголовка, если существуют записи о товарах.
Для реализации такого поведения таблица заголовка соединяется с таблицей подробностей с помощью ограничения внешнего ключа.
Давайте рассмотрим смысл наложения ограничений внешнего ключа на примере таблиц, содержащих информацию о накладных.
Для этого создадим две таблицы для хранения накладной - таблицу TITLE для хранения заголовка и таблицу INVENTORY для хранения информации о товарах, входящих в накладную.
CREATE TABLE TITLE(
IDJTITLE INTEGER NOT NULL Primary Key,
DateNakl DATE,
NumNakl INTEGER,
NoteNakl VARCHAR(255));
Обратите внимание на то, что мы сразу определили первичный ключ в таблице заголовка на основе поля ID_TITLE. Остальные поля таблицы TITLE содержат тривиальную информацию о заголовке накладной - дату, номер, примечание.
Теперь определим таблицу для хранения информации о товарах, входящих в накладную:
CREATE TABLE INVENTORY(
ID_INVENTORY INTEGER NOT NULL PRIMARY KEY,
FK_TITLE INTEGER NOT NULL,
ProductName VARCHAR (255),
Kolvo DOUBLE PRECISION,
Positio INTEGER);
Давайте рассмотрим, какие поля входят в таблицу INVENTORY. Во-первых, это ID_INVENTORY - первичный ключ этой таблицы. Затем идет целочисленное поле FK_TITLE, которое служит для ссылки на идентификатор заголовка ID_TITLE в таблице заголовков накладных. Далее идут поля ProductName, Kolvo и Positio. описывающие наименование товара, его количество и позицию в накладной.
Для нашего примера важнее всего поле FK_TITLE. Если мы захотим вывести информацию о товарах определенной накладной, то нам следует воспользоваться следу ющиУ1 запросом, в котором параметр mas_ID_TITLE определяет идентификатор заголовка:
SELECT *
FROM INVENTORY II
WHERE II.FK_TITLE=?mas_ID_TITLE
В сущности, в описываемой ситуации ничто не мешает заполнить таблицу INVENTORY записями, ссылающимися на несуществующие записи в таблице TITEE. Также ничего не препятствует удалению заголовка уже существующей накладной, в результате чего записи о товарах могут стать "бесхозными".
Сервер не будет препятствовать всем этим вставкам и удалениям. Таким образом, контроль за целостностью данных в базе данных полностью возлагается на клиентское приложение. А ведь с одной базой данных могут работать несколько приложений, разрабатываемых, быть может, разными программистами, что может привести к различной интерпретации данных и к ошибкам.
Поэтому необходимо явно наложить ограничение на то, что в таблиц} INVENTORY могут помещаться лишь такие записи о товарах, которые имеют корректною ССЫЛКУ на заголовок накладной. Собственно это и есть ограничение внешнего ключа, которое позволяет вставлять в поля, входящие в ограничения, только те значения, которые есть в другой таблице.
Такое ограничение можно организовать с помощью внешнего ключа. Для данного примера необходимо наложить ограничения внешнего ключа на поле FK_TITLE и связать его с первичным ключом ID_TITLE в TITEE. Добавить внешний ключ в уже существующую таблицу можно следующей командой:
ALTER TABLE INVENTORY
ADD CONSTRAINT fktitlel FOREIGN KEY(FK_TITLE) REFERENCES
TITLE(ID_TITLE)
Часто при добавлении внешнего ключа возникает ошибка object is in use (объект используется) Дело в ю, что для создания внешнею ключа, необходимо открьпь базу данных в монопольном режиме - чтобы оиювременно не бьпо других пользователей Также нетьзя производить никаких обращений к модифицируемой таблице-это может вызвать object is in use
Здесь INVENTORY - имя таблицы, на которую накладывается ограничение внешнего ключа; fktitlel - имя внешнего ключа; FK_TITLE - поля, составляющие внешний ключ; TITLE — имя таблицы, предоставляющей значения (ссылочную ОСНОВУ) для внешнего ключа; ID_TITLE — поля первичного или уникального ключа в таблице TITLE которые являются ссылочной основой для внешнего ключа.
Полный синтаксис ограничения внешнего ключа (с возможностью создавать ограничения на основании нескольких полей) приведен ниже:
<tconstraint> = [CONSTRAINT constraint] FOREIGN KEY ( col [,
col } ) REFERENCES other_table [ ( other__col [ , other_col ...] } ]
[ON DELETE {NO ACTION CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE (NO ACTION|CASCADE|SET DEFAULT SET NULL}]
Как видите, определения содержат большой набор опций. Для начала давайте рассмотрим базовое определение внешнего ключа, которое наиболее часто используется в реальных базах данных, а затем разберем возможные опции.
Чаще всего употребляются декларативная форма ограничения внешнего ключа, когда указывается набор полей (col [, col ...]), которые будут составлять ограничение; таблица other_table, которая содержит в полях [( other_col [, other_col ...]) список возможных значений для внешнего ключа.
Пример такого определения при создании таблицы:
CREATE TABLE Inventory2(
...
FK_TABLE INTEGER NOT NULL CONSTRAINT fkinv REFERENCES
TITLE(ID_TITLE)
...) ;
Обратите внимание, что в этом определении опущены ключевые слова FOREIGN KEY, а также подразумевается, что в качестве внешнего ключа будет использоваться единственное поле - FK_TITLE.
А в следующем примере приведена более полная форма создания внешнего ключа одновременно с таблицей:
CREATE TABLE Inventory2(
...
FK_TABLE INTEGER NOT NULL,
CONSTRAINT fkinv FOREIGN KEY (FKJTABLE) REFERENCES
TITLE(IDJTITLE)
...) ;
- Ссылки на внешние компоновочные блоки
- От исключительной полезности к стратегическому ценообразованию
- 2.2.5. Ключи
- Внешние носители информации
- Как подключить ноутбук к сети Интернет
- Могу ли я изменить или отключить звуки, которые проигрываются при запуске Windows, щелчке кнопкой мыши на папке и т. д.?
- Как записать звук и включить его в звуковую схему Windows?
- Из компьютера иногда раздается резкий звук. Как его отключить?
- Меня подключили к сети. Как в нее входить?
- Как отключить сеть, не выдергивая кабель?
- На сайтах я читаю только текст и не хочу платить за картинки. Как их отключить?
- При запуске Internet Explorer загружается какая-то непонятная страница. Как ее отключить?