写点什么

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

评论

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

企业级统一数据平台建设思路

星环科技

数据平台

使用 Flomesh 服务网格进行流量拆分

Flomesh

微服务 Service Mesh 服务网格

什么是软件开发领域的 obsolete 或者 deprecated 含义

汪子熙

软件开发 三周年连更

如何用 Go 实现一个配置包

江湖十年

好用的Angular组件库有哪些推荐的?TinyNG好用吗?

英勇无比的消炎药

开源 前端 angular OpenTiny

推荐一些好用的ChatGPT扩展工具

石云升

ChatGPT 三周年连更

当生成式AI照进医疗,医患关系将何去何从?

脑极体

AI

Java面向对象程序设计|二人间对话示例

TiAmo

Java 三周年连更 点对点通信 socket通信 面向对象程序设计

跨平台应用开发进阶(五十八):短链基本工作原理与实现方案

No Silver Bullet

短链接 跨平台应用开发 三周年连更

minikube 初体验环境搭建

IT蜗壳-Tango

三周年连更

Go并发编程的秘密武器:内存模型和同步原语

Jack

6个优化策略,助你降低K8S成本

SEAL安全

k8s 成本管理

微信小程序开发限制

肥晨

三周年连更

CefSharp自定义缓存实现

沙漠尽头的狼

Unity手机游戏开发:从搭建到发布上线全流程实战

海拥(haiyong.site)

三周年连更

系统稳定性建设之我见(64/100)

hackstoic

质量管理 系统稳定性

Hi3861开发板入门

鸿蒙之旅

OpenHarmony 三周年连更

【Linux】中安装pip(详细教程)

A-刘晨阳

Python Linux 运维 pip 三周年连更

大数据时代数据化转型的多种模式

星环科技

数据存储与访问——文件存储读写

芯动大师

application 三周年连更 SharedPreference

Golang new 和 make 函数

宇宙之一粟

Go make new 三周年连更

Qz学算法-数据结构篇(哈希表)

浅辄

数据结构 三周年连更

Spring Boot如何获取Excel sheet页?

bug菌

Spring Boot spring-boot 三周年连更

躬身入局的数科公司,为本就拥挤的数智化赛道带来了什么?

用友BIP

用友iuap 用友技术大会 数科公司

AI不会取代打工人,使用AI的人才会! | 社区征文

王中阳Go

程序员 AI GPT ChatGPT 三周年征文

京韵、京城、京味:从一台服务器看数字北京

脑极体

算力

【源码分析】【seata】at 模式分布式事务 -rm 实现逻辑

如果晴天

源码分析 分布式事务 seata Seata框架

Unity 之 实现背景图动态适配不同分辨率

陈言必行

Unity 三周年连更

Redis Set 用了 2 种数据结构来存储,到现在才知道

Java你猿哥

Java redis string HashMap底层原理

Java - 泛型

乌龟哥哥

三周年连更

LuckyDraw发布啦

进基的小张

开源项目 Github'

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