暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

PostgreSQL智慧碎片|微观案例 |第40期

原创 多米爸比 2024-05-07
1130

本期分享如下几个案例:

  • 临时取消外键检查
  • 设置约束延迟生效
  • 校验json字符串
  • pg_cron定时任务更新

1.如何在会话中临时取消外键检查

下面t1表的id字段被t2表的id字段外键引用

CREATE TABLE t1(id int NOT NULL UNIQUE); CREATE TABLE t2(id int REFERENCES t1(id)); INSERT INTO t1 values(1),(2); INSERT INTO t2 values(1);

此时如果要对父表t1进行数据删除,可能会失败,因为t1表的id字段已经被外键引用:

postgres=# DELETE FROM t1 WHERE id = 1; ERROR: update or delete on table "t1" violates foreign key constraint "t2_id_fkey" on table "t2" DETAIL: Key (id)=(1) is still referenced from table "t2".

如何在会话中临时取消外键检查,以便调整父表数据。

设置参数session_replication_role为replica,可以在会话内禁用外键约束:

SET session_replication_role = 'replica';

注意:下面对t1表设置DISABLE TRIGGER也可禁用外键,设置会永久生效。

ALTER TABLE t1 DISABLE TRIGGER ALL;

2.约束如何设置延迟生效

执行数据批量更新操作时,暂时允许违反约束条件,直到事务提交时才进行约束条件检查和生效,这就是约束延迟生效功能。它可以帮助用户在数据更新时,避免由于约束条件限制而导致更新失败。

约束的延迟生效功能有如下三种设置:

  • 不延迟(NOT DEFERRABLE)
  • 语句级延迟生效(DEFERRABLE INITIALLY IMMEDIATE)
  • 事务级延迟生效(DEFERRABLE INITIALLY DEFERRED)

延迟生效功能仅影响主外键、唯一约束和排他约束,而非空约束和检查约束暂不支持。

主键约束的延迟示例如下:

CREATE TABLE t(id int primary key not deferrable);

默认是不延迟,可以显式带上关键字not deferrable。

语句级延迟生效示例如下(每一条语句执行后进行约束检查):

CREATE TABLE t(id int primary key deferrable initially immediate);

事务级延迟生效示例如下(事务结束时才检查约束):

CREATE TABLE t(id int primary key deferrable initially deferred);

语句级延迟生效和事务级延迟生效可以在transaction内使用SET CONSTRAINTS命令进行切换:

postgres=# start transaction ; START TRANSACTION postgres=*# SET CONSTRAINTS t_pkey DEFERRED ; SET CONSTRAINTS postgres=*# SET CONSTRAINTS t_pkey IMMEDIATE ; SET CONSTRAINTS

表的约束延迟生效选项可以通过系统表pg_constraint进行查询:

  • condeferred字段,字段定义为DEFERRED时为true
  • condeferrable字段,字段的延迟生效选项是否允许事务内切换

3.如何校验json字符串是否合法

PG 15beta版本发布了大量json的新功能函数,但正式发布时撤回了,当时因为没有提供对json类型进行检测的内部函数,直到PG 16增加了如下两个系统函数:

  • pg_input_is_valid:检测数据类型与输入值是否有效
  • pg_input_error_info:如果检测失败可查看错误信息

数据类型检测函数可以有效避免类型转换失败而导致事务中断,与此相关,大量json新功能函数也正提交到17。

下面是使用pg_input_is_valid函数检测json字符串的示例:

postgres=# select pg_input_is_valid('{key:"val"}','json'); pg_input_is_valid ------------------- f (1 row) postgres=# select pg_input_is_valid('{"key":"val"}','json'); pg_input_is_valid ------------------- t (1 row)

4.pg_cron定时任务插件更新

来自仙人掌的文章:PostgreSQL定时任务插件pg_cron被误杀后可以自己重启了

pg_cron定时任务插件v1.6.1版本解决了两个易用性问题:

  • 支持设置时区,不再需要根据固定GMT去计算时差
  • 支持自动重启,解决调度进程被误杀后可自动重启,而无需重启数据库

当前pg_cron最新版本为v1.6.2。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论