Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Реализация ограничения

Реализация ограничения

При реализации ссылочного ограничения должны быть учтены некоторые предварительные условия. В этом разделе мы рассмотрим очень простой пример. Если вы выполняете разработку в существующем сложном окружении, где действуют привилегии SQL, то вам следует позаботиться о получении привилегии REFERENCES. Об этом сказано в отдельном разделе далее в этой главе.

Родительская структура

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

CREATE TABLE PARENT (

ID BIGINT NOT NULL,

DATA VARCHAR(20),

CONSTRAINT PK_PARENT PRIMARY KEY(ID));

COMMIT;

Дочерняя структура

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

CREATE TABLE CHILD (

ID BIGINT NOT NULL,

CHILD_DATA VARCHAR(20),

PARENT_ID BIGINT,

CONSTRAINT PK_CHILD PRIMARY KEY(ID));

COMMIT;

Следующее, что нам нужно сделать, это определить отношение между дочерней и родительской таблицами - создать ограничение внешнего ключа.

Синтаксис определения FOREIGN KEY

Синтаксис определения ссылочной целостности следующий:

FOREIGN KEY (столбец [, столбец ...])

REFERENCES (родительская-таблица [, столбец ...])

[USING [ASC | DESC] INDEX имя-индекса] /* добавлено в версии 1.5 */

[ON DELETE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}]

[ON UPDATE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}]

Определим наш внешний ключ:

ALTER TABLE CHILD

ADD CONSTRAINT FK_CHILD_PARENT

FOREIGN KEY(PARENT_ID)

REFERENCES PARENT(ID);

/* также допустимо REFERENCES PARENT, поскольку ID является первичным ключом таблицы PARENT */

Firebird сохраняет ограничение FK_CHILD_PARENT и создает обычный индекс для столбца (столбцов), перечисленных в качестве аргументов FOREIGN KEY. В Firebird этот индекс будет также назван FK_CHILD_PARENT, если вы не использовали необязательное предложение USING для задания другого имени индекса. В Firebird 1.0.x индекс будет иметь имя INTEG_NN (где NN - некоторое число).

! ! !

ВНИМАНИЕ! Если вы указали убывающий индекс для ограничения первичного или уникального ключа, вы также должны указать USING DESCENDING INDEX для каждого ссылающегося на него внешнего ключа.

. ! .

Наши две таблицы теперь связаны огpаничением формальной ссылочной целостности. Мы можем добавлять новые строки в таблицу PARENT без каких-либо огpаничений:

INSERT INTO PARENT (ID, DATA)

VALUES (1, 'Pareпt No, 1');

При этом существует ограничение для CНILD. Мы можем выполнить следующее:

INSERT INTO CHILD (ID, CHILD_DATA)

VALUES (1, 'Child No. 1');

Поскольку допускающий пустое значение столбец PARENT_ID отсутствует в списке столбцов, в нем будет сохранено значение NULL. Это допускается правилами целостности по умолчанию. Такая строка будет зависшей (или осиротевшей, orphan).

Однако мы получим ошибку ограничения, если попытаемся сделать следующее:

INSERT INTO CHILD(ID, CHILD_DATA, PARENT_ID)

VALUES (2, 'child No, 2', 2);

ISC ERROR CODE:335544466

ISC ERROR MESSAGE:

violation of FOREIGN KEY constraint "FK_CHILD_PARENT" on table "CHILD" (нарушение ограничения "FK_CHILD_PARENT" для внешнего ключа таблицы CHILD)

В таблице PARENT не существует строки, имеющей у первичного ключа значение 2, следовательно, ограничение не позволит выполнить добавление.

Оба следующих действия допустимы:

UPDATE CHILD

SET PARENT_ID = 1

WHERE ID = 1;

COMMIT;

/**/

INSERT INTO CHILD (ID, CHILD_DATA, PARENT_ID)

VALUES (2, 'Child No.2', 1) ;

COMMIT;

Теперь строка из PARENT со значением ID = 1 имеет две дочерние строки. Это классическая структура главная-подчиненная - простая реализация отношения один-ко- многим. Для защиты целостности данного отношения правила по умолчанию не позволят выполнить следующее:

DELETE FROM PARENT WHERE ID = 1;

Оглавление книги


Генерация: 0.101. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз