Каскадные удаления в PostgreSQL - PullRequest
5 голосов
/ 05 сентября 2008

У меня есть база данных с несколькими десятками таблиц, связанных внешними ключами. При нормальных обстоятельствах я хочу поведение по умолчанию ON DELETE RESTRICT для этих ограничений. Но при попытке поделиться снимком базы данных с консультантом, мне нужно было удалить некоторые конфиденциальные данные. Я бы хотел, чтобы моя память о команде DELETE FROM Table CASCADE не была чистой галлюцинацией.

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

У кого-нибудь есть лучшее решение в следующий раз, когда появится что-то подобное?

Ответы [ 7 ]

4 голосов
/ 01 октября 2008

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

CREATE TABLE "header"
(
  header_id serial NOT NULL,
  CONSTRAINT header_pkey PRIMARY KEY (header_id)
);

CREATE TABLE detail
(
  header_id integer,
  stuff text,
  CONSTRAINT detail_header_id_fkey FOREIGN KEY (header_id)
      REFERENCES "header" (header_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);
insert into header values(1);
insert into detail values(1,'stuff');
delete from header where header_id=1;
alter table detail drop constraint detail_header_id_fkey;
alter table detail add constraint detail_header_id_fkey FOREIGN KEY (header_id)
      REFERENCES "header" (header_id) on delete cascade;
delete from header where header_id=1;
alter table detail add constraint detail_header_id_fkey FOREIGN KEY (header_id)
      REFERENCES "header" (header_id) on delete restrict;
1 голос
/ 10 июня 2010
TRUNCATE table CASCADE;

Я новичок в Postgres, поэтому я не уверен, какой компромисс для TRUNCATE vs. DROP.

1 голос
/ 01 октября 2008

Вы можете создать ограничения внешнего ключа как DEFERRABLE. Тогда вы сможете временно отключить их во время очистки данных и повторно включить их, когда закончите. Посмотрите на этот вопрос .

0 голосов
/ 23 июля 2010

TRUNCATE просто удаляет данные из таблицы и оставляет структуру

0 голосов
/ 11 сентября 2008

Не думаю, что вам нужно обрабатывать файл дампа таким образом. Выполните потоковый дамп / восстановление и обработайте его. Что-то вроде:

createdb -h scratchserver scratchdb
createdb -h scratchserver sanitizeddb

pg_dump -h liveserver livedb --schema-only | psql -h scratchserver sanitizeddb
pg_dump -h scratchserver sanitizeddb | sed -e "s/RESTRICT/CASCADE/" | psql -h scratchserver scratchdb

pg_dump -h liveserver livedb --data-only | psql -h scratchserver scratchdb
psql -h scrachserver scratchdb -f delete-sensitive.sql

pg_dump -h scratchserver scratchdb --data-only | psql -h scratchserver sanitizeddb
pg_dump -Fc -Z9 -h scratchserver sanitizedb > sanitizeddb.pgdump

, где вы храните все ваши DELETE sqls в delete-sens.sql. Базу данных / шаги sanitizeddb можно удалить, если вы не против того, чтобы консультант получил БД с внешними ключами CASCADE вместо внешних ключей RESTRICT.

Могут также быть более эффективные способы в зависимости от того, как часто вам нужно это делать, насколько велика база данных и какой процент данных является конфиденциальным, но я не могу придумать более простой способ сделать это один раз или дважды для базы данных разумного размера . В конце концов вам понадобится другая база данных, поэтому, если у вас нет кластера slony, вы не сможете избежать цикла дамп / восстановления, который может занять много времени.

0 голосов
/ 06 сентября 2008

@ Тони: Нет, схемы могут быть полезны, и мы действительно используем их для разделения данных в нашей базе данных. Но я говорю о попытке очистки конфиденциальных данных, прежде чем дать консультанту копию БД. Я хочу, чтобы эти данные исчезли.

0 голосов
/ 05 сентября 2008

Возможно, вы захотите использовать схемы с PostgreSQL. Я делал это в прошлых проектах, чтобы разные группы людей или разработчики могли иметь свои собственные данные. Затем вы можете использовать свои сценарии для создания нескольких копий базы данных именно для таких ситуаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...