CodeGym /课程 /SQL SELF /JSON和其他类型对比: ARRAYTEXT

JSON和其他类型对比: ARRAYTEXTHSTORE

SQL SELF
第 34 级 , 课程 3
可用

在PostgreSQL里,很多开发者都会纠结:到底用啥数据结构存信息?用数组(ARRAY)来搞点简单结构?还是用文本(TEXT)字段存字符串?又或者,HSTORE存点“键-值”对?当然,还有个问题:到底啥时候用JSON或者JSONB才最合适?

为了帮你搞明白这些,我们来聊聊每种方式的优缺点,还会给你举点实际用法的例子。

啥时候用数组(ARRAY),啥时候用JSONB?

数组ARRAY)超适合存一堆类型一样的数据。比如你有个学生分数列表,或者一条记录的标签,数组就很合适。

数组例子:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades INTEGER[] -- 分数数组
);

INSERT INTO students (name, grades)
VALUES ('Alice', ARRAY[90, 85, 88]),
       ('Bob', ARRAY[70, 75, 78]);

另一方面,JSONB适合更复杂、嵌套的数据结构。比如你想给每条记录存点额外信息,比如每门课的分数描述,用JSONB就很香。

JSONB例子:

CREATE TABLE students_json (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades JSONB -- 分数相关的数据对象
);

INSERT INTO students_json (name, grades)
VALUES ('Alice', '{"数学": 90, "科学": 85, "英语": 88}'),
       ('Bob', '{"数学": 70, "科学": 75, "英语": 78}');

主要区别

对比项 数组(ARRAY JSONB
结构 同类型的简单数据 复杂嵌套数据结构
数据访问 按下标:grades[1] 按键名:grades->'数学'
索引支持 只能对整个数组用GINBTREE 可以对键用GINBTREE索引
啥时候用 简单数据列表(标签、分数、ID) 有键值的复杂对象

数组和JSONB互转例子

来看看怎么把数据在数组和JSONB之间互转:

数组 → JSONB

SELECT to_jsonb(grades) AS grades_jsonb
FROM students;

-- 结果:
-- [{"90","85","88"}]

JSONB → 数组

SELECT array_agg(value::INTEGER) AS grades_array
FROM jsonb_array_elements_text('["90", "85", "88"]');
-- 结果:
-- {90,85,88}

JSONB和文本数据(TEXT)对比

文本字段很适合你只想存点字符串或者小段没啥结构的数据。如果你就是想查查字符串,比如产品名、描述啥的,TEXT就够用了。

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title TEXT,
    description TEXT
);

INSERT INTO books (title, description)
VALUES ('SQL基础', 'SQL的简明入门介绍'),
       ('高级PostgreSQL', 'PostgreSQL性能的深度指南');

啥时候更适合用JSONB?

如果你的字符串慢慢变成有嵌套结构的信息(比如描述里还带分类、标签列表),那还是用JSONB靠谱。

CREATE TABLE books_json (
    id SERIAL PRIMARY KEY,
    info JSONB
);

INSERT INTO books_json (info)
VALUES ('{"title": "SQL基础", "tags": ["初学者", "数据库"]}'),
       ('{"title": "高级PostgreSQL", "tags": ["性能", "优化"]}');

主要区别

对比项 文本(TEXT JSONB
结构 无结构数据 有结构、可嵌套数据
查找 全文本搜索 按键、值、嵌套结构查找
数据修改 只能整体替换 可以改单个键
啥时候用 简单字符串 复杂的键值数据

JSONB和HSTORE对比

HSTORE算是JSONB的老大哥,可以存“键-值”对。比如你的数据结构很简单(不需要嵌套和数组),HSTORE会更轻便更快。

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    attributes HSTORE
);

INSERT INTO products (attributes)
VALUES ('"颜色"=>"红色", "尺码"=>"M"'),
       ('"颜色"=>"蓝色", "尺码"=>"L"');

为啥JSONB替代了HSTORE

虽然HSTORE用来存“键-值”对很方便,但它不支持嵌套和数组,所以JSONB更万能。如果你数据结构变复杂了,JSONB就是自然而然的下一步。

主要区别

对比项 HSTORE JSONB
结构 “键-值”对,不支持嵌套 完整的嵌套结构
数组支持 不支持 支持
查找 只能按键查 按键、值、嵌套结构查
啥时候用 简单键值对 复杂数据结构

怎么选合适的数据类型?

如果你:

  • 结构简单——就是列表或同类型数据,用数组(ARRAY
  • 就是字符串或描述,用文本字段(TEXT
  • “键-值”对但不需要嵌套,选HSTORE
  • 有嵌套对象、数组、结构复杂——你需要JSONB

格式互转例子

TEXT → JSONB

SELECT to_jsonb('简单文本例子') AS jsonb_form;
-- 结果: "简单文本例子"

JSONB → TEXT

SELECT info::TEXT AS text_form
FROM books_json;
-- 结果: {"title": "SQL基础", "tags": ["初学者", "数据库"]}

HSTORE → JSONB

SELECT hstore_to_jsonb(attributes) AS jsonb_form
FROM products;
-- 结果: {"颜色": "红色", "尺码": "M"}

JSONB → HSTORE

SELECT jsonb_to_hstore('{"颜色": "红色", "尺码": "M"}') AS hstore_form;
-- 结果: "颜色"=>"红色", "尺码"=>"M"

要注意啥?

如果你想要最大灵活性、支持复杂结构,选JSONB。不过,如果你的需求就是简单数据结构,比如数组、文本或“键-值”对,那就用对应的数据类型(ARRAYTEXTHSTORE)。

记住,选对数据结构能帮你后面开发省不少事,还能让你的查询更快!

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