写点什么

PostgreSQL 中如何启用 / 禁用及验证外键约束

  • 2021-01-09
  • 本文字数:1106 字

    阅读完需:约 4 分钟

PostgreSQL 中如何启用/禁用及验证外键约束

1 问题提出


近期在做多个数据源 DB 的数据向一个目标 DB 做数据迁移的过程中,遇到有外键约束的表,由于表之间数据的依赖关系和数据的导入顺序导致数据加载失败,因此记录了一下关于这类问题的解决思路。

testa 中 t1 表结构及数据如下:



testb 中 t2 表结构及数据如下:



当恢复数据时,由于数据导入顺序问题,可能会出现违反约束的报错。


比如,首先恢复的 t2 表中数据,此时会有如下的报错:



2 分析问题


这里数据本身并没有问题,只是当时恢复表数据时候首先恢复了 t2 表导致了违反外键约束的报错,此时我们可以首先禁用 t2 表上的外键约束并在加载对其进行验证。



这里 all 会禁用表上的所有外键,同时也禁用负责验证约束的内部触发器,这里使用 all 也存在一些限制,就是你必须是超级用户才能执行此操作,如果是普通用户执行将失败。如果你想要使用普通用户去禁用某一特定用户的用户触发器。



此时,我们再对表 t2 进行数据插入可以成功:



此时,我们首先插入一条违反外键约束的数据,然后将约束条件启用:



此时成功启用约束条件,但是没有报错不符合外键约束!那我再向 t2 插入一次数据,验证约束是否真的生效。



由此可以验证,验证约束的内部触发器已经启用,对于后续新插入或者更新的数据会进行检查。那么对于之前的行,为什么没有进行检查呢?



通过查看系统表 pg_constraint,我们可以看到约束记录的状态为已验证。


3 解决问题


那么我们应该如何处理数据恢复中的外键约束问题并且使新数据和老数据都进行有效性验证呢?


方法 1:删除外键


  • 删除表中的所有外键

  • 加载数据

  • 重新创建外键,但使其无效,以避免增大 cost,现在数据会被验证

  • 当系统功能负载较小时,验证约束



这样的方式,创建无效外键对后续新插入和更新的数据有约束作用,在外键检查时对之前存在的数据可以进行检查,从而保证所有的数据符合外键约束。


方法 2:修改系统表状态


通过上面的测试我们可以知道,在对约束禁用期间,约束记录的状态为已验证,此时我们可以直接更新系统表 pg_constraint。




在这种情况下,这个约束将被完全验证,因为他在系统表中记录为无效。


方法 3:约束延迟生效



这样做的缺点是它仅在一个事务中生效。因此,必须在事务中保证各表之间数据的约束。


4 小结


迁移数据时,如果涉及外键约束的多个表的导入(尤其来自多个数据源,原始数据不一定满足约束关系),灵活启用/禁用及验证外键约束,可使迁移后合并的数据切实满足外键约束,保证 DB 中的关系完整性。



头图:Unsplash

作者:彭占元

原文:https://mp.weixin.qq.com/s/Lom04TPWlSse-hEqRuSV_Q

原文:PostgreSQL 中如何启用/禁用及验证外键约束

来源:Qunar 技术沙龙 - 微信公众号 [ID:QunarTL]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-01-09 23:194971

评论

发布
暂无评论
发现更多内容

读书笔记-MySQL

yunCrush

MySQL

LiteOS:盘点那些重要的数据结构

华为云开发者联盟

源码 数据结构 LiteOS LOS_DL_LIST Priority Queue

从磁盘读取成本分析两种 100% 遍历思路:按格子遍历 & 按线遍历

宫水三叶的刷题日记

面试 LeetCode 数据结构与算法

西北大学研发猴脸识别技术,金丝猴可刷脸打卡;IJCAI 2020丨基于学习实例隐空间的文本风格转换

京东科技开发者

人脸识别 IT 量子通讯

「产品经理训练营」第五章作业

Sòrγy_じò ぴé

产品经理训练营

Fast AI人工智能审图平台-建筑图纸设计效率的倍增器

AI AI审图

《第一财经(月刊2021年02期)》

石云升

读书笔记 28天写作 2月春节不断更 第一财经

教你如何优雅的改写“if-else”

华为云开发者联盟

代码

从架构设计的演进来看,我们真的需要DDD

三石

DDD 软件架构 话题讨论

Java lambda表达式人类使用指南

ES_her0

28天写作

线程池面试必考

叫练

面试 线程池 线程池工作原理

基于simhash的文本去重原理

行者AI

Python hash

一篇学会RSA JavaScript加密,涉及OpenSSL

梁龙先森

JavaScript 大前端 28天写作 2月春节不断更

Java训练营第一周习题:01字节码分析

现实中游走

Java 字节码

趣谈哈希表优化:从规避 Hash 冲突到利⽤ Hash 冲突

百度Geek说

大前端 测试 哈希表 hash 研发工具

1月干货总结:EasyDL上线时序预测模型,文档翻译全新发布

百度大脑

诊所数字化:最大的数据资产-患者数字档案内容

boshi

电子病历 数字化医疗 七日更 28天写作

互联网员工下班时间曝光:所有的光鲜,都有加班的味道

不脱发的程序猿

996 28天写作 二月春节不断更 加班文化 互联网企业

关于GaussDB(DWS)的正则表达式知多少?人人都能看得懂的详解来了!

华为云开发者联盟

正则表达式 GaussDB

话题讨论 | 技术人员的职业发展困惑,你也有么?

架构精进之路

职业规划 话题讨论 28天写作 技术人员

【LeetCode】爱生气的书店老板Java题解

Albert

算法 LeetCode 28天写作 2月春节不断更

日记 2021年2月23日(周二)

Changing Lin

2月春节不断更

架构设计篇之微服务实战笔记(四)

小诚信驿站

架构师 刘晓成 小诚信驿站 28天写作 架构师成长笔记

Selenium 常用方法与属性、鼠标悬停与 Select 操作

梦想橡皮擦

Python 28天写作 2月春节不断更

解决dyld: Library not loaded icu4c

一个大红包

brew icu4c

产业实践推动科技创新,京东科技集团3篇论文入选ICASSP 2021

京东科技开发者

人工智能 机器学习 信号 语音识别

IAR故障解决:由于找不到mfc140u.dll,无法继续执行代码

不脱发的程序猿

28天写作 二月春节不断更 IAR 软件故障 DLL库

使用 RxJS 设计实现一个下载中心功能

laoergege

大前端 RXJS

话题讨论 | 技术从入门到熟练是怎样的?

happlyfox

话题讨论 28天写作

前端面试常考题:JS垃圾回收机制

华为云开发者联盟

JavaScript Vue 大前端 js 垃圾回收

产品经理训练营第四周总结

产品经理训练营

PostgreSQL 中如何启用/禁用及验证外键约束_语言 & 开发_Qunar技术沙龙_InfoQ精选文章