我有一个非常大的数据库(在PostgreSQL上运行),其中包含许多表之间具有复杂关系的表(外键,删除级联等)。 我需要从许多表中删除一些数据,但我不确定由于级联删除而会从数据库中真正删除多少数据。

如何检查我是否不会删除不应删除的数据?

我有一个测试数据库 - 只是我可以做我想做的真实副本的一个副本:)

我唯一的想法是在之前和之后转储数据库并检查它。但它看起来并不舒服。 另一个想法 - 转储数据库的一部分,我认为不应该受到DELETE语句的影响,并在数据删除之前和之后检查这部分。但是我认为没有简单的方法可以做到(有数百个表,删除应该可以使用~10个)。有办法吗?

任何其他想法如何解决问题?

有帮助吗?

解决方案

您可以查询information_schema,以便自己绘制有关如何在数据库中定义约束的图片。然后你会知道删除时会发生什么。这不仅对这种情况有用,而且总是有用的。

类似(用于约束)

select table_catalog,table_schema,table_name,column_name,rc.* from
information_schema.constraint_column_usage ccu, 
information_schema.referential_constraints rc 
where ccu.constraint_name = rc.constraint_name

其他提示

使用psql,启动事务,执行删除操作,然后运行您能想到的任何检查查询。然后,您可以回滚或提交。

如果担心键悬空(即:指向已删除的记录),则在测试数据库上运行删除,然后使用查询查找现在指向无效目标的任何键。 (当你这样做时,你也可以确保应该不受影响的部分没有改变)

更好的解决方案是花时间绘制删除级联,以便您知道会发生什么 - 了解数据库的工作方式非常有价值,因此花在此上的工作将超出此特定删除范围。

无论你在做出重大改变之前是多么肯定你都支持DB!

感谢您的回答!

Vinko,你的回答对我非常有用,我会研究它。

实际上,对于我的情况,只需比较记录删除前后的表计数,并检查哪些表受其影响。

它是通过下面描述的简单命令完成的

psql -U U_NAME -h`hostname` -c '\d' | awk '{print $3}' > tables.list

for i in `cat tables.list `; do echo -n "$i: " >> tables.counts; psql -U U_NAME -h`hostname` -t -c "select count(*) from $i" >> tables.counts; done

for i in `cat tables.list `; do echo -n "$i: " >> tables.counts2; psql -U U_NAME -h`hostname` -t -c "select count(*) from $i" >> tables.counts2; done

diff tables.counts tables.counts2
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top