我有一个非常大的数据库(在PostgreSQL上运行),其中包含许多表之间具有复杂关系的表(外键,删除级联等)。 我需要从许多表中删除一些数据,但我不确定由于级联删除而会从数据库中真正删除多少数据。
如何检查我是否不会删除不应删除的数据?
我有一个测试数据库 - 只是我可以做我想做的真实副本的一个副本:)
我唯一的想法是在之前和之后转储数据库并检查它。但它看起来并不舒服。 另一个想法 - 转储数据库的一部分,我认为不应该受到DELETE语句的影响,并在数据删除之前和之后检查这部分。但是我认为没有简单的方法可以做到(有数百个表,删除应该可以使用~10个)。有办法吗?
任何其他想法如何解决问题?
答案 0 :(得分:1)
您可以查询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
答案 1 :(得分:1)
使用psql,启动事务,执行删除操作,然后运行您能想到的任何检查查询。然后,您可以回滚或提交。
答案 2 :(得分:0)
如果担心键悬空(即:指向已删除的记录),则在测试数据库上运行删除,然后使用查询查找现在指向无效目标的任何键。 (当你这样做时,你也可以确保不受影响的部分没有改变)
更好的解决方案是花时间绘制删除级联,以便您知道会发生什么 - 了解数据库的工作方式非常有价值,因此花在此上的工作将超出此特定删除范围。
无论你在做出重大改变之前是多么肯定你都支持DB!
答案 3 :(得分:0)
感谢您的回答!
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