必须用 json 类型,不是 varchar 或 text;mysql 的 json 能力仅在声明 json 类型时生效,建表需明确写 profile json,引擎限定 innodb,插入须用 json_object/json_array 构造,查询区分 -> 与 ->>,更新须用 json_set 等函数实现原子局部修改。

必须用 JSON 类型,不是 VARCHAR 或 TEXT
MySQL 的 JSON 能力只在你真正用了 JSON 类型时才生效。如果建表时写 details TEXT,哪怕存的是 {"a":1},MySQL 也只当它是普通字符串——不校验、不索引、不能用 -> 操作符,后续所有优化都无从谈起。
常见错误现象:插入单引号包裹的 JSON(如 '{"name":'Alice'}')或带尾随逗号的结构,直接报错 Invalid JSON text;而 TEXT 列会安静地存进去,等你查询时才发现字段根本没法提取。
- 建表语句必须明确声明:
CREATE TABLE users (profile JSON) - 引擎只能是
InnoDB(MyISAM不支持JSON) -
JSON列不能设DEFAULT,也不能加NOT NULL后不给值——插入时必须显式传NULL或合法 JSON
插入时优先用 JSON_OBJECT 和 JSON_ARRAY
手拼 JSON 字符串极易出错:变量插进去时引号嵌套混乱、中文没转义、数组末尾多逗号……这些都会让 INSERT 失败。函数方式由 MySQL 内部生成,天然合法,且自动标准化布尔值和键名。
示例对比:
INSERT INTO users (profile) VALUES (JSON_OBJECT('name', 'Alice', 'active', true, 'tags', JSON_ARRAY('dev', 'mysql')));
优于:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
INSERT INTO users (profile) VALUES ('{"name": "Alice", "active": true, "tags": ["dev", "mysql"]}');
- 含变量时尤其危险:比如
CONCAT('{"name":"', name_var, '"}')遇到name_var = "O'Reilly"就直接语法错误 -
JSON_OBJECT会自动去重同名键(后出现的覆盖前一个),JSON_ARRAY对空值处理更鲁棒 - 不推荐用
CAST(... AS JSON)替代,它不校验结构合法性,只是类型转换
查询时分清 -> 和 ->>
-> 返回带双引号的 JSON 片段(类型仍是 JSON),->> 返回去引号后的标量值(字符串/数字/布尔)。这个区别直接影响 WHERE 条件、ORDER BY 和索引使用。
典型错误:写 WHERE data->'$.status' = 'active' —— 实际比较的是 "active"(带引号)和 active(无引号),永远不相等。
- 需要参与比较或排序,一律用
->>:WHERE data->>'$.status' = 'active' - 要保留嵌套结构继续下一层提取,用
->:data->'$.address'->>'$.city' - 路径不存在时两者都返回
NULL,不会报错,但JSON_CONTAINS更适合判断数组是否含某值
更新必须用 JSON_SET 等函数,别拼字符串
用 UPDATE ... SET json_col = CONCAT('{"a":', new_val, '}') 这类操作等于全量覆盖:并发写入会丢失对方修改、性能差、还可能因格式错误导致字段变 NULL。
JSON_SET、JSON_REPLACE、JSON_INSERT 是原子级局部更新,MySQL 在二进制层面操作,安全高效。
-
JSON_SET(data, '$.status', 'archived'):路径存在则更新,不存在则新增 -
JSON_REPLACE(data, '$.status', 'archived'):仅当路径已存在才改,否则忽略 - 数组追加用
JSON_ARRAY_APPEND(data, '$.tags', 'new_tag'),别手动拼数组字符串
真正难的不是语法,而是想清楚:这个字段到底该用 JSON 还是拆成关联表。JSON 适合配置项、用户偏好、日志元数据这类低频查询、高灵活性场景;一旦需要频繁按内部字段 JOIN 或聚合统计,就该回归关系模型——再好的 JSON 函数也救不了设计偏差。










