像我们现在做开发的时候,谁没接触过 JSON 呀,调用 Web API,保存配置文件,处理物联网设备传回的日志之类的,JSON 这种半结构化数据真是随处可见。
金仓数据库 KingbaseES (KES) 在国产数据库中属于佼佼者,所以其功能自然不容忽视,该数据库原本就具备 JSON 数据类型的相关支持,而且特意为我们供应了一整套实用的函数以及索引机制,大致来讲,就是使得用户既能收获关系型数据库那值得信赖的 ACID 特性,又能够轻松获取 NoSQL 所具有的灵活性。
今天这篇文章,咱们来讲讲 KingbaseES 如何全方位支持 JSON 函数的,带大家一起轻松应对半结构化数据。

文章目录
-
- [1. 选型第一步:JSON 和 JSONB 到底用哪个?](#1. 选型第一步:JSON 和 JSONB 到底用哪个?)
- [2. 动手试试:从建表到查询](#2. 动手试试:从建表到查询)
-
- [2.1 先建个表,插点数据](#2.1 先建个表,插点数据)
- [2.2 像切菜一样灵活的查询操作符](#2.2 像切菜一样灵活的查询操作符)
- [2.3 强大的标准 SQL JSON 函数](#2.3 强大的标准 SQL JSON 函数)
- [3. 进阶玩法:修改与构建](#3. 进阶玩法:修改与构建)
-
- [3.1 直接在数据库里改 JSON](#3.1 直接在数据库里改 JSON)
- [3.2 构造 JSON](#3.2 构造 JSON)
- [4. 性能加速器:GIN 索引](#4. 性能加速器:GIN 索引)
- [5. 小结](#5. 小结)
1. 选型第一步:JSON 和 JSONB 到底用哪个?
在 KingbaseES 里,存 JSON 数据有两种路子,虽然看着都能存,但这俩在底层的脾气秉性可大不一样:
- JSON 类型 :
- 特性:简单粗暴,你给它啥样,它就存啥样。纯文本存储,连空格、键的顺序、甚至重复的键都给你留着。
- 缺点:查起来费劲,每次都得重新解析一遍,效率不高,而且还没法建索引。
- 适用场景:这就适合那些必须原封不动保留原始数据的情况,比如法律审计啊,或者单纯当个日志归档存着不动。
JSON 文本(松散、无序、带空格)
json
{
"user_name": "张三",
"age": 28,
"is_vip": true,
"hobbies": ["编程", "游戏", "阅读"],
"address": {
"city": "北京",
"street": "科技园路8号"
},
"last_login": null,
"score": 95.5
}
- JSONB 类型 (强烈推荐):
- 特性:存的是二进制格式。存进去的时候它会先"嚼碎"了(解析),把多余的空格扔了,键的顺序也不留,重复的键只留最后一个。
- 优点 :查起来飞快,因为不需要再解析了;最关键的是,它支持 GIN 索引,这可是查询性能起飞的关键。
- 适用场景:只要你是需要频繁查、改、处理 JSON 数据,选它准没错。
JSONB 二进制结构(紧凑、有序、树状)
plaintext
JSONB_OBJECT [8字节头部]
├─ 键序1(S:字符串类型):"address" → 嵌套对象
│ ├─ 键序1:"city"(S)→ "北京"(16字节)
│ └─ 键序2:"street"(S)→ "科技园路8号"(24字节)
├─ 键序2(B:布尔类型):"is_vip" → true(1字节)
├─ 键序3(N:数字类型):"age" → 28(4字节,整数编码)
├─ 键序4(A:数组类型):"hobbies" → 3个元素
│ ├─ 索引0(S):"编程"(8字节)
│ ├─ 索引1(S):"游戏"(8字节)
│ └─ 索引2(S):"阅读"(8字节)
├─ 键序5(N:数字类型):"score" → 95.5(8字节,浮点数编码)
├─ 键序6(NULL:空类型):"last_login" → null(1字节)
└─ 键序7(S:字符串类型):"user_name" → "张三"(12字节)
2. 动手试试:从建表到查询
光说不练假把式,咱们直接上代码,看看 KES 的 JSON 能力到底怎么样。
2.1 先建个表,插点数据
咱们先搞一张表,里面带个 JSONB 类型的字段:
sql
CREATE TABLE product_docs (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
attributes JSONB -- 使用 JSONB 类型
);
-- 插入数据
INSERT INTO product_docs (name, attributes) VALUES
('智能手机', '{"brand": "KingMobile", "color": "black", "specs": {"storage": "256GB", "ram": "12GB"}, "tags": ["new", "sale"]}'),
('蓝牙耳机', '{"brand": "KingAudio", "color": "white", "specs": {"battery": "24h"}, "tags": ["wireless"]}');

2.2 像切菜一样灵活的查询操作符
KES 提供了一套跟 PostgreSQL 很像的操作符,取数据特别顺手:
->: 拿对象(出来的还是 JSON 格式)。->>: 拿文本(出来的就是纯字符串了)。#>: 按路径拿对象(层级深的时候好用)。
sql
-- 查询所有品牌(返回文本)
SELECT attributes->>'brand' AS brand FROM product_docs;
-- 查询存储规格为 256GB 的产品(嵌套查询)
SELECT name
FROM product_docs
WHERE attributes->'specs'->>'storage' = '256GB';

2.3 强大的标准 SQL JSON 函数
除了上面那些好用的操作符,KingbaseES 对 SQL 标准和 Oracle 风格 的 JSON 函数支持得也相当完美。如果你以前习惯用 Oracle,那上手肯定特亲切。
- JSON_VALUE:取单个值。
- JSON_QUERY:取对象或者数组。
- JSON_TABLE:这个厉害了,能把 JSON 数据直接转换成关系表的格式(行列转换的神器)。
sql
-- 使用 JSON_VALUE 提取颜色
SELECT name, JSON_VALUE(attributes, '$.color') AS color
FROM product_docs;
-- 使用 JSON_TABLE 将 JSON 数组拆解为行
-- 假设我们需要展开 tags 数组
SELECT p.name, t.tag
FROM product_docs p,
JSON_TABLE(p.attributes, '$.tags[*]' COLUMNS (tag VARCHAR(20) PATH '$')) AS t;

3. 进阶玩法:修改与构建
3.1 直接在数据库里改 JSON
以前可能得把数据拿出来在代码里改,现在不用了,直接在数据库这一层就能动刀:
- jsonb_set:更新指定路径下的值。
- - :删除键或数组元素。
sql
-- 将 ID 为 1 的手机颜色修改为 "silver"
UPDATE product_docs
SET attributes = jsonb_set(attributes, '{color}', '"silver"')
WHERE id = 1;
-- 给所有产品增加一个 "in_stock" 标记
UPDATE product_docs
SET attributes = attributes || '{"in_stock": true}';
3.2 构造 JSON
有时候前端要 JSON 格式,咱们也不用在后端代码里拼了,直接把关系型数据转成 JSON 吐出去:
sql
-- 将查询结果直接构建为 JSON 对象
SELECT jsonb_build_object(
'product_name', name,
'details', attributes
)
FROM product_docs;

4. 性能加速器:GIN 索引
这可是 JSONB 的"杀手锏"。要是表里 JSON 数据多了,全表扫描肯定慢得要死。这时候,KES 的 GIN (Generalized Inverted Index) 索引就派上用场了。
sql
-- 在 attributes 列上创建 GIN 索引
CREATE INDEX idx_product_attrs ON product_docs USING GIN (attributes);
建好索引之后,像下面这种查询,哪怕数据量到了千万级,也能瞬间给你返回结果:
sql
-- 查询包含 "wireless" 标签的产品
-- @> 是"包含"操作符,GIN 索引对此支持极佳
SELECT name FROM product_docs WHERE attributes @> '{"tags": ["wireless"]}';
5. 小结
总的来说,KingbaseES 对 JSON 的支持可不是简单地"能存能取"那么简单,它其实是给咱们构建了一套完整的生态系统:
- 要么存要么用:JSON 和 JSONB 随你挑。
- 兼容性强 :既有简单的操作符,也支持 Oracle/SQL 标准的那些函数(比如
JSON_TABLE),老项目迁移过来也省心。 - 性能卓越:配合 GIN 索引,查半结构化数据也能像查普通表一样快。
不管你是想做一个灵活的内容管理系统(CMS),还是得处理那些变来变去的电商商品属性,KingbaseES 的 JSON 能力都能给你稳稳的支撑。
参考资料:KingbaseES 数据库知识库