写点什么

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

评论

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

封装一个koa分布式锁中间件来解决幂等或重复请求的问题

程序知音

编程 程序员 后端

大话云原生之负载均衡篇-小饭馆客流量变大了

字母哥哥

Docker 负载均衡 云原生

Web侧防御指南

穿过生命散发芬芳

7月月更 Web防护

linux-riscv-5.17 纯净源码

贾献华

7月月更

最全SQL与NoSQL优缺点对比

雨果

sql NoSQL 数据库

Web2.0的巨头纷纷布局VC,Tiger DAO VC或成抵达Web3捷径

股市老人

scrcpy这款软件解决了和同事分享手机屏幕的问题| 社区征文

尼露

Python XML-RPC实现简单的远程调用过程

宇宙之一粟

Python 7月月更

毕业总结

库尔斯

架构实战营

线程的启动与优先级

zarmnosaj

7月月更

Vuex(一)

小恺

7月月更

DotNet圈里一个优秀的ORM——FreeSql

为自己带盐

7月月更 freesql dotnetcore

linux硬盘挂载教程

乌龟哥哥

7月月更

Flutter 退出当前操作二次确认怎么做才更优雅?

岛上码农

flutter ios 安卓 移动端开发 7月月更

『快速入门electron』之实现窗口拖拽

是乃德也是Ned

Electron electron实战 7月月更

leetcode 650. 2 Keys Keyboard 只有两个键的键盘(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

为什么网站打开速度慢?

源字节1号

网站开发

为什么说数据服务化是下一代数据中台的方向?

雨果

数据中台 数字化转型 DaaS数据即服务

你开发数据API最快多长时间?我1分钟就足够了

雨果

API API开发

疫情当头,作为Leader如何进行团队的管理?| 社区征文

码界西柚

团队管理 远程办公 7月日更 初夏征文

Spring Boot应用在kubernetes的sidecar设计与实战

程序员欣宸

Java Kubernetes Sidecar 7月月更

【算法刷题日记之本手篇】组队竞赛与删除公共字符

未见花闻

7月月更

「Docker 那些事儿」容器很难理解?带你从头到尾捋一遍

Albert Edison

7月月更

秒杀系统设计

库尔斯

架构实战营

ajax

Jason199

ajax 7月月更

服务可见可观测性

阿泽🧸

微服务 7月月更

电商系统微服务架构

极客土豆

Hive的UDF

怀瑾握瑜的嘉与嘉

hive 7月月更

L3立法试水,为自动驾驶产业带来什么?

脑极体

图解网络:什么是虚拟路由器冗余协议 VRRP?

wljslmz

网络技术 路由协议 7月月更 VRRP

疫情当头,作为Leader如何进行代码版本和需求开发管控?| 社区征文

码界西柚

团队管理 远程办公 7月日更 远程开发 初夏征文

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