Когда вы создаете сложные структуры базы данных, включающие множество таблиц с ограничениями внешнего ключа, представлениями, триггерами, функциями и т. д., вы неявно создаете сеть зависимостей между объектами. Например, таблица с ограничением внешнего ключа зависит от таблицы, на которую она ссылается.
Чтобы обеспечить целостность всей структуры базы данных, PostgreSQL гарантирует, что вы не сможете удалить объекты, от которых все еще зависят другие объекты. Например, попытка удалить таблицу products, с зависящей от нее таблицей заказов, приведет к следующему сообщению об ошибке:
DROP TABLE products;
ERROR: cannot drop table products because other objects depend on it
DETAIL: constraint orders_product_no_fkey on table orders depends on table products
HINT: Use DROP ... CASCADE to drop the dependent objects too.
Сообщение об ошибке содержит полезную подсказку: если вы не хотите удалять все зависимые объекты по отдельности, вы можете запустить:
DROP TABLE products CASCADE;
и все зависимые объекты будут удалены рекурсивно, как и любые объекты, зависящие от них. В этом случае он не удаляет таблицу заказов, он удаляет только ограничение внешнего ключа. На этом он останавливается, потому что от ограничения внешнего ключа ничего не зависит. (Если вы хотите проверить, что DROP ... CASCADE
будет делать, запустите DROP
без CASCADE
него и прочитайте DETAIL
вывод.)
Почти все DROP
команды в PostgreSQL поддерживают указание CASCADE
. Конечно, характер возможных зависимостей зависит от типа объекта. Вы также можете написать RESTRICT
вместо, CASCADE
чтобы получить поведение по умолчанию, то есть предотвратить удаление объектов, от которых зависят любые другие объекты.
Если DROP
команда перечисляет несколько объектов, CASCADE
требуется только при наличии зависимостей за пределами указанной группы. Например, если говорить DROP TABLE tab1, tab2
о существовании ссылки на внешний ключ tab1
, tab2
это не означает, что CASCADE
это необходимо для успеха.
Для определяемых пользователем функций PostgreSQL отслеживает зависимости, связанные с видимыми извне свойствами функции, такими как ее аргументы и типы результатов, но не зависимости, которые можно узнать, только изучив тело функции. В качестве примера рассмотрим такую ситуацию:
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
'green', 'blue', 'purple');
CREATE TABLE my_colors (color rainbow, note text);
CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
'SELECT note FROM my_colors WHERE color = $1'
LANGUAGE SQL;
PostgreSQL будет знать, что get_color_note
функция зависит от rainbow
типа: удаление типа приведет к принудительному удалению функции, потому что ее тип аргумента больше не будет определен. Но PostgreSQL не будет считать get_color_note
, что зависит от my_colors
таблицы, и поэтому не удалит функцию, если таблица будет удалена. Хотя у этого подхода есть недостатки, есть и преимущества. Функция все еще действительна в некотором смысле, если таблица отсутствует, хотя ее выполнение вызовет ошибку; создание новой таблицы с тем же именем позволит функции снова работать.
0 комментариев