CodeGym /课程 /SQL SELF /对比 JSONJSONB:每种格式的优缺点

对比 JSONJSONB:每种格式的优缺点

SQL SELF
第 33 级 , 课程 1
可用

JSON 和 JSONB 最大的区别之一就是数据存储的格式。JSON 是以文本形式保存数据,而 JSONB 是以二进制形式存储。也就是说:

  • JSON 会把你传进来的数据原样保存。比如你插入 {"title": "PostgreSQL", "tags": ["database", "SQL"]} 这串,它就会按原样存下来。
  • JSONB 会先解析 JSON 对象,去掉多余的空格,把 key 排序,优化结构,然后再以二进制格式存储。

这种优化让 JSONB 在处理数据时更快,特别是做复杂的过滤、查找和排序操作时。

读写性能对比

JSON 和 JSONB 在读写速度上各有特点:

  • JSON 写入数据库更快,因为不用在保存前解析数据。但读取和处理时会慢点,因为 PostgreSQL 查询时还得重新解析数据。
  • JSONB 写入时会慢点,因为保存前要处理数据。但读取、过滤和取值都快很多,所以做分析或搜索类的需求更推荐用 JSONB。

举个例子:

-- 创建带 JSON 和 JSONB 的表
CREATE TABLE json_example (data JSON);
CREATE TABLE jsonb_example (data JSONB);

-- 插入数据
INSERT INTO json_example VALUES ('{"key": "值", "tags": ["json", "例子"]}');
INSERT INTO jsonb_example VALUES ('{"key": "值", "tags": ["jsonb", "例子"]}');

-- 过滤数据
SELECT * FROM json_example WHERE data->'key' = '"值"';  -- 慢
SELECT * FROM jsonb_example WHERE data->'key' = '"值"'; -- 快

数据索引

JSONB 最大的优势之一就是支持索引。PostgreSQL 可以给 JSONB 列建索引,用 GIN 类型的索引,大大加快查找和过滤速度。

建索引的例子:

-- 给 JSONB 列建索引
CREATE INDEX idx_jsonb_tags ON jsonb_example USING gin (data->'tags');

而 JSON 不支持索引,所以做复杂查找和过滤时就没那么合适了。

什么时候用 JSON,什么时候用 JSONB

JSON 比较适合这些场景:

  • 你想原样保存数据,不做任何改动。
  • 你不打算经常用 JSON 数据做过滤、查找或排序。
  • JSON 数据主要是要原样传给别的系统或者客户端(比如 API 给前端返回)。

例子:

-- 不分析直接存 JSON
CREATE TABLE api_responses (
    id SERIAL PRIMARY KEY,
    response JSON
);

-- 插入 API 传来的数据
INSERT INTO api_responses (response)
VALUES ('{"status": "成功", "payload": {"id": 123, "name": "John"}}');

JSONB 适合这些情况:

  • 你打算经常根据 JSON 里的值做过滤、查找、分组或排序。
  • 你更看重数据读取的性能,而不是写入速度。
  • 你想用索引来加速 JSON 数据的操作。

例子:

-- 用 JSONB 存分析和嵌套对象
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSONB
);

-- 插入数据
INSERT INTO products (details)
VALUES ('{"name": "笔记本", "price": 1200, "tags": ["电子产品", "电脑"]}');

-- 查找带 "电子产品" 标签的商品
SELECT * FROM products
WHERE details @> '{"tags": ["电子产品"]}';

关于 @> 和 --> 操作符的更多用法,咱们下节课再聊 :P

JSONJSONB 的操作例子

我们来建两个表:一个用 JSON 列,一个用 JSONB:

CREATE TABLE json_table (
    id SERIAL PRIMARY KEY,
    data JSON
);

CREATE TABLE jsonb_table (
    id SERIAL PRIMARY KEY,
    data JSONB
);

插入数据,两张表的写法都一样:

INSERT INTO json_table (data)
VALUES ('{"key": "值", "tags": ["json", "例子"]}');

INSERT INTO jsonb_table (data)
VALUES ('{"key": "值", "tags": ["jsonb", "例子"]}');

现在我们来查 key 为 的数据:

-- 对 JSON
SELECT * FROM json_table
WHERE data->>'key' = '值';

-- 对 JSONB
SELECT * FROM jsonb_table
WHERE data->>'key' = '值';

数据量小的时候,性能差别几乎看不出来。但如果有几百万行,JSONB 的表现会好很多,尤其是你建了索引的话:

CREATE INDEX idx_jsonb_key ON jsonb_table USING gin ((data->>'key'));

处理嵌套对象和数组,JSONB 也更高效:

-- 从数组里取值
SELECT data->'tags'->>0 AS first_tag 
FROM jsonb_table;

优缺点总结

特点 JSON JSONB
数据存储 原样以文本格式保存数据 以二进制格式保存,key 会排序
写入性能 更快,因为直接存原始数据 慢点,因为要先解析
读取性能 慢点,因为查询时要解析数据 更快,因为数据已经优化好
索引 不支持 支持(GIN、BTREE 索引)
过滤
操作支持 有限 更丰富

到底选 JSON 还是 JSONB,得看你的需求。如果只是想原样存文本数据,直接用 JSON 就行。如果你要在列里频繁操作、过滤、查找、分组,JSONB 会更高效也更方便。

对于复杂应用,如果 JSON 数据不仅仅是“存着”,还要经常做分析,JSONB 就是神器。所以,实在拿不准就选 JSONB,说不定以后你写的“人生最快 SQL”就靠它了!

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION