问题描述
@H_502_0@我有一个类似 Postgres 的表
UserID EmailFlag PrintFlag SomeOtherField
12 1 0 yes
34 0 1 somecomment
@H_502_0@为了优化 sql 查询,我想像这样使用 JSONB 派生列:
UserID EmailFlag PrintFlag SomeOtherField JsonBDerivedColumn
12 1 0 yes {email: 1,print: 0,comment: "yes"}
34 0 1 somecomment {email: 0,print: 1,comment: "somecomment"}
@H_502_0@如何使用 Postgres sql 实现填充 JsonBDerivedColumn
?
解决方法
您可以使用 jsonb_build_object
函数从其他字段构建 jsonb 对象:
jsonb_build_object('email',EmailFlag_field,'print',PrintFlag_field,'comment',SomeOtherField_field)
每次在 your_table
中插入或更新行时,您都可以通过触发器自动填充 JsonBDerivedColumn 列:
CREATE OR REPLACE FUNCTION T_Before_Insert_Update_your_table()
RETURNS trigger LANGUAGE plpgsql VOLATILE AS
$BODY$
BEGIN
NEW.JsonBDerivedColumn = jsonb_build_object('email',NEW.EmailFlag,NEW.PrintFlag,NEW.SomeOtherField)
RETURN NEW ;
END ;
$BODY$
DROP TRIGGER IF EXISTS T_Before_Insert_Update_your_table ON your_table ;
CREATE TRIGGER T_Before_Insert_Update_your_table
BEFORE INSERT OR UPDATE OF EmailFlag,PrintFlag,SomeOtherField
ON your_table
FOR EACH ROW
EXECUTE PROCEDURE T_Before_Insert_Update_your_table() ;
如果在您添加新的 JsonBDerivedColumn 列并创建触发器函数之前您的表已经存在行,则您需要为 your_table
的所有现有行填充一次新列。您可以通过启动全表的虚拟更新来实现,这将触发表的所有现有行的新触发器函数:
UPDATE your_table AS t
SET EmailFlag = t.EmailFlag
WHERE TRUE ;
但是在这个故事的结尾,我不确定您是否会优化您的 SQL 查询......基于现有列的 simple index 或 multicolumn index 或 combining multiple indexes 怎么样? EmailFlag、PrintFlag、SomeOtherField ?