mysql 5.7.8+ 原生支持 json 类型,建表需用 json 字段声明,插入须为合法 json,不可设默认字符串值,不能作主键/外键/唯一约束,查询需用 -> 或 json_extract() 提取并配合 json_unquote() 获取纯文本,索引需通过生成列实现。

JSON 是 MySQL 5.7.8+ 的原生类型,不是插件或别名,只要版本达标就能直接用。
确认 MySQL 版本是否支持 JSON
执行 SELECT VERSION();,结果必须 ≥ 5.7.8。低于该版本(比如 5.7.7)可能只有 Labs 版本提供,生产环境不建议使用。
如果建表时报错 ERROR 1064 或提示“unknown type 'JSON'”,大概率是版本不达标,或者连错了旧实例(本地多个 MySQL 实例共存时常见)。
建表时直接声明 JSON 字段
语法和其他列类型完全一样,不需要额外配置:
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), profile JSON );
注意点:
-
profile可设为NULL,但插入非 NULL 值时必须是合法 JSON 文本(如'{"city":"Beijing"}'),否则报错ERROR 3140 (22032) - 不能设默认值为字符串字面量(如
DEFAULT '{"active":true}'),会直接报错;MySQL 5.7 中无法用DEFAULT (JSON_OBJECT())(那是 8.0.13+ 才支持的) -
JSON字段不能做主键、外键或唯一约束——内部是二进制格式,无法直接比较
插入 JSON 数据的三种安全方式
所有方式都经过 MySQL 解析器校验,非法 JSON 会当场拒绝:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 字符串字面量(最常用):
INSERT INTO users (name, profile) VALUES ('Alice', '{"age":30,"tags":["dev","mysql"]}'); -
JSON_OBJECT()构造对象(5.7.13+ 支持表达式,早期版本只接受常量或列名):INSERT INTO users (name, profile) VALUES ('Bob', JSON_OBJECT('role', 'admin', 'score', 95)); -
JSON_ARRAY()构造数组:INSERT INTO users (name, profile) VALUES ('Carol', JSON_ARRAY(1, 2, 'test'));
别用 VARCHAR 存 JSON 字符串再手动校验——绕过了自动解析、函数优化和索引能力,得不偿失。
查询 JSON 字段要避开常见陷阱
用 -> 操作符提取值最简洁,但要注意返回带双引号的 JSON 字符串:
SELECT name, info->'$.nick_name' AS nick_name FROM test_user;
如果要取纯文本(比如用于 WHERE 或 JOIN),必须套一层 JSON_UNQUOTE():
SELECT name FROM test_user WHERE JSON_UNQUOTE(info->'$.nick_name') = '小萌';
容易漏掉的点:
-
->是JSON_EXTRACT()的快捷写法,两者等价 - 路径表达式必须以
$开头,比如'$.email',不能写成'email' - 对数组元素取值要用索引:
info->'$.tags[0]'
真正麻烦的是索引——JSON 字段本身不能直接加索引,得靠生成列(Generated Column)中转,这个动作在 5.7 里是必须手动做的,漏掉就查不快。










