PostgreSQL 中 JSON 与 JSONB 类型的区别
PostgreSQL 提供了两种 JSON 数据类型:json 和 jsonb。两者均可存储 JSON 格式数据,但在存储方式和处理性能上有显著差异。
存储格式差异:
json类型以纯文本形式存储 JSON 数据,保留原始格式(包括空格、键顺序等),插入时仅做基本语法验证。jsonb类型以二进制格式存储,解析后重新排列键顺序、删除冗余空格,并建立优化后的索引结构。
核心对比:
| 特性 | json | jsonb |
|---|---|---|
| 存储方式 | 原始文本(直接复制) | 解析后的二进制格式 |
| 写入速度 | 更快(无转换开销) | 较慢(需解析和优化) |
| 查询速度 | 较慢(需实时解析) | 更快(支持索引和预优化) |
| 存储空间 | 较小(保留原始格式) | 较大(额外元数据开销) |
| 键顺序保留 | 保留 | 不保留 |
| 重复键处理 | 保留最后一次出现的键值 | 仅保留最后一次出现的键值 |
可视化存储示例
假设插入以下 JSON 数据:
CREATE TABLE test_data (id serial, j json, jb jsonb);
INSERT INTO test_data (j, jb) VALUES (
'{"name": "Alice", "age": 30, "active": true, "tags": ["a", "b"]}',
'{"name": "Alice", "age": 30, "active": true, "tags": ["a", "b"]}'
);
内部存储表现对比:
-
json类型
存储与输入完全一致的文本,包括空格和键顺序:{"name": "Alice", "age": 30, "active": true, "tags": ["a", "b"]} -
jsonb类型
存储为优化后的二进制,键可能重新排序(字母顺序),移除空格:{"active": true, "age": 30, "name": "Alice", "tags": ["a", "b"]}
操作差异示例
查询效率测试:
-- 对json类型查询(需实时解析)
EXPLAIN ANALYZE SELECT * FROM test_data WHERE j->>'name' = 'Alice';
-- 对jsonb类型查询(可利用索引)
CREATE INDEX idx_jb ON test_data USING gin (jb);
EXPLAIN ANALYZE SELECT * FROM test_data WHERE jb @> '{"name": "Alice"}';
修改数据:
-- jsonb支持直接操作符修改(9.5+版本)
UPDATE test_data SET jb = jb || '{"age": 31}'::jsonb WHERE id = 1;
-- json类型需完全替换
UPDATE test_data SET j = '{"name": "Alice", "age": 31}'::json WHERE id = 1;
如何选择类型
适用 json 的场景:
- 需要保留原始 JSON 格式(如日志记录)。
- 仅做存储且极少查询。
适用 jsonb 的场景:
- 需要高频查询或修改 JSON 内容。
- 需要创建 GIN 索引加速搜索。
- 不关心键顺序或格式细节。
通过以上对比,可根据实际业务需求选择合适的数据类型。
PostgreSQL中JSON与JSONB对比
1043

被折叠的 条评论
为什么被折叠?



