json和jsonb读写性能
- json写入比jsonb快,但检索时比jsonb慢
- json存储格式为文本,jsonb存储格式为二进制
- 检索json数据必须重新解析,jsonb数据不需要重新解析
- 10版本及以上全部索引支持json和jsonb数据类型
- jsonb上的gin索引支持"@>","?","?&","?|"操作符
json和jsonb的差异
- json数据的键的顺序和输入一样,但是jsonb的会不一样
- jsonb会删除空格和重复的键
- 大多数应用场景建议使用jsonb
##age前的空格和重复id键都原样保留
select '{"id":1, "age":18,"info":"hello,word","price":10.08,"id":2}'::json
json
--------------------------------------------------------------
{"id":1, "age":18,"info":"hello,word","price":10.08,"id":2}
##age前的空格和重复id键只保留最后一个
select '{"id":1, "age":18,"info":"hello,word","price":10.08,"id":2}'::jsonb
jsonb
----------------------------------------------------------
{"id": 2, "age": 18, "info": "hello,word", "price": 10.08}
查询
- "->"操作符可以查询json数据键值
- "->>"操作符可以以文本格式返回json字段键值
追加
- "||"操作符追加键值
删除
- "-"操作符删除
- "#-"操作符删除指定键值,通常用于有嵌套json数据删除的场景
更新
- "||"操作符进行覆盖更新
- "jsonb_set(target jsonb,path text[],new_value jsonb[,create_missing boolean])"语法进行修改
- target:数据源
- path:路径
- new_value:更新后的键值
- create_missing:true:如果键值不存在则添加;false:如果兼职不存在,则不添加
相关函数
- json_each():返回键值对结果
- json_each_text():以文本形式返回键值对结果
- row_to_json():将普通表转换成json类型表
- json_object_keys():返回每对的键值对中key
基本操作
##创建测试的基础表
CREATE TABLE public.aa (
id int4 NULL,
province varchar(10) NULL,
city varchar(10) NULL
);
CREATE INDEX aa_key ON public.aa USING btree (id);
##创建json,jsonb测试表
create table aa_json(id serial,addr_info json);
create table aa_jsonb(id serial,addr_info jsonb);
/*
##addr_info的json格式存储的信息
{
"id": 1,
"city": "广州",
"province": "广东"
}
*/
##普通表信息转变成json数据,使用row_to_json()方法
select row_to_json(aa) from aa
##转化为jsonb格式
select row_to_json(aa)::jsonb from aa
##插入数据
insert into aa_json(addr_info) select row_to_json(aa)::json from aa
##数据查询
select * from aa_json where addr_info ->> 'city'='广州'
##创建B+树索引
create index idx_aa_json on aa_json using btree ((addr_info->>'city'));
##jsonb创建gin索引
create index idx_gin_aa_json_id on aa_jsonb using btree (((addr_info->>'id')::integer));
##创建全文索引
create index idx_gin_search_json on aa_json using gin(to_tsvector('English',addr_info));
全文索引
1.tsvector
tsvector全文检索数据类型代表一个被优化的可以基于搜索的文档,字符串的内容被分隔成好几段
2.tsquery
tsquery表示一个文本查询,存储用于搜索的词,并且支持布尔型操作"&","|","!"将字符串转换成tsquery
全文索引数据标准化
select to_tsquery('hello&world');
to_tsquery
-----------------
'hello' & 'world'
select to_tsvector('English','hello world');
to_tsvector
-------------------
'hello':1 'world':2