写点什么

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:194309

评论

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

360携手HarmonyOS打造独特的“天气大师”

HarmonyOS开发者

HarmonyOS 应用开发

要把微博、贴吧变成即时聊天,总共分几步?

融云 RongCloud

译文 | 一文看懂技术债

LigaAI

场景应用 技术债务 非功能性需求

“元宇宙”时代,离我们还有多远?

澳鹏Appen

人工智能 大数据 AR vr 元宇宙

患上“远见病”的VR,不得不走进动物世界

脑极体

Camtasia Studio2022激活码序列号

茶色酒

Camtasia Studio2022

恒源云(GPUSHARE)_超越预训练 NLP 的模型来喽

恒源云

自然语言处理 深度学习 算法

在线HTML转JSX工具

入门小站

工具

BabaSSL 发布 8.3.0|实现相应隐私计算的需求

SOFAStack

开源 密码学 隐私计算 国密 BABASSL

刚刚,我们收到了北京冬奥组委的感谢信

阿里巴巴云原生

阿里云 云原生 冬奥会 合作

小程序已成为超级APP必选项,逐鹿私域“留量”

Speedoooo

小程序 APP开发 软件开发、 轻量应用 小程序管理平台

让ICT飞鸟,长出数字能源的翅膀

脑极体

如何在 Linux 中将主目录移动到新分区或磁盘?

Ethereal

如何搭建FAQ文档?只需四步

小炮

企业管理工具

搭建 VuePress 博客,你可能会用到的一些插件

冴羽

Vue 博客 vuepress 博客开发 博客搭建

使用 Recast.AI 创建具有人工智能的聊天机器人

汪子熙

人工智能 机器学习 聊天机器人 CRM 3月月更

实践GoF的23的设计模式:SOLID原则(下)

华为云开发者联盟

设计模式 GoF 依赖倒置原则 接口隔离原则 SOLID原则

44条工程管理经验教训

hongfei

项目管理 3月月更 工程管理 工程经验

三条命令搭建自己的博客平台

山河已无恙

WordPress 3月月更

Linux之route命令

入门小站

Linux

一周信创舆情观察(2.21~2.27)

统小信uos

MySQL数据备份,恢复和验证

wong

MySQL mysqldump

pip手动升级

阿呆

Python pip

AWS S3 对象存储攻防

火线安全

云原生 云安全

企业培训赛道大火,谁能真正解企业人才培训之急?

ToB行业头条

网络安全kali渗透学习 web渗透入门 使用msf扫描靶机上mysql服务的空密码

学神来啦

网络安全 kali kali Linux 运维‘

微信小程序图片拖拽排序探索

云小梦

CSS 微信小程序 图片拖动 movable-area

SpringDataRedis序列化带有双引号

编号94530

redis spring 序列化 Jackson

开发提效小技巧分享(一)

编程三昧

3月月更 前端工具

企业深入使用微服务后会面临哪些问题?云原生全链路灰度给了新思路

阿里巴巴云原生

阿里云 云原生 灰度 云原生微服务 链路

分享几个你可能不知道的交互式Git 命令

华为云开发者联盟

git 交互式暂存 交互式 暂存

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