2017-07-21 25 views
0

我有一个表:如何使字段默认值分配给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字段的值,不管它是否是一个ab

我想要messagetype要的ab一个enum值,反映了有效载荷的内容。

是否正常化JSON数据在Postgres中是正确的做法,还是我会更好地设置某种形式的数据视图?

+1

为什么你需要'有效载荷'字段?它可以在查询时建立。 –

+0

道歉,我没有解释清楚。有效负载通常包含一个* complex * JSON对象,其中只有一个顶级属性,并且包含一个“messageid”。我想从JSON中挑选几个有用的数据,以使查询更简单,更快捷。 – fadedbee

+1

如果数据结构化,请不要保留有效负载。使用正确的数据类型来创建所有字段。如果数据不是结构化的,我的意思是,如果你事先不知道它的结构,JSON只在数据库中有用。 –

回答

1

请勿保留有效负载。改为保存字段。假设这个模式:

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"}} 
1

我rarly与DB jsons工作,所以它不精片代码,但它的作品。

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

如果所有你jsons因为这些从例如作为简单(只有一对键值,并且只有2键可能的),那么请不要将它们存储为jsons但如2个字段KEY_A和key_b或键和价值列。

+0

对不起,这是相反的,如果我正在寻找。我已经*有*有效载荷,但想要将单个顶级对象的'messageid'属性和单个顶级对象的属性名称存储为“普通”字段,以使查询变得更简单和更快。 – fadedbee