Нетривиальное использование таблиц
Добавление ограничений в существующую таблицу
Команда ALTER TABLE позволяет включать ограничения в существующую таблицу. Впрочем, в PostgreSQL 7.1.x поддерживается только возможность добавления ограничений CHECK и FOREIGN KEY.
Установка ограничений в команде ALTER TABLE имеет следующий синтаксис:
ALTER TABLE таблица ADD [ CONSTRAINT ограничение ] { CHECK (условие) | FOREIGN KEY (поле […. ]) REFERENCES таблица [ (поле [….])] [ MATCH FULL | MATCH PARTIAL ] [ ON DELETE операция ] [ ON UPDATE операция ] [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED INITIALLY IMMEDIATE ] }
В листинге 7.9 устанавливается новое ограничение FOREIGN KEY для поля subjected, которое связывается с полем id таблицы subjects. Ограничение гарантирует, что в результате вставки или обновления данных в поле subjected таблицы books не появятся значения, отсутствующие в поле id таблицы subjects.
Листинг 7.9. Добавление ограничений в существующую таблицу.
booktown=# ALTER TABLE books booktown-# ADD CONSTRAINT legal_subjects booktown-# FOREIGN KEY (subjectjd) booktown-# REFERENCES subjects (id); NOTICE: ALTER TABLE… ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) CREATE
Удаление ограничений
В PostgreSQL 7.1.x не поддерживается прямое удаление ограничений из таблицы. Добиться нужного результата можно лишь одним способом – создать копию таблицы, практически полностью повторяющую оригинал, но не содержащую удаляемых ограничений. Данные копируются из исходной таблицы в новую, после чего таблицы переименовываются командой ALTER TABLE и копия заменяет оригинал.
Внимание
Применяя этот прием, следует учитывать, что кто-то из пользователей может подключиться к базе данных и работать с модифицируемыми таблицами. Вставка или любые модификации данных в процессе копирования недопустимы; таким образом, если таблица активно используется, вы можете временно запретить подключения к PostgreSQL, внести необходимые изменения и перезапустить систему.
В листинге 7.10 снятие ограничений продемонстрировано на примере ограничения FOREIGN KEY с именем legal_subjects, установленного для таблицы books (см. листинг 7.9). Обратите внимание на удаление индекса books_1d_pkey перед созданием новой таблицы, что позволяет создать таблицу с индексом books_id_pkey. На самом деле это не обязательно, но имя индекса первичного ключа лучше сохранить.
Листинг 7.10. Удаление ограничений.
booktown=*# DROP INDEX books_id_pkey; DROP booktown=# CREATE TABLE new_books booktown-# (id integer CONSTRAINT books_id_pkey PRIMARY KEY. booktown(# title text NOT NULL. booktown(# author_id integer. booktown(# subjected integer): NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'books_id_pkey' for table 'new_books' CREATE booktown=# INSERT INTO new_books SELECT * FROM books: INSERT 0 15 booktown=f ALTER TABLE books RENAME TO old_books: ALTER booktown=# ALTER TABLE new_books RENAME TO books; ALTER