写点什么

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

评论

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

架构师的十八般武艺:高并发架构

agnostic

高并发

C++学习------cmath头文件的源码学习04

桑榆

c++ 源码阅读 9月月更

2022-09-10:以下go语言代码输出什么?A:编译错误;B:49.0;C:49。 package main import ( “fmt“ ) func main() { ch

福大大架构师每日一题

golang 福大大 选择题

京东前端一面面试题

bb_xiaxia1998

JavaScript 前端

Nvm的安装及使用(Nodejs版本管理器)

node.js NVM 9月月更

库调多了,都忘了最基础的概念-《死锁与范式的碰撞》

知识浅谈

死锁 范式 9月月更

哪些应用适合Docker化改造

阿泽🧸

Docker 9月月更

算法基础(一)| 快速排序和归并排序详解

timerring

算法 9月月更

关于 SAP UI5 所有控件的共同祖先 - sap.ui.base.ManagedObject

汪子熙

SAP Fiori SAP UI5 ui5 9月月更

一张图告诉你出海服务商怎么选:中国互联网出海服务商生态图谱

易观分析

报告 出海服务商

极速导入elasticsearch测试数据

程序员欣宸

elasticsearch 9月月更

数据治理(十三):Ranger 安装与启动

Lansonli

数据治理 9月月更

腾讯前端面试题合集

beifeng1996

JavaScript 前端

中秋阅读计划 | 有趣不枯燥的“小薄书”

图灵教育

程序员 科普 计算机 书单 中秋节

力扣15 - 三数之和【奇妙的双指针】

Fire_Shield

双指针 LeetCode 9月月更

力扣349 - 两个数组的交集【哈希表+数组+双指针】

Fire_Shield

双指针 哈希表 9月月更

5分钟教你如何利用华为云IoT进行物联网设备上云

wljslmz

物联网 IoT 华为云 9月月更

【JavaWeb】Servlet系列——Cookie机制、乱码问题总结

胖虎不秃头

Web java; 9月月更

python小知识-日志处理logging

AIWeker

Python python小知识 9月月更

Python 教程之变量(2)—— Python中整数的最大可能值是多少?

海拥(haiyong.site)

Python 9月月更

TCP/IP参考模型

StackOverflow

编程 计算机网络 9月月更

【C语言深度剖析】深入理解C语言中函数的递归算法

Albert Edison

递归 C语言 函数 9月月更

中秋阅读计划 | 有趣不枯燥的“小薄书”

图灵社区

程序员 科普 计算机 书单 中秋

LeetCode-454. 四数相加 II(Java)

bug菌

9月日更 Leet Code 9月月更

LeetCode-164. 最大间距(Java)

bug菌

9月日更 Leet Code 9月月更

Java进阶(十四)实现每天定时对数据库的操作

No Silver Bullet

Java 数据库 9月月更

Qt实现文本编辑器(一)

中国好公民st

c++ qt 9月月更

许世伟老师架构课笔记分享

AiDaddy

架构师 需求设计

Python 教程之变量(3)—— 全局变量和局部变量

海拥(haiyong.site)

Python 9月月更

【Nacos云原生】阅读源码第一步,本地启动Nacos

石臻臻的杂货铺

云原生 nacos 9月月更

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