Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
db_lectures / 06. Изменение таблиц. Ограничения целостности.docx
Скачиваний:
79
Добавлен:
21.05.2015
Размер:
23.27 Кб
Скачать

Ссылочная целостность

Мы знаем, что внешние ключи запрещают создание строк в orders, которые не относятся к какому-либо существующему товару. Но если нужно удалить товар из таблицы products после того как в orders создана запись, которая ссылается на него? SQL позволяет вам управлять возможными действиями в этой ситуации. Напрашивается несколько вариантов:

  • Запретить удаление ссылочного продукта

  • Всё-равно удалить строку

  • Что-то другое?

Чтобы проиллюстрировать это, реализуем следующую политику отношения многим-ко-многим в предыдущем примере: когда кто-то хочет удалить товар, на который ссылается строка в таблице orders (через order_items), мы запрещаем это. Если кто-то удаляет строку в orders, элменты в order_items также удаляются.

CREATE TABLE order_items (

product_no integer REFERENCES products ON DELETE RESTRICT,

order_id integer REFERENCES orders ON DELETE CASCADE,

quantity integer,

PRIMARY KEY (product_no, order_id)

);

При использовании этого предложения система отклонит выполнение любых операторов INSERT или UPDATE, с помощью которых будет предпринята попытка создать в дочерней таблице значение внешнего ключа, не соответствующее одному из уже существующих значений потенциального ключа родительской таблицы. Когда действия системы выполняются при поступлении операторов UPDATE и DELETE, содержащих попытку обновить или удалить значение потенциального ключа в родительской таблице, которому соответствует одна или более строк дочерней таблицы, то они зависят от правил поддержки ссылочной целостности, указанных во фразах ON UPDATE и ON DELETE предложения FOREIGN KEY. Язык SQL предоставляет следующие возможности:

RESTRICT предотвращает удаление ссылочной строки.

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

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

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

NO ACTION - операция удаления строки из родительской таблицы отменяется. Именно это значение используется по умолчанию в тех случаях, когда в описании внешнего ключа фраза ON DELETE опущена. Важнейшее различие между этими двумя альтернативами состоит в том, что NO ACTION позволяет отложить проверку до окончания транзакции, а RESTRICT нет.

В завершении, мы должны отметить, что внешний ключ должен ссылаться на колонки, которые либо являются первичным ключом, либо формой ограничения уникальности. Если внешний ключ ссылается на ограничение уникальности, то необходимо обратить внимание на некоторые дополнительные вещи, такие как совпадение со значениями null. Об этом рассказывается в справочной документации CREATE TABLE.

Изменение таблиц

Если при создании таблицы допущены ошибки или требования приложения изменились, можно удалить эту таблицу и создать её заново, но если таблица уже содержит данные или если на таблицу ссылаются другие объекты базы данных (например, внешний ключ), это неудобно. Поэтому существует набор команд для внесения изменений в существующие таблицы. Заметим, что эти действия концептуально отличаются от изменений самих данных, содержащихся в таблице: здесь мы говорим о изменении структуры таблицы.

Все эти действия выполняются с помощью команды ALTER TABLE, на странице описания которой, можно найти подробности перечисленных здесь действий.

ALTER TABLE [ ONLY ] name [ * ]

action [, ... ]

ALTER TABLE [ ONLY ] name [ * ]

RENAME [ COLUMN ] column TO new_column

ALTER TABLE name

RENAME TO new_name

ALTER TABLE name

SET SCHEMA new_schema

Где action:

ADD [ COLUMN ] column type [ column_constraint [ ... ] ]

DROP [ COLUMN ] column [ RESTRICT | CASCADE ]

ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ]

ALTER [ COLUMN ] column SET DEFAULT expression

ALTER [ COLUMN ] column DROP DEFAULT

ALTER [ COLUMN ] column { SET | DROP } NOT NULL

ALTER [ COLUMN ] column SET STATISTICS integer

ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }

ADD table_constraint

DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]

DISABLE TRIGGER [ trigger_name | ALL | USER ]

ENABLE TRIGGER [ trigger_name | ALL | USER ]

ENABLE REPLICA TRIGGER trigger_name

ENABLE ALWAYS TRIGGER trigger_name

DISABLE RULE rewrite_rule_name

ENABLE RULE rewrite_rule_name

ENABLE REPLICA RULE rewrite_rule_name

ENABLE ALWAYS RULE rewrite_rule_name

CLUSTER ON index_name

SET WITHOUT CLUSTER

SET WITH OIDS

SET WITHOUT OIDS

SET ( storage_parameter = value [, ... ] )

RESET ( storage_parameter [, ... ] )

INHERIT parent_table

NO INHERIT parent_table

OWNER TO new_owner

SET TABLESPACE new_tablespace