MYSQL8 JSON 类型学习笔记
基础
函数速查表
Name | Description | Introduced | Deprecated |
---|---|---|---|
-> | Return value from JSON column after evaluating path; equivalent to JSON_EXTRACT(). | ||
->> | Return value from JSON column after evaluating path and unquoting the result; equivalent to JSON_UNQUOTE(JSON_EXTRACT()). | ||
JSON_ARRAY() | Create JSON array | ||
JSON_ARRAY_APPEND() | Append data to JSON document | ||
JSON_ARRAY_INSERT() | Insert into JSON array | ||
JSON_CONTAINS() | Whether JSON document contains specific object at path | ||
JSON_CONTAINS_PATH() | Whether JSON document contains any data at path | ||
JSON_DEPTH() | Maximum depth of JSON document | ||
JSON_EXTRACT() | Return data from JSON document | ||
JSON_INSERT() | Insert data into JSON document | ||
JSON_KEYS() | Array of keys from JSON document | ||
JSON_LENGTH() | Number of elements in JSON document | ||
JSON_MERGE() | Merge JSON documents, preserving duplicate keys. Deprecated synonym for JSON_MERGE_PRESERVE() | Yes | |
JSON_MERGE_PATCH() | Merge JSON documents, replacing values of duplicate keys | ||
JSON_MERGE_PRESERVE() | Merge JSON documents, preserving duplicate keys | ||
JSON_OBJECT() | Create JSON object | ||
JSON_OVERLAPS() | Compares two JSON documents, returns TRUE (1) if these have any key-value pairs or array elements in common, otherwise FALSE (0) | 8.0.17 | |
JSON_PRETTY() | Print a JSON document in human-readable format | ||
JSON_QUOTE() | Quote JSON document | ||
JSON_REMOVE() | Remove data from JSON document | ||
JSON_REPLACE() | Replace values in JSON document | ||
JSON_SCHEMA_VALID() | Validate JSON document against JSON schema; returns TRUE/1 if document validates against schema, or FALSE/0 if it does not | 8.0.17 | |
JSON_SCHEMA_VALIDATION_REPORT() | Validate JSON document against JSON schema; returns report in JSON format on outcome on validation including success or failure and reasons for failure | 8.0.17 | |
JSON_SEARCH() | Path to value within JSON document | ||
JSON_SET() | Insert data into JSON document | ||
JSON_STORAGE_FREE() | Freed space within binary representation of JSON column value following partial update | ||
JSON_STORAGE_SIZE() | Space used for storage of binary representation of a JSON document | ||
JSON_TABLE() | Return data from a JSON expression as a relational table | ||
JSON_TYPE() | Type of JSON value | ||
JSON_UNQUOTE() | Unquote JSON value | ||
JSON_VALID() | Whether JSON value is valid | ||
JSON_VALUE() | Extract value from JSON document at location pointed to by path provided; return this value as VARCHAR(512) or specified type | 8.0.21 | |
MEMBER OF() | Returns true (1) if first operand matches any element of JSON array passed as second operand, otherwise returns false (0) | 8.0.17 |
sql优化
写出高性能sql说白了就是对优化器的口味
- 在 MySQL 8.0中,优化器可以对 JSON 列执行部分原位更新,而不是删除旧文档并将新文档完整地写入该列。
需要满足的条件:
- UPDATE 语句使用 JSON _ SET ()、 JSON _ REPLACE ()或 JSON _ REMOVE ()三个函数中的任何一个来更新列。
- 输入列和目标列必须是同一列。
- 所有更改都用新的数组或对象值替换现有的数组或对象值,并且不向父对象或数组添加任何新元素。
- 被替换的值必须至少与替换值一样大。换句话说,新值不能大于旧值。
创建JSON值
- 有效的JSON值,否则报错
INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
- JSON _ TYPE ()函数期望一个 JSON 参数,并尝试将其解析为一个 JSON 值。如果值有效,则返回值的 JSON 类型,否则将产生错误。
MySQL 使用 utf8mb4字符集和 utf8mb4 _ bin 排序规则处理 JSON 上下文中使用的字符串。其他字符集中的字符串根据需要转换为 utf8mb4。(对于 ascii 或 utf8字符集中的字符串,不需要转换,因为 ascii 和 utf8是 utf8mb4的子集。) - JSON _ ARRAY ()接受一个(可能是空的)值列表,并返回一个包含这些值的 JSON 数组
- JSON _ OBJECT ()接受一个(可能是空的)键值对列表,并返回一个包含这些键值对的 JSON 对象
- JSON _ MERGE _ PRESERVE ()接受两个或多个 JSON 文档并返回组合结果
查询
column-path 操作符-> 和 内联路径操作符->>(不包括周围的引号或任何转义符)
mysql> SELECT col->"$.mascot" FROM qtest;
+---------------------------------------------+
| col->"$.mascot" |
+---------------------------------------------+
| "Our mascot is a dolphin named \"Sakila\"." |
+---------------------------------------------+
mysql> SELECT sentence->>"$.mascot" FROM facts;
+-----------------------------------------+
| sentence->>"$.mascot" |
+-----------------------------------------+
| Our mascot is a dolphin named "Sakila". |
+-----------------------------------------+
规范化
文本插入和JSON_OBJECT函数都会依据“最后的重复键获胜”规则,例如{"a": 1, "a": 2}会得到{"a": 2}
合并
JSON_MERGE_PRESERVE与JSON_MERGE_PATCH区别
简单的说:json_merge_patch是覆盖,json_merge_preserve是组合(转化为数组或连接数组)
- 对于json对象
如果参数列表中的json文档之间属性没有交集,则两个函数表现一致;否则,json_merge_preserve将相同键的值组成数组值,如果已经有数组值,则组合进这个数组或者将数组连接起来;重要的是如果第二个文档中某个属性为null并且第一个文档中有此属性,则结果中无此属性。
JSON _ MERGE _ PATCH ()移除第一个对象中的任何成员,并在第二个对象中使用匹配的键,前提是与第二个对象中的键关联的值不为 JSON null。
- 对于json数组
json_merge_patch用第二个文档覆盖了第一个文档;json_merge_preserve仍旧是组合起来
路径表达式和搜索
路径表达式对于提取部分 JSON 文档或修改 JSON 文档的函数非常有用,路径语法使用一个前导 $字符来表示正在考虑的 JSON 文档。
SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
SELECT JSON_SET('"x"', '$[0]', 'a');
[ N ] 附加到选择数组的路径
[M to N] 指定数组值的子集或范围
路径可以包含*或通配符**
- . [ * ]计算 JSON 对象中所有成员的值。
- [ * ]计算 JSON 数组中所有元素的值。
- prefix**suffix 后缀计算以命名前缀开始并以命名后缀结束的所有路径。
路径包含空格
需要用引号,例如$."a fish"
last关键字
last表示最后一个元素的索引$[last-3 to last-1]
如果对非数组求值,则为元素本身
mysql> SELECT JSON_REPLACE('"Sakila"', '$[last]', 10);
+-----------------------------------------+
| JSON_REPLACE('"Sakila"', '$[last]', 10) |
+-----------------------------------------+
| 10 |
+-----------------------------------------+
修改
JSON _ SET ()替换现有路径的值,并为不存在的路径添加值
JSON _ INSERT ()添加新值,但不替换现有值,如果该位置已有值,则不操作原值,忽略新值
JSON _ REPLACE ()替换现有值并忽略新值
JSON _ REMOVE ()返回原始文档中删除减去一个 JSON 文档和一个或多个路径选择的值
比较和排序
可以使用 = 、 < 、 < = 、 > 、 > = 、 < > 、 ! = 和 < = > 运算符比较 JSON 值
<=>是null-safe相等比较,对于有null值的比较不会返回null
"不支持"between、in、greatest(最大)、least(最小),但是经过本人测试,是支持的。
官方文档原文为
A workaround for the comparison operators and functions just listed is to cast JSON values to a native MySQL numeric or string data type so they have a consistent non-JSON scalar type.
貌似意思是说,对于数值类型和字符串类型是支持上述比较操作的
如果类型不同,则比较结果仅由具有较高优先级的类型确定
类型名称是由 JSON _ TYPE ()函数返回的名称。在一行中一起显示的类型具有相同的优先级
BLOB
BIT
OPAQUE
DATETIME
TIME
DATE
BOOLEAN
ARRAY
OBJECT
STRING
INTEGER, DOUBLE(整数都被转换为 DOUBLE)
NULL
转换
转换规则
- 隐式转换为utf8mb4然后解析为json值;反过来json转为字符串
- NULL转为null
- 几何类型通过调用ST_AsGeoJSON()函数
- 其他类型,生成一个由单个标量值组成的 JSON 文档;反过来如果 JSON 文档由目标类型的单个标量值组成,该标量值可以强制转换为目标类型。否则,返回NULL并发出警告
应用举例
ORDER BY CAST(JSON_EXTRACT(jdoc, '$.id') AS UNSIGNED)
聚合
对于 JSON 值的聚合,SQLNULL 值与其他数据类型一样被忽略。除了 MIN ()、 MAX ()和 GROUP _ CONCAT ()之外,非 NULL 值被转换为数值类型并进行聚合。对于数值标量的 JSON 值,转换为 number 应该会产生有意义的结果,尽管(取决于值)可能会发生截断和精度损失。转换为其他 JSON 值的数量可能不会产生有意义的结果。
注意点
- JSON对象中的 null、true、false必须小写
- 特殊字符需要\转义,文本形式插入需要\转义
mysql> INSERT INTO facts VALUES > (JSON_OBJECT("mascot", "Our mascot is a dolphin named \"Sakila\".")); mysql> INSERT INTO facts VALUES > ('{"mascot": "Our mascot is a dolphin named \\"Sakila\\"."}');
【完结】