当前位置: 首页 > news >正文

PostgreSQL JSON 与 JSONB 类型查询详解:差异、示例与最佳实践

PostgreSQL JSONJSONB 查询示例

PostgreSQL 支持 JSONJSONB 两种 JSON 类型:

  • JSON:存储为 纯文本,查询时需要解析,效率较低。
  • JSONB:存储为 二进制格式,支持索引,查询性能更好。

下面分别列出 JSONJSONB 的查询示例。

一、JSON 查询示例

创建 JSON 类型的表:

CREATE TABLE demo_json (
    id SERIAL PRIMARY KEY,
    params JSON
);

插入数据:

INSERT INTO demo_json (params) VALUES 
('{"name": "Alice", "age": 25, "is_active": true, "skills": ["Java", "SQL"], "address": {"city": "New York", "zip": 10001}, "salary": null}'),
('{"name": "Bob", "age": 30, "is_active": false, "skills": ["Python", "Go"], "address": {"city": "Los Angeles", "zip": 90001}, "salary": 5000}');

1. 查询 JSON 数据

(1) 查询 JSON 整个对象
SELECT params FROM demo_json;
(2) 查询 JSON 中的某个键
SELECT params->'name' FROM demo_json;

🔹 -> 返回 JSON 类型。

SELECT params->>'name' FROM demo_json;

🔹 ->> 返回 TEXT 类型(更适合查询)。

(3) 查询 JSON 数组中的元素
SELECT params->'skills'->0 FROM demo_json;

🔹 获取数组中的第一个元素。


2. 过滤 JSON 数据

(4) 查询 JSON 中包含某个值
SELECT * FROM demo_json WHERE params->>'name' = 'Alice';
(5) 查询 JSON 数字值
SELECT * FROM demo_json WHERE (params->>'age')::INT > 25;
(6) 查询 JSON 布尔值
SELECT * FROM demo_json WHERE (params->>'is_active')::BOOLEAN = true;
(7) 查询 JSON 中 null
SELECT * FROM demo_json WHERE params->>'salary' IS NULL;

3. JSON 不能索引,查询较慢

CREATE INDEX idx_json_name ON demo_json ((params->>'name'));

🔹 JSON 本身不支持索引,必须用 表达式索引 才能加速查询。


二、JSONB 查询示例

创建 JSONB 类型的表:

CREATE TABLE demo_jsonb (
    id SERIAL PRIMARY KEY,
    params JSONB
);

插入数据:

INSERT INTO demo_jsonb (params) VALUES 
('{"name": "Alice", "age": 25, "is_active": true, "skills": ["Java", "SQL"], "address": {"city": "New York", "zip": 10001}, "salary": null}'),
('{"name": "Bob", "age": 30, "is_active": false, "skills": ["Python", "Go"], "address": {"city": "Los Angeles", "zip": 90001}, "salary": 5000}');

1. 查询 JSONB 数据

(1) 查询 JSONB 整个对象
SELECT params FROM demo_jsonb;
(2) 查询 JSONB 中的某个键
SELECT params->'name' FROM demo_jsonb;
SELECT params->>'name' FROM demo_jsonb;

🔹 区别

  • -> 返回 JSONB(适用于嵌套查询)。
  • ->> 返回 TEXT(适用于筛选)。
(3) 查询 JSONB 数组中的元素
SELECT params->'skills'->0 FROM demo_jsonb;

2. 过滤 JSONB 数据

(4) 查询 JSONB 中包含某个值
SELECT * FROM demo_jsonb WHERE params->>'name' = 'Alice';
(5) 查询 JSONB 数字值
SELECT * FROM demo_jsonb WHERE (params->>'age')::INT > 25;
(6) 查询 JSONB 布尔值
SELECT * FROM demo_jsonb WHERE (params->>'is_active')::BOOLEAN = true;
(7) 查询 JSONB 中 null
SELECT * FROM demo_jsonb WHERE params->>'salary' IS NULL;

3. JSONB 独有的高级查询

(8) 使用 @> 进行 JSONB 包含查询
SELECT * FROM demo_jsonb WHERE params @> '{"age": 25}';

🔹 查询 params 是否包含 {"age": 25}

(9) 查询 JSONB 数组是否包含某个值
SELECT * FROM demo_jsonb WHERE params->'skills' ? 'Java';

🔹 ? 用于数组包含查询

(10) 查询 JSONB 数组是否包含多个值
SELECT * FROM demo_jsonb WHERE params->'skills' ?| array['Java', 'Python'];

🔹 ?| 表示包含至少一个

SELECT * FROM demo_jsonb WHERE params->'skills' ?& array['Java', 'SQL'];

🔹 ?& 表示包含所有


4. JSONB 更新

(11) 更新 JSONB 的某个值
UPDATE demo_jsonb 
SET params = jsonb_set(params, '{age}', '40') 
WHERE params->>'name' = 'Alice';

🔹 更新 age 字段为 40

(12) 更新 JSONB 中的嵌套对象
UPDATE demo_jsonb 
SET params = jsonb_set(params, '{address, city}', '"Chicago"') 
WHERE params->>'name' = 'Alice';

🔹 更新 address.cityChicago


5. JSONB 索引(查询更快)

CREATE INDEX idx_jsonb_name ON demo_jsonb USING GIN (params);

🔹 JSONB 支持 GIN 索引,加速查询!


总结

对比项JSONJSONB
存储格式纯文本二进制
查询性能解析时才转换,较慢直接查询,较快
索引支持仅支持表达式索引支持 GIN 索引
包含查询params->>'name' = 'Alice'params @> '{"name": "Alice"}'
更新单个键需更新整个 JSONjsonb_set() 可更新部分
数组查询不支持 ? 操作符支持 params->'skills' ? 'Java'

🔹 JSONB 更适用于查询频繁的数据,尤其是带索引的查询。
🔹 JSON 适用于存储但不做复杂查询的数据。

🚀 结论:如果要查询 JSON 数据,推荐使用 JSONB

http://www.dtcms.com/a/107944.html

相关文章:

  • 【STM32设计】基于STM32的智能门禁管理系统(指纹+密码+刷卡+蜂鸣器报警)(代码+资料+论文)
  • Gartner预计2025年AI支出达6440亿美元:数据中心与服务器市场的关键驱动与挑战
  • R语言、MaxEnt模型丨物种分布模拟技术的研究进展与技术挑战
  • mapbox_gl The requested URL returned error: 401
  • 小程序json对象数据从上一个页面传给下一个页面
  • 最短路径--SPFA算法
  • 软考中级网络工程师第十一章网络管理
  • Winform MQTT客户端连接方式
  • 力扣268.丢失的数字
  • 树莓派超全系列文档--(16)无需交互使用raspi-config工具其三
  • 【微知】ARM CPU是如何获取某个进程的页表的?(通过TTBR寄存器,MMU进行处理)
  • 基于javaweb的SSM+Maven校园共享自行车管理系统设计与实现(源码+文档+部署讲解)
  • 基于策略模式的CATIA元素显隐控制工具开发实践——PySide6与PyCATIA深度整合方案
  • 什么是PID控制?
  • FFmpeg命令详解
  • 波动率 计算学习 离散系数
  • 【JavaScript】十四、轮播图
  • 探索Ark-TS语言:什么是Ark-TS?如何入门?有什么基础容易上手?
  • 系统分析师备考启动
  • HashMap底层采用数组+链表而非数组+数组的设计,主要基于以下原因及两者的对比:
  • docker安装ngnix
  • diffusion-vas 提升遮挡区域的分割精度
  • openEuler24.03 LTS下安装Flume
  • 动态规划:第一弹(第N个泰波那契数列、使用最小花费爬楼梯、解码方法)
  • AI安全:构建负责任且可靠的系统
  • leetcode287.寻找重复数
  • 【开发问题记录】回流(Reflow) 和 重绘(Repaint)
  • C++的UDP连接解析域名地址错误
  • React PDF 预览终极优化:30 页大文件不卡,加载快如闪电!
  • 【机器学习】嘿马机器学习(算法篇)第14篇:决策树算法,学习目标【附代码文档】