OK,PostgreSQL 里的 JSONB 是个超强的工具,能存很复杂的层级数据结构。但如果你想改一下 JSONB 列里的某个值,比如换个用户的手机号,或者往数组里加个新类别,咋办?听起来简单,但 JSONB 可不是表格,不能直接改某个单元格。要想在 JSON 对象里更新数据,我们得用点特殊函数。今天的主角就是:
jsonb_set():用来按“路径”修改或新增某个值。jsonb_insert():用来往 JSON 数组里插入新元素。
用 jsonb_set() 更新数据
jsonb_set() 这个函数能让你改 JSONB 对象的一部分,或者往里加新 key 和 value。
基本语法
jsonb_set(target jsonb, path text[], new_value jsonb, create_missing boolean)
target— 你要更新的 JSONB 对象。path— 字符串数组,表示你要改的 key 的路径。new_value— 你想加进去或替换掉的值。create_missing— 布尔参数(TRUE 或 FALSE),表示要不要自动创建缺失的 key。
来看个最简单的例子。假设我们有个 users 表,里面有个 profile 列,类型是 JSONB,存着用户的资料。有个用户要换手机号,怎么搞?
-- 创建表并插入数据
CREATE TABLE users (
id SERIAL PRIMARY KEY,
profile JSONB
);
INSERT INTO users (profile)
VALUES ('{"name": "奥托", "contact": {"phone": "+1-495-123-45-67"}}');
-- 更新手机号
UPDATE users
SET profile = jsonb_set(profile, '{contact,phone}', '"8-800-555-35-35"', FALSE)
WHERE id = 1;
-- 看看结果
SELECT profile FROM users WHERE id = 1;
结果:
{
"name": "奥托",
"contact": {
"phone": "8-800-555-35-35"
}
}
牛!手机号就这么改了!注意,key 的路径要用字符串数组写,比如 '{contact,phone}'。
新增 key
如果你要改的 key 不存在,可以把 create_missing = TRUE,这样会自动帮你创建:
UPDATE users
SET profile = jsonb_set(profile, '{address,city}', '"柏林"', TRUE)
WHERE id = 1;
-- 看看结果
SELECT profile FROM users WHERE id = 1;
结果:
{
"name": "奥托",
"contact": {
"phone": "8-800-555-35-35"
},
"address": {
"city": "柏林"
}
}
现在多了个地址部分,是不是很方便?
用 jsonb_insert() 插入数据
jsonb_insert() 这个函数用来往 JSONB 对象里的数组加新元素。
基本语法
jsonb_insert(target jsonb, path text[], new_value jsonb, insert_after boolean)
target— 目标 JSONB 对象。path— 字符串数组,表示你想插入元素的数组路径。new_value— 要加进去的值。insert_after— 布尔参数。FALSE 表示插在指定索引前,TRUE 表示插在后面。
举个例子。假如我们有个表,profile 列里存着用户的兴趣列表。我们想往数组里加个新兴趣:
-- 先加点数据
UPDATE users
SET profile = jsonb_set(profile, '{interests}', '["运动", "音乐"]', TRUE)
WHERE id = 1;
-- 把新兴趣 "编程" 插到最前面
UPDATE users
SET profile = jsonb_insert(profile, '{interests,0}', '"编程"', FALSE)
WHERE id = 1;
-- 看看结果
SELECT profile FROM users WHERE id = 1;
结果:
{
"name": "奥托",
"contact": {
"phone": "8-800-555-35-35"
},
"address": {
"city": "柏林"
},
"interests": [
"编程",
"运动",
"音乐"
]
}
常见问题和避坑指南
用 jsonb_set() 和 jsonb_insert() 有点小 tricky,注意下面这些点:
- 路径写错。 如果路径不对,或者你想改的元素不存在但
create_missing=FALSE,要么报错,要么啥都不变。一定要先确认 JSON 结构。 - 数据类型不对。
new_value必须是 JSONB 类型。如果你要插入字符串,记得用双引号包起来('"值"')。 - 数据被覆盖。 直接更新数组不用对的函数,可能会把原来的数据全覆盖。想安全加新元素,用
jsonb_insert()。
错误示例:
-- 错误:路径不对
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新联系人"', FALSE)
WHERE id = 1;
这会报错,因为 profile 里没有 contacts 这个 key,而且 create_missing 是 FALSE。
怎么避免:
-- 设置 create_missing = TRUE
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新联系人"', TRUE)
WHERE id = 1;
实际应用场景
玩 JSONB 可不是闹着玩的,这可是很多现代应用的必备技能。举几个实际例子:
- 存用户设置。 JSONB 超适合存那种每个用户都不一样的动态数据,比如 app 的个性化设置。
- 对接外部 API。 拿 REST API 回来的原始 JSON 数据,直接丢 JSONB 里,超方便。
- 大数据分析。 嵌套 JSON 结构很适合搞 IoT 数据、日志、分析啥的。
这就是我们关于 JSON 对象更新的入门讲解啦。现在你已经知道怎么往 JSONB 里插、改、加数据,还能避开常见的坑。下节课我们会讲怎么合并 JSONB 对象,让你玩得更溜!
GO TO FULL VERSION