官方文档地址【译自】:
https://dev.mysql.com/doc/refman/8.0/en/json.html
从MySQL 5.7.8开始,MySQL支持存储JSON数据类型。 与将JSON格式的字符串存储在字符串列中相比,JSON数据类型具有以下优点:
-
自动验证存储在JSON列中的JSON文档。 无效的文档会产生错误。
-
优化的存储格式。 存储在JSON列中的JSON文档将转换为内部格式,以允许快速读取文档元素。 当服务器稍后必须读取以该二进制格式存储的JSON值时,则无需从文本表示形式解析该值。 二进制格式的结构使服务器可以直接通过键或数组索引查找子对象或嵌套值,而无需读取文档中它们之前或之后的所有值。
在MySQL 8.0.13之前,JSON列不能具有非NULL的默认值。
创建 JSON 列
创建 JSON 列 sql,列数据类型使用 “JSON”:
CREATE TABLE t1 (jdoc JSON);
JSON 列中存储的是数组时,使用“[]”,元素用英文逗号隔开,结构如下:
["abc", 10, null, true, false]
JSON 列中存储 key-value 键值对时,结构如下:
{"k1": "value", "k2": 10}
如上面示例所示,JSON数组和对象可以包含字符串或数字的值,JSON空null 或 JSON布尔值true或false。 JSON对象中的键必须是字符串。 还允许使用时间(日期,时间或日期时间)值:
["12:18:29.000000", "2015-07-29", "2015-07-29 12:18:29.000000"]
当然嵌套也是可以的:
[99, {"id": "HK500", "cost": 75.99}, ["hot", "cold"]]
{"k1": "value", "k2": [10, 20]}
MySQL 中提供了一些
函数
,可以返回JSON数据;也可以使用
CAST(value AS)
将其他类型的值转换为JSON类型 。
在MySQL中,JSON值被编写为字符串。 MySQL会解析在需要JSON值的上下文中使用的任何字符串,如果该字符串无法解析为正确的JSON,则会产生错误。 这些上下文包括将值插入具有JSON数据类型的列中,并将参数传递给需要JSON值的函数(在MySQL JSON函数的文档中通常显示为json_doc或json_val)。
Insert 语句
如果值是有效的JSON值,尝试将值插入JSON列成功,但如果不是,则失败。如以下示例所示:
mysql> CREATE TABLE t1 (jdoc JSON);
Query OK, 0 rows affected (0.20 sec)
mysql> INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO t1 VALUES('[1, 2,');
ERROR 3140 (22032) at line 2: Invalid JSON text:
"Invalid value." at position 6 in value (or column) '[1, 2,'.
需要改为 INSERT INTO t1 VALUES('[1, 2]'); 就可以插入了。
JSON_TYPE() 函数
JSON_TYPE() 函数需要一个JSON参数,并尝试将其解析为JSON值。 如果有效,则返回值的JSON类型,否则返回错误:
mysql> SELECT JSON_TYPE('["a", "b", 1]');
+----------------------------+
| JSON_TYPE('["a", "b", 1]') |
+----------------------------+
| ARRAY |
+----------------------------+
mysql> SELECT JSON_TYPE('"hello"');
+----------------------+
| JSON_TYPE('"hello"') |
+----------------------+
| STRING |
+----------------------+
mysql> SELECT JSON_TYPE('hello');
ERROR 3146 (22032): Invalid data type for JSON data in argument 1
to function json_type; a JSON string or JSON type is required.
mysql> SELECT JSON_TYPE('{"hello":1}');
+----------------------+
| JSON_TYPE('{"hello":1}') |
+----------------------+
| OBJECT |
+----------------------+
MySQL使用utf8mb4字符集和utf8mb4_bin归类处理在JSON上下文中使用的字符串。 其他字符集中的字符串将根据需要转换为utf8mb4。 (对于ascii或utf8字符集中的字符串,不需要转换,因为ascii和utf8是utf8mb4的子集。)
可以将JSON值赋值给用户自定义的变量:
mysql> SET @j = JSON_OBJECT('key', 'value');
mysql> SELECT @j;
+------------------+
| @j |
+------------------+
| {"key": "value"} |
+------------------+
但是,用户定义的变量不能为JSON数据类型,因此尽管上例中的 @j 看起来像JSON值,并且具有与JSON值相同的字符集和排序规则,但它不具有JSON数据类型。 而是将 JSON_OBJECT() 的结果分配给变量后,将其转换为字符串。
mysql> SELECT CHARSET(@j), COLLATION(@j);
+-------------+---------------+
| CHARSET(@j) | COLLATION(@j) |
+-------------+---------------+
| utf8mb4 | utf8mb4_bin |
+-------------+---------------+
通过转换JSON值生成的字符串的字符集为utf8mb4,排序规则为utf8mb4_bin(大小写敏感)。
区分大小写也适用于JSON null,true和false文字,这些文字必须始终以
小写形式
编写:
mysql> SELECT JSON_VALID('null'), JSON_VALID('Null'), JSON_VALID('NULL');
+--------------------+--------------------+--------------------+
| JSON_VALID('null') | JSON_VALID('Null') | JSON_VALID('NULL') |
+--------------------+--------------------+--------------------+
| 1 | 0 | 0 |
+--------------------+--------------------+--------------------+
mysql> SELECT CAST('null' AS JSON);
+----------------------+
| CAST('null' AS JSON) |
+----------------------+
| null |
+----------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST('NULL' AS JSON);
ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json:
"Invalid value." at position 0 in 'NULL'.
JSON值的规范化、合并和自动包装
JSON 规范化
解析字符串并发现它是有效的JSON文档时,也会对其进行规范化。 这意味着具有与在文档后面找到的键重复的键(从左到右)的成员将被丢弃。 由以下JSON_OBJECT()调用产生的对象值仅包含第二个key1元素,因为该键名早于该值,如下所示:
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": "def", "key2": "abc"} |
+------------------------------------------------------+
将值插入JSON列时,也会执行规范化,如下所示:
mysql> CREATE TABLE t1 (c1 JSON);
mysql> INSERT INTO t1 VALUES
> ('{"x": 17, "x": "red"}'),
> ('{"x": 17, "x": "red", "x": [3, 5, 7]}');
mysql> SELECT c1 FROM t1;
+------------------+
| c1 |
+------------------+
| {"x": "red"} |
| {"x": [3, 5, 7]} |
+------------------+
RFC 7159
提出了这种“最后的重复键胜出”行为,并且大多数JavaScript解析器都实现了这种行为。 (Bug #86866, Bug #26369555)。
注意:
在 8.0.3 之前的MySQL版本中,具有与在文档前面找到的键重复的键的键的成员将被丢弃。 以下JSON_OBJECT()调用产生的对象值不包括第二个key1元素,因为该键名早于该值(如下例,'def' 被丢弃了):
mysql> SELECT JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def');
+------------------------------------------------------+
| JSON_OBJECT('key1', 1, 'key2', 'abc', 'key1', 'def') |
+------------------------------------------------------+
| {"key1": 1, "key2": "abc"} |
+------------------------------------------------------+
在 MySQL 8.0.3 之前,在向JSON列中插入值时,也会执行“第一个重复键获胜”规范化:
mysql> CREATE TABLE t1 (c1 JSON);
mysql> INSERT INTO t1 VALUES
> ('{"x": 17, "x": "red"}'),
> ('{"x": 17, "x": "red", "x": [3, 5, 7]}');
mysql> SELECT c1 FROM t1;
+-----------+
| c1 |
+-----------+
| {"x": 17} |
| {"x": 17} |
+-----------+
所以在使用JSON时,一定要注意 MySQL 的版本,特别注意 JSON 中 key 相同的情况。
MySQL还会在原始JSON文档中的键,值或元素之间舍弃多余的空格,并在显示每个逗号(,)或冒号(:)后留一个空格(或在必要时插入)。 这样做是为了提高可读性。
为了提高查找效率,MySQL还对JSON对象的键进行排序。 您应该注意,此排序的结果可能会更改,并且不能保证在各个发行版中都保持一致。
JSON 合并
MySQL 8.0.3(及更高版本)支持两种合并算法,这些算法由JSON_MERGE_PRESERVE()和JSON_MERGE_PATCH()函数实现。 它们在处理重复键的方式上有所不同:JSON_MERGE_PRESERVE()保留重复键的值,而JSON_MERGE_PATCH()丢弃除最后一个值以外的所有值。 接下来的几段说明了这两个函数中的每个函数如何处理JSON文档(即对象和数组)的不同组合的合并。
注意:
JSON_MERGE_PRESERVE()与早期版本的MySQL(在MySQL 8.0.3中重命名)中的JSON_MERGE()函数相同。 在MySQL 8.0中,仍支持将JSON_MERGE()作为JSON_MERGE_PRESERVE()的别名,但不建议使用JSON_MERGE()并在将来的发行版中将其删除。
合并数组
。 在组合多个数组的上下文中,这些数组将合并为一个数组。 JSON_MERGE_PRESERVE()通过将稍后命名的数组连接到第一个数组的末尾来实现此目的。 JSON_MERGE_PATCH()将每个参数视为由单个元素组成的数组(因此其索引为0),然后应用“最后重复键获胜”逻辑仅选择最后一个参数。 您可以比较此查询显示的结果:
mysql> SELECT
-> JSON_MERGE_PRESERVE('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Preserve,
-> JSON_MERGE_PATCH('[1, 2]', '["a", "b", "c"]', '[true, false]') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2, "a", "b", "c", true, false]
Patch: [true, false]
合并对象
。合并时,多个对象将产生一个对象。 JSON_MERGE_PRESERVE()通过组合数组中该键的所有唯一值来处理具有相同键的多个对象; 然后将此数组用作结果中该键的值。 JSON_MERGE_PATCH()会从左到右丢弃找到重复键的值,以便结果仅包含该键的最后一个值。以下查询说明重复键 a 的结果差异:
mysql> SELECT
-> JSON_MERGE_PRESERVE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Preserve,
-> JSON_MERGE_PATCH('{"a": 3, "b": 2}', '{"c": 3, "a": 4}', '{"c": 5, "d": 3}') AS Patch\G
*************************** 1. row ***************************
Preserve: {"a": [1, 4], "b": 2, "c": [3, 5], "d": 3}
Patch: {"a": 4, "b": 2, "c": 5, "d": 3}
在需要数组值的上下文中使用的非数组值将自动包装:该值由[和]字符包围,以将其转换为数组。 在以下语句中,每个参数都自动包装为数组([1],[2])。 然后将它们合并以生成单个结果数组。 与前两种情况一样,JSON_MERGE_PRESERVE()合并具有相同键的值,而JSON_MERGE_PATCH()丢弃除最后一个键之外的所有重复键的值,如下所示:
mysql> SELECT
-> JSON_MERGE_PRESERVE('1', '2') AS Preserve,
-> JSON_MERGE_PATCH('1', '2') AS Patch\G
*************************** 1. row ***************************
Preserve: [1, 2]
Patch: 2
可以通过将对象自动包装为数组,然后通过合并值或通过根据合并函数(分别为JSON_MERGE_PRESERVE()或JSON_MERGE_PATCH())选择“最后重复键赢”来合并数组来合并数组和对象值。 在此示例中看到:
mysql> SELECT
-> JSON_MERGE_PRESERVE('[10, 20]', '{"a": "x", "b": "y"}') AS Preserve,
-> JSON_MERGE_PATCH('[10, 20]', '{"a": "x", "b": "y"}') AS Patch\G
*************************** 1. row ***************************
Preserve: [10, 20, {"a": "x", "b": "y"}]
Patch: {"a": "x", "b": "y"}
查找和修改 JSON 值
JSON路径表达式选择JSON文本中的值。
使用路径表达式对于提取JSON文档的一部分或修改JSON文档以指定在该文档中的何处进行操作的函数很有用。 例如,以下查询从JSON文本中提取具有名称键的成员的值:
mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan" |
+---------------------------------------------------------+
路径语法使用前导 $ 字符表示所考虑的JSON文本,还可以选择后面跟有选择器,这些选择器依次指示文本中更具体的部分:
.[*]
返回JSON对象中所有成员的值;
[*] 返回JSON数组中所有元素的值。
prefix ** suffix 匹配所有命名以prefix前缀开头并以命名suffix后缀结尾的路径。
-
JSON文本中不存在的路径(匹配不到)返回为NULL。
[3, {"a": [5, 6], "b": 10}, [99, 100]]
$[0]等于3。
$[1]的取值为{“ a”:[5,6],“ b”:10}。
$[2]的取值为[99,100]。
$[3]计算结果为NULL(它引用第四个数组元素,该元素不存在)。
因为$ [1]和$ [2]计算为非标量值(是数组),所以它们可以用作选择嵌套值的更特定路径表达式的基础。 例子:
$[1].a的值为[5,6]。
$[1].a [1]的计算结果为6。
$[1].b的值为10。
$[2][0]的计算结果为99。
如前所述,如果未加引号的键名在路径表达式中不合法,则必须用引号命名路径的组件。 让$引用此值:
{"a fish": "shark", "a bird": "sparrow"}
上例中键都包含一个空格,并且必须用引号引起来:
$."a fish" 的值为shark.
$."a bird" 的值为sparrow
使用通配符的路径求值的数组可以包含多个值:
mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
+---------------------------------------------------------+
| [1, 2, [3, 4, 5]] |
+---------------------------------------------------------+
mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
+------------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
+------------------------------------------------------------+
| [3, 4, 5] |
+------------------------------------------------------------+
JSON数组的范围
。 您可以将范围与to关键字一起使用以指定JSON数组的子集。 例如,$ [1至3]包含数组的第二,第三和第四个元素,如下所示:
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]');
+----------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]') |
+----------------------------------------------+
| [2, 3, 4] |
+----------------------------------------------+
1 row in set (0.00 sec)
语法是M to N,其中M和N分别是JSON数组中元素范围的第一个和最后一个索引。 N必须大于M; M必须大于或等于0。数组元素的索引从0开始。
您可以在支持通配符的上下文中使用范围。
最右边的数组元素
。 支持使用last关键字作为数组中最后一个元素的索引的同义词。 last-N形式的表达式可以用于相对寻址,并且可以在范围定义内使用,例如:
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]');
+--------------------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]') |
+--------------------------------------------------------+
| [2, 3, 4] |
+--------------------------------------------------------+
1 row in set (0.01 sec)
您可以使用带有JSON列标识符和JSON路径表达式的column-> path作为JSON_EXTRACT(column,path)的同义词。 有关更多信息,请参见第12.18.3节“
搜索JSON值的函数
”。 另请参见
索引生成的列以提供JSON列索引
。
表 t1 中的列 c1 为JSON类型,存储值为 {"x":"red"},查询时以下是等价的,返回
"red"
:
select c1->'$.x' from t1;
select JSON_EXTRACT(c1, '$.x') from t1;
某些函数采用现有的JSON文档,以某种方式对其进行修改,然后返回生成的修改后的文档。 路径表达式指示在文档中的何处进行更改。 例如,JSON_SET(),JSON_INSERT()和JSON_REPLACE()函数每个都获取一个JSON文档,以及一个或多个描述文档在何处修改的路径值对以及要使用的值。 这些功能在如何处理文档中现有和不存在的值方面有所不同。
JSON路径语法
MySQL支持并在本手册的其他地方介绍的许多JSON函数(请参见
第12.18节“ JSON函数”
)要求使用路径表达式来标识JSON文档中的特定元素。 路径由路径的范围和一个或多个路径分支组成。 对于MySQL JSON函数中使用的路径,范围始终是要搜索或对其进行操作的文档,并以前导$字符表示。 路径分支由句点字符(.)分隔。 数组中的单元格由[N]表示,其中N是非负整数。 键名必须为双引号字符串或有效的ECMAScript标识符(请参阅
ECMAScript语言规范中的标识符名称和标识符
)。 路径表达式(如JSON文本)应使用ascii,utf8或utf8mb4字符集进行编码。 其他字符编码被隐式强制为utf8mb4。 完整的语法如下所示:
pathExpression:
scope[(pathLeg)*]
pathLeg:
member | arrayLocation | doubleAsterisk
member:
period ( keyName | asterisk )
arrayLocation:
leftBracket ( nonNegativeInteger | asterisk ) rightBracket
keyName:
ESIdentifier | doubleQuotedString
doubleAsterisk:
period:
asterisk:
leftBracket:
rightBracket:
MySQL 8.0.2和更高版本还支持使用 to 关键字(例如$ [2至10])以及 last 关键字作为数组最右边元素的同义词,来表示JSON数组子集的范围符号。 有关更多信息和示例,请参见搜索和修改JSON值。
JSON值的比较和排序
可以使用=,<,<=,>,> =,<>,!= 和 <=> 运算符比较JSON值。
JSON值尚不支持以下比较运算符和函数:
上面列出的比较运算符和函数的解决方法是将JSON值转换为本地MySQL数字或字符串数据类型,以便它们具有一致的非JSON标量类型。
JSON值的比较分为两个级别。 比较的第一级基于比较值的JSON类型。 如果类型不同,则比较结果仅由优先级更高的类型确定。 如果两个值具有相同的JSON类型,则使用特定于类型的规则进行第二级比较。
以下列表显示了JSON类型的优先级,从最高优先级到最低优先级。 (类型名称是JSON_TYPE()函数返回的名称。)在一行上一起显示的类型具有相同的优先级。 列表前面列出的JSON类型的任何值的比较都比列表后面列出的JSON类型的任何值的比较大。
OPAQUE
DATETIME
BOOLEAN
ARRAY
OBJECT
STRING
INTEGER, DOUBLE
对于具有相同优先级的JSON值,比较规则是特定于类型的:
比较两个值的前N个字节,其中N是较短值中的字节数。 如果两个值的前N个字节相同,则较短的值将排序在较长的值之前。
与BLOB的规则相同。
与BLOB的规则相同。 OPAQUE值是未归类为其他类型之一的值。
表示较早时间点的值先于表示较晚时间点的值排序。 如果两个值最初分别来自MySQL DATETIME和TIMESTAMP类型,则如果它们表示相同的时间点,则它们相等。
两个时间值中较小的一个先于较大的一个。
较早的日期在较新的日期之前排序。
如果两个JSON数组的长度相同并且数组中对应位置的值相等,则它们相等。
如果数组不相等,则它们的顺序由存在差异的第一个位置的元素确定。 在该位置具有较小值的数组将首先排序。 如果较短数组的所有值都等于较长数组中的相应值,则首先对较短数组进行排序。
[] < ["a"] < ["ab"] < ["ab", "cd", "ef"] < ["ab", "ef"]
JSON false 小于 JSON true。
如果两个JSON对象具有相同的键集,并且两个键中的每个键具有相同的值,则它们相等。
{"a": 1, "b": 2} = {"b": 2, "a": 1}
The order of two objects that are not equal is unspecified but deterministic.(两个不相等对象的顺序是不确定的,但是确定性的。???)
字符串在要比较的两个字符串的utf8mb4表示的前N个字节上按词法排序,其中N是较短字符串的长度。 如果两个字符串的前N个字节相同,则较短的字符串被认为小于较长的字符串。
"a" < "ab" < "b" < "bc"
此排序等效于排序规则为utf8mb4_bin的SQL字符串的排序。 因为utf8mb4_bin是二进制排序规则,所以JSON值的比较区分大小写:
"A" < "a"
JSON值可以包含精确值数字和近似值数字。 有关这些类型的数字的一般讨论,请参见第9.1.2节
“Numeric Literals”.。
第12.3节“表达式求值中的类型转换”中讨论了比较原生MySQL数字类型的规则,但是在JSON值中比较数字的规则有些不同:
- 在分别使用原生MySQL INT和DOUBLE数值类型的两列之间的比较中,已知所有比较都涉及一个整数和一个双精度数,因此对于所有行,该整数都将转换为双精度数。 即,将精确值数字转换为近似值数字。
- 另一方面,如果查询比较两个包含数字的JSON列,则无法事先知道数字是整数还是双精度。 为了在所有行中提供最一致的行为,MySQL将近似值数字转换为精确值数字。 所得的顺序是一致的,并且不会丢失精确值数字的精度。 例如,给定标量9223372036854775805、9223372036854775806、9223372036854775807和9.223372036854776e18,顺序如下:
9223372036854775805 < 9223372036854775806 < 9223372036854775807
< 9.223372036854776e18 = 9223372036854776000 < 9223372036854776001
如果是JSON比较使用非JSON数字比较规则,则可能会出现不一致的顺序。 常用的MySQL数字比较规则产生以下顺序:
9223372036854775805 < 9223372036854775806 < 9223372036854775807
9223372036854775805 = 9223372036854775806 = 9223372036854775807 = 9.223372036854776e18
对于将任何JSON值与SQL NULL进行比较,结果为UNKNOWN。
比较JSON和非JSON值,将根据下表中的规则将非JSON值转换为JSON,然后按照前面所述比较这些值。
在JSON和非JSON值之间转换
下表概述了在JSON值和其他类型的值之间进行转换时MySQL遵循的规则:
表11.3 JSON转换规则:
other type | CAST(other type AS JSON) | CAST(JSON AS other type) |
JSON | 不变 | 不变 |
utf8 字符类型 (utf8mb4 , utf8 , ascii ) | 该字符串将解析为JSON值 | JSON值被序列化为utf8mb4字符串 |
其他字符类型 | 其他字符编码将隐式转换为utf8mb4,并按utf8字符类型所述进行处理。 | JSON值被序列化为utf8mb4字符串,然后转换为其他字符编码。 结果可能没有意义。 |
NULL | 结果为 JSON 类型的NULL值 | 不适用 |
Geometry 类型 | 通过调用ST_AsGeoJSON()将几何值转换为JSON文本。 | 非法操作。 解决方法:将CAST(json_val AS CHAR)的结果传递给ST_GeomFromGeoJSON()。 |
所有其它类型 | 结果生成一个由单个标量值组成的JSON文本 | 如果JSON文本由目标类型的单个标量值组成,并且该标量值可以转换为目标类型,则成功。 否则,返回NULL并产生警告。 |
JSON值的 ORDER BY 和 GROUP BY 根据以下原则工作:
- 标量JSON值的排序使用与前面的讨论相同的规则。
- 对于升序排序,SQL NULL在所有JSON值(包括JSON null)之前排序。 对于降序排序,SQL NULL在所有JSON值(包括JSON null)之后进行排序。
- Sort keys for JSON values are bound by the value of the
max_sort_length
system variable, so keys that differ only after the first max_sort_length
bytes compare as equal. ??? - 当前不支持对非标量值进行排序,并且会出现警告。
对于排序,将JSON标量转换为其他一些原生 MySQL 类型可能是有益的。 例如,如果名为jdoc的列包含具有对象的JSON对象,该对象的成员由id键和一个非负值组成,请使用此表达式按id值排序:
ORDER BY CAST(JSON_EXTRACT(jdoc, '$.id') AS UNSIGNED)
如果碰巧有一个生成的列被定义为使用与ORDER BY中相同的表达式,则MySQL优化器将识别出该列,并考虑将索引用于查询执行计划。 请参见第8.3.11节“优化使用生成的列索引”。
JSON值聚合
对于JSON值的聚合,与其他数据类型一样,将忽略SQL NULL值。 非NULL值将转换为数字类型并进行汇总,但MIN(),MAX()和GROUP_CONCAT()除外。 尽管可能会发生截断和精度损失(取决于值),但转换为数字应该为数字标量的JSON值才产生有意义的结果。 转换为其他JSON值的数字可能不会产生有意义的结果。
目录前言 创建 JSON 列Insert 语句JSON_TYPE() 函数JSON值的规范化、合并和自动包装JSON 规范化JSON 合并查找和修改 JSON 值JSON路径语法JSON值的比较和排序在JSON和非JSON值之间转换JSON值聚合官方文档地址【译自】:https://dev.mysql.com/doc/refman/8.0/en/json.html前言 从MySQL 5.7.8开始,MySQL支...
11.10.11 JSON_TYPE(json_val)函数
JSON_TYPE(json_val)函数用于返回JSON数据的JSON类型,MySQL中支持的JSON类型除了可以是MySQL中的数据类型外,还可以是OBJECT和ARRAY类型,其中OBJECT表示JSON对象,ARRAY表示JSON数组。使用示例如下:
mysql> SELECT JSON_TYPE(cont...
mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据时,还是比较别扭的。
创建一个JSON字段的表
首先先创建一个表,这个表包含一个json格式的字段:
CREATE TABLE table_name (
id INT NOT NULL AUTO_INCREMENT,
json_col JSON,
PRIMARY K
JSON 数据类型是
MySQL 5.7.8 开始支持的。在此之前,只能通过字符类型(CHAR,VARCHAR 或 TEXT )来保存
JSON 文档。
相对字符类型,原生的
JSON 类型具有以下优势:
在插入时能自动校验文档是否满足
JSON 格式的要求。
优化了存储格式。无需读取整个文档就能快速访问某个元素的值。
在
JSON 类型引入之前,如果我们想要获取
JSON 文档
中的某个元素,必须首先读取整个
JSON 文档,然后在客户端将其转换为
JSON 对象,最后再通过对象获取指定元素的值。
【MySQL】对JSON数据操作(全网最全)
总所周知,mysql5.7以上提供了一种新的字段格式-json,大概是mysql想把非关系型和关系型数据库一口通吃,所以推出了这种非常好用的格式,这样,我们的很多基于mongoDb或者clickHouse的业务都可以用mysql去实现了。当然了,5.7的版本只是最基础的版本,对于海量数据的效率是远远不够的,不过这些都在mysql8.0解决了。今天我们就针对mysql的json数据格式操作做一个简单的介绍。
如何创建json格式字段
这里我们先创建一个简单的
MySQL:Data truncation: Invalid JSON text: “Invalid value.“ at position 1 in value for column
在 MySQL 中,您可以使用函数 `json_extract` 处理 JSON 类型的数据。该函数接受两个参数:第一个参数是包含 JSON 数据的列,第二个参数是用于提取 JSON 数据的路径表达式。
例如,假设有一张名为 `mytable` 的表格,其中有一个名为 `mycolumn` 的列包含以下 JSON 数据:
```json
"name": "John Smith",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
要提取此 JSON 数据中的 `name` 字段,您可以使用以下查询:
```sql
SELECT json_extract(mycolumn, '$.name') FROM mytable;
此查询将返回 `John Smith`。要提取地址信息,您可以使用以下查询:
```sql
SELECT json_extract(mycolumn, '$.address') FROM mytable;
此查询将返回以下 JSON 数据:
```json
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
希望这可以帮助您开始使用 `json_extract` 函数处理 MySQL 中的 JSON 数据。