PostgreSQL从入门到进阶
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
🏠 首页
  • 开始学习

    • PostgreSQL介绍
    • 安装配置
  • 基础教程

    • 数据库与表
    • 数据类型
    • CRUD操作
    • WHERE条件
  • 进阶查询

    • 联表查询
    • 聚合函数
    • 子查询
    • 视图
  • 性能优化

    • 索引优化
    • 查询优化
    • EXPLAIN分析
  • 事务处理
  • 触发器
  • 存储过程
  • JSON数据
  • 博客系统
  • 用户管理系统
  • 最佳实践
🔗 编程指南
  • 开始之前

    • 教程介绍
    • 什么是PostgreSQL?
    • 安装PostgreSQL
  • 基础入门

    • 数据库和表的概念
    • 数据类型详解
    • 增删改查操作(CRUD)
    • 查询条件WHERE
  • 进阶查询

    • 多表联查JOIN
    • 聚合函数
    • 子查询
    • 视图VIEW
  • 性能优化

    • 索引详解
    • 查询优化
    • 执行计划分析
  • 高级特性

    • 事务处理
    • 触发器
    • 存储过程
    • JSON数据
  • 实战项目

    • 实战项目:博客系统
    • 实战项目:用户管理系统
    • 最佳实践

JSON数据

嗨!我是长安。PostgreSQL也能玩NoSQL!

🎯 JSON vs JSONB

PostgreSQL支持两种JSON类型:

特性JSONJSONB
存储方式文本二进制
插入速度快稍慢
查询速度慢快
索引支持不支持支持
推荐❌✅ 用这个!

📝 存储JSON数据

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    attributes JSONB  -- 使用JSONB
);

-- 插入JSON数据
INSERT INTO products (name, attributes) VALUES 
    ('iPhone 15', '{"color": "black", "storage": "256GB", "price": 5999}'),
    ('MacBook Pro', '{"color": "silver", "cpu": "M3", "ram": "16GB"}');

🔍 查询JSON数据

获取JSON字段

-- -> 返回JSON类型
SELECT attributes -> 'color' FROM products;
-- 结果:"black"

-- ->> 返回文本类型
SELECT attributes ->> 'color' FROM products;
-- 结果:black

-- 嵌套访问
SELECT attributes -> 'specs' -> 'cpu' FROM products;

WHERE条件

-- 查找黑色产品
SELECT * FROM products 
WHERE attributes ->> 'color' = 'black';

-- 查找价格大于5000的
SELECT * FROM products 
WHERE (attributes ->> 'price')::numeric > 5000;

-- 检查键是否存在
SELECT * FROM products 
WHERE attributes ? 'storage';

-- 包含某个值
SELECT * FROM products 
WHERE attributes @> '{"color": "black"}';

💡 修改JSON数据

-- 添加字段
UPDATE products 
SET attributes = attributes || '{"warranty": "1年"}'
WHERE id = 1;

-- 修改字段
UPDATE products 
SET attributes = jsonb_set(attributes, '{price}', '6999')
WHERE id = 1;

-- 删除字段
UPDATE products 
SET attributes = attributes - 'price'
WHERE id = 1;

🎯 JSON函数

-- jsonb_array_elements:展开数组
SELECT * FROM jsonb_array_elements('[1,2,3]');

-- jsonb_each:展开对象
SELECT * FROM jsonb_each('{"a":1,"b":2}');

-- jsonb_object_keys:获取所有键
SELECT jsonb_object_keys(attributes) FROM products;

-- jsonb_pretty:格式化输出
SELECT jsonb_pretty(attributes) FROM products;

📊 索引JSON字段

-- GIN索引(推荐)
CREATE INDEX idx_attributes ON products USING GIN (attributes);

-- 现在查询很快
SELECT * FROM products WHERE attributes @> '{"color": "black"}';

-- 索引特定路径
CREATE INDEX idx_color ON products ((attributes ->> 'color'));

🎮 实战案例

用户配置

CREATE TABLE user_settings (
    user_id INT PRIMARY KEY,
    settings JSONB DEFAULT '{}'
);

INSERT INTO user_settings VALUES 
    (1, '{"theme": "dark", "language": "zh-CN", "notifications": {"email": true, "sms": false}}');

-- 查询主题是dark的用户
SELECT user_id FROM user_settings 
WHERE settings ->> 'theme' = 'dark';

-- 更新设置
UPDATE user_settings 
SET settings = jsonb_set(settings, '{theme}', '"light"')
WHERE user_id = 1;

商品属性

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    category VARCHAR(50),
    specs JSONB
);

-- 手机
INSERT INTO products VALUES 
    (1, 'iPhone 15', '手机', '{"brand": "Apple", "color": ["黑色", "白色"], "storage": ["128GB", "256GB", "512GB"]}');

-- 查询有黑色的手机
SELECT * FROM products 
WHERE specs -> 'color' ? '黑色';

-- 统计每种颜色的数量
SELECT 
    jsonb_array_elements_text(specs -> 'color') as color,
    COUNT(*) 
FROM products 
GROUP BY color;

📚 下一步

恭喜!高级特性学完了!

现在进入实战项目!


长安的经验:JSONB很灵活,但别什么都用JSON,结构化数据还是用普通列!⚖️

最近更新: 2025/12/1 18:21
Prev
存储过程