Postgresql 如何使字段默认为分配给jsonb字段的值?

Postgresql 如何使字段默认为分配给jsonb字段的值?,postgresql,jsonb,postgresql-9.6,Postgresql,Jsonb,Postgresql 9.6,我有一张桌子: CREATE TABLE inbound ( -- broadcasts received from RTs id SERIAL primary key, ts TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), rt VARCHAR(10) NOT NULL, region region NOT NULL, channel channel NOT NULL, payload jsonb

我有一张桌子:

CREATE TABLE inbound ( -- broadcasts received from RTs
    id SERIAL primary key,
    ts TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
    rt VARCHAR(10) NOT NULL,
    region region NOT NULL,
    channel channel NOT NULL,
    payload jsonb,
    messageid, -- denormalised
    messagetype -- denormalised
);
有效负载可能是:
{“a”:{“messageid”:“ABC123”}
{“b”:{“messageid”:“ABC123”}

我希望
messageid
字段始终包含负载对象的
messageid
字段的值,而不管它是
a
还是
b

我希望
messagetype
a
b
enum
值,反映有效负载的内容


在Postgres中,对JSON数据进行非规范化是正确的做法,还是最好对数据设置某种形式的视图

不要保留有效负载。而是将字段保存在中。假设此模式:

create type messagetype as enum('a','b');
create table inbound (
    messageid text,
    messagetype messagetype
)
当收到有效载荷时:

with p (payload) as ( values
    ('{"a":{"messageid":"ABC123"}}'::jsonb),
    ('{"b":{"messageid":"ABC123"}}')
)
insert into inbound (messagetype, messageid)
select key::messagetype, value ->> 'messageid'
from p, jsonb_each(payload)
并在要求时:

select jsonb_build_object(messagetype, jsonb_build_object('messageid', messageid))
from inbound
;
       jsonb_build_object       
--------------------------------
 {"a": {"messageid": "ABC123"}}
 {"b": {"messageid": "ABC123"}}

不要保留有效载荷。而是将字段保存在中。假设此模式:

create type messagetype as enum('a','b');
create table inbound (
    messageid text,
    messagetype messagetype
)
当收到有效载荷时:

with p (payload) as ( values
    ('{"a":{"messageid":"ABC123"}}'::jsonb),
    ('{"b":{"messageid":"ABC123"}}')
)
insert into inbound (messagetype, messageid)
select key::messagetype, value ->> 'messageid'
from p, jsonb_each(payload)
并在要求时:

select jsonb_build_object(messagetype, jsonb_build_object('messageid', messageid))
from inbound
;
       jsonb_build_object       
--------------------------------
 {"a": {"messageid": "ABC123"}}
 {"b": {"messageid": "ABC123"}}

我很少在DB上使用JSON,所以这不是一段很好的代码,但它可以工作

select myjsonb#>concat('','{',jsonb_object_keys(myjsonb),'}','')::text[]
  from (values ('{"a":{"messageid":"ABC123"}}'::jsonb ), ('{"b":
        {"messageid":"ABC123"}}'::jsonb)) a (myjsonb).

如果您的所有JSON都像示例中的这些一样简单(只有一对键值,可能只有两个键),那么不要将它们存储为JSON,而是存储为两个字段key_a和key_b或key和value列。

我很少在DB上使用JSON,所以这不是一段好代码,但它可以工作

select myjsonb#>concat('','{',jsonb_object_keys(myjsonb),'}','')::text[]
  from (values ('{"a":{"messageid":"ABC123"}}'::jsonb ), ('{"b":
        {"messageid":"ABC123"}}'::jsonb)) a (myjsonb).

如果您的所有JSON都像示例中的这些一样简单(只有一对键值,可能只有两个键),那么不要将它们存储为JSON,而是存储为两个字段key_a和key_b或key和value列。

为什么需要
有效负载
字段?它可以在查询时生成。抱歉,我没有解释清楚。有效负载通常包含一个复杂的JSON对象,其中只有一个顶级属性,它包含一个“messageid”。我想从JSON中提取一些有用的数据,以使查询更简单、更快。但是,如果数据是结构化的,请不要保留有效负载。使所有字段都具有正确的数据类型。JSON只有在数据没有结构化的情况下才在数据库中有用,我的意思是,如果您事先不知道它的结构。@ClodoaldoNeto我知道基本结构,但结构需要灵活。为什么您需要
有效负载
字段?它可以在查询时生成。抱歉,我没有解释清楚。有效负载通常包含一个复杂的JSON对象,其中只有一个顶级属性,它包含一个“messageid”。我想从JSON中提取一些有用的数据,以使查询更简单、更快。但是,如果数据是结构化的,请不要保留有效负载。使所有字段都具有正确的数据类型。JSON只有在数据没有结构化的情况下才在数据库中有用,我的意思是,如果你事先不知道它的结构。@ClodoaldoNeto我知道基本结构,但结构需要灵活。对不起,如果我要找的是相反的结构。我已经有了有效负载,但希望将单个顶级对象的
messageid
属性和单个顶级对象的属性名称存储为“普通”字段,以使查询更简单、更快。抱歉,如果我正在查找,则情况正好相反。我已经有了有效负载,但希望将单个顶级对象的
messageid
属性和单个顶级对象的属性名称存储为“普通”字段,以使查询更简单、更快。