mysql从5.7开始支持json数据类型,适用于存储配置、标签等半结构化数据。1. 创建表时定义json列;2. 插入合法json字符串;3. 使用->或->>提取字段内容;4. 用json_extract或->操作符做条件筛选;5. 用json_contains查询数组中的值;6. 更新整个或部分json内容可用json_set、json_replace或json_remove函数;7. 对json字段建索引推荐使用虚拟列加索引或mysql 8.0+的json索引方式;json虽灵活但应合理设计,结合常规字段使用效果更佳。
MySQL从5.7版本开始支持JSON数据类型,这让它在处理半结构化数据时更加灵活。如果你需要存储类似配置、标签、嵌套信息等不固定格式的数据,用JSON字段会比传统的多表关联更方便。但怎么用得顺手,还是有些技巧的。
JSON字段的基本使用方式
创建表的时候,可以直接定义一个列的类型为JSON:
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, info JSON );
插入数据时,直接传入合法的JSON字符串即可:
INSERT INTO users (info) VALUES ('{"name": "张三", "age": 28, "tags": ["开发", "阅读"]}');
查询的时候,可以用->操作符提取字段内容:
SELECT info->'$.name' AS name FROM users;
注意:这个提取出来的结果是带引号的字符串,如果要去掉引号,可以加个->>:
SELECT info->>'$.name' AS name FROM users;
查询JSON中的特定值
有时候你可能想根据JSON里的某个字段做条件筛选,比如找出所有年龄大于30的用户:
SELECT * FROM users WHERE JSON_EXTRACT(info, '$.age') > 30;
或者用更简洁的写法:
SELECT * FROM users WHERE info->'$.age' > 30;
如果你要查数组类型的字段,比如找tags里包含“开发”的记录:
SELECT * FROM users WHERE JSON_CONTAINS(info->'$.tags', '"开发"');
注意里面的值要用双引号包裹,因为JSON标准要求字符串必须用双引号。
修改JSON字段的内容
更新整个JSON内容很简单,直接赋新值就行:
UPDATE users SET info = '{"name": "李四", "age": 32}' WHERE id = 1;
但如果只想修改其中某个字段,推荐用JSON_SET、JSON_REPLACE或JSON_REMOVE函数:
- JSON_SET:添加或更新字段
- JSON_REPLACE:只替换已有字段
- JSON_REMOVE:删除字段
举个例子,给id=1的用户增加一个地址字段:
UPDATE users SET info = JSON_SET(info, '$.address', '北京') WHERE id = 1;
索引优化JSON查询性能(重点)
默认情况下,对JSON字段内的值做查询是不能走索引的,效率会比较低。解决办法有两个:
- 创建虚拟列(Generated column)并为其建立索引
- 使用JSON索引(MySQL 8.0+ 支持)
以虚拟列为例子:
ALTER TABLE users ADD COLUMN name VARCHAR(100) GENERATED ALWAYS AS (info->>'$.name') STOred; CREATE INDEX idx_name ON users(name);
这样以后按名字查询就能走索引了。
如果是MySQL 8.0以上版本,还可以直接建索引:
CREATE INDEX idx_age ON users((CAST(info->'$.age' AS UNSIGNED)));
不过这种写法稍显复杂,也容易出错,建议优先考虑虚拟列的方式。
基本上就这些。JSON类型虽然好用,但别滥用,尤其不要把整个表都设计成一个大JSON字段。适当结合常规字段和JSON结构,才能发挥最大优势。