服务端与数据 / 进阶

PostgreSQL JSONB:灵活字段也需要建模边界

JSONB 适合变化快的附加属性,但高频过滤、关联和强约束字段应保留为普通列。本文给出常用查询与索引策略。

哪些字段适合放进 JSONB

适合:不同商品类别的扩展属性、低频读取的第三方原始响应、版本化配置;不适合:金额、状态、外键、需要唯一约束的标识,以及频繁聚合排序的字段。

判断标准不是字段会不会变化,而是它是否参与核心业务规则。JSONB 里的值也能索引,但类型约束、外键和迁移可见性都不如普通列自然。

区分 JSON 值和文本值

先把问题稳定复现,再决定要改哪一层。

EXAMPLE / 02PostgreSQL
-- ->> 返回文本
SELECT metadata->>'plan' AS plan FROM users;

-- @> 判断结构包含
SELECT id FROM users
WHERE metadata @> '{"flags": {"beta": true}}';

-- 路径值转成数值后比较
SELECT id FROM products
WHERE (attributes->>'weight')::numeric > 10;

索引必须匹配操作符

大量 @> 包含查询适合 GIN;总是过滤固定路径时,表达式 B-tree 索引更小、更直接。修改深层 JSON 前要考虑并发覆盖问题,必要时把热点字段拆成普通列。

EXAMPLE / 03PostgreSQL
CREATE INDEX users_metadata_gin
ON users USING gin (metadata jsonb_path_ops);

CREATE INDEX users_plan_idx
ON users ((metadata->>'plan'));