欢迎光临德州市中国灵车网
详情描述

MySQL 提供了多种操作和查询JSON数据的方式。以下是几种常用的JSON查询筛选方法:

1. 基本JSON路径查询

访问特定字段

-- 使用 -> 操作符(返回JSON类型)
SELECT column->'$.key' FROM table;

-- 使用 ->> 操作符(返回字符串类型)
SELECT column->>'$.key' FROM table;

-- 使用 JSON_EXTRACT() 函数
SELECT JSON_EXTRACT(column, '$.key') FROM table;

2. 查询嵌套字段

假设有以下JSON数据:

{
  "user": {
    "name": "张三",
    "age": 30,
    "address": {
      "city": "北京",
      "street": "长安街"
    }
  }
}
-- 访问嵌套字段
SELECT 
  data->'$.user.name' as name,
  data->'$.user.address.city' as city
FROM users;

-- 使用通配符 * 查询数组中的元素
SELECT data->'$.phones[*].number' FROM users;

3. WHERE条件筛选

-- 查询特定值的记录
SELECT * FROM users 
WHERE data->'$.user.name' = '"张三"';

-- 使用 ->> 避免引号问题
SELECT * FROM users 
WHERE data->>'$.user.name' = '张三';

-- 查询嵌套字段条件
SELECT * FROM users 
WHERE data->>'$.user.address.city' = '北京';

-- 数值比较
SELECT * FROM users 
WHERE CAST(data->'$.user.age' AS UNSIGNED) > 25;

4. JSON数组查询

-- 查询数组长度
SELECT JSON_LENGTH(data->'$.tags') FROM products;

-- 查询数组是否包含特定值
SELECT * FROM products 
WHERE JSON_CONTAINS(data->'$.tags', '"electronics"');

-- 查询数组是否包含路径
SELECT * FROM products 
WHERE JSON_CONTAINS_PATH(data, 'one', '$.tags');

-- 访问数组特定位置
SELECT data->'$.tags[0]' FROM products;

5. JSON函数组合使用

-- JSON_EXTRACT 与 JSON_UNQUOTE
SELECT JSON_UNQUOTE(JSON_EXTRACT(data, '$.user.name')) FROM users;

-- 检查JSON路径是否存在
SELECT * FROM users 
WHERE JSON_CONTAINS_PATH(data, 'one', '$.user.address.city');

-- 多个条件组合
SELECT * FROM users 
WHERE data->>'$.user.age' > '25' 
  AND data->>'$.user.address.city' = '北京';

6. 高级查询示例

-- 动态路径查询
SET @path = '$.user.address.city';
SELECT JSON_EXTRACT(data, @path) FROM users;

-- 查询所有键名
SELECT JSON_KEYS(data) FROM users;

-- 查询嵌套对象的所有键
SELECT JSON_KEYS(data->'$.user') FROM users;

-- 更新JSON字段
UPDATE users 
SET data = JSON_SET(data, '$.user.age', 31)
WHERE data->>'$.user.name' = '张三';

7. 性能优化建议

-- 创建虚拟列并建立索引
ALTER TABLE users 
ADD COLUMN user_name VARCHAR(50) 
GENERATED ALWAYS AS (data->>'$.user.name');

CREATE INDEX idx_user_name ON users(user_name);

-- 使用生成列进行查询
SELECT * FROM users WHERE user_name = '张三';

8. 完整示例

-- 创建测试表
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  profile JSON
);

-- 插入数据
INSERT INTO users (profile) VALUES 
('{"name": "张三", "age": 30, "tags": ["开发者", "MySQL"]}'),
('{"name": "李四", "age": 25, "tags": ["设计师"]}');

-- 查询示例
SELECT 
  id,
  profile->>'$.name' as name,
  profile->>'$.age' as age,
  JSON_EXTRACT(profile, '$.tags[0]') as first_tag
FROM users
WHERE profile->>'$.age' > 26
  AND JSON_CONTAINS(profile->'$.tags', '"开发者"');

注意事项:

引号处理-> 返回带引号的JSON值,->> 返回去引号的字符串 性能考虑:JSON查询通常比结构化查询慢,建议对常用字段创建生成列和索引 NULL处理:JSON路径不存在时返回NULL 版本要求:MySQL 5.7.8+ 支持JSON数据类型和相关函数

根据具体需求选择合适的查询方式,对于频繁查询的字段,建议使用生成列+索引的方案。