从MySQL 8.0.17开始,MySQL支持符合JSON模式的JSON文档验证JSON模式规范草案4.这可以使用本节中详述的任何一个功能来完成,其中两者都采取两个参数,JSON模式和JSON文档,该文档是针对架构验证的。json_schema_valid()
如果文档验证架构,则返回true,如果没有,则为false;json_schema_validation_report()
在验证上以JSON格式提供报告。
两个函数处理null或无效输入如下:
如果至少有一个参数是
空值
,函数返回空值
.如果至少有一个参数不是有效的JSON,函数将引发错误(
er_invalid_type_for_json.
)此外,如果架构不是有效的JSON对象,则函数返回
er_invalid_json_type.
.
MySQL支持这一点要求
在JSON模式中的属性以强制包含所需属性(请参阅功能描述中的示例)。
MySQL支持这一点id
那$架构
那描述
, 和类型
JSON Schemas中的属性但不需要任何一个。
MySQL不支持JSON模式中的外部资源;使用$ ref.
关键字的原因json_schema_valid()
失败er_not_supported_yet.
.
MySQL支持JSON架构中的正则表达式模式,该模式支持,但默默地忽略无效模式(请参阅描述json_schema_valid()
例如)。
这些函数的详细描述如下:
验证JSON.
文档
反对json.架构
.两个都架构
和文档
是必需的。架构必须是有效的JSON对象;该文档必须是有效的JSON文档。如果满足这些条件:如果文档验证架构,则函数返回true(1);否则,它返回false(0)。在本例中,我们设置了一个用户变量
@Schema.
对于地理坐标的JSON模式的值,另一个@document
到包含一个这样的坐标的JSON文档的值。然后我们验证@document
根据验证@Schema.
用它们作为参数json_schema_valid()
:mysql >设置@schema = '{ '> " id”:“http://json-schema.org/geo”,”>“美元模式”:“http://json-schema.org/draft-04/schema”,“>”的描述:“地理坐标”,”>“类型”:“对象”,”>“属性”:{”>“纬度”:{”>“类型”:“数量”,”>“最低”:-90年,”>“最大”:90 '> }, '> " 经度”:{”>“类型”:“数量”,”>“最小值”:-180 >“最大”:180 '> } '> }, '> " 要求”:【“纬度”、“经度”】“>}”;mysql> SET @document = '{'> "latitude": 63.444697, '> "longitude": 10.445118 '>}';查询OK, 0 rows affected (0.00 sec) mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);+---------------------------------------+ | JSON_SCHEMA_VALID (@schema @document ) | +---------------------------------------+ | 1 | +---------------------------------------+ 1行集(0.00秒)
自从
@Schema.
包含要求
属性,我们可以设置@document
到其他有效但不包含所需属性的值,然后测试它@Schema.
像这样:mysql> set @document ='{}';查询OK, 0 rows affected (0.00 sec) mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);+ ---------------------------------- + |json_schema_valid(@schema,@document)|+ ---------------------------------- + |0 |+ ------------------------------------ + 1行(0.00秒)
如果我们现在设置价值
@Schema.
到同一个json架构但没有要求
属性,@document
验证是因为它是一个有效的JSON对象,即使它不包含任何属性,如图所示:mysql >设置@schema = '{ '> " id”:“http://json-schema.org/geo”,”>“美元模式”:“http://json-schema.org/draft-04/schema”,“>”的描述:“地理坐标”,”>“类型”:“对象”,”>“属性”:{”>“纬度”:{”>“类型”:“数量”,”>“最低”:-90年,”>“最大”:90 '> }, '> " 经度”:{”>“类型”:“数量”,”>“最小值”:-180, '> "maximum": 180 '> } '> } '>}'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT JSON_SCHEMA_VALID(@schema, @document); +---------------------------------------+ | JSON_SCHEMA_VALID(@schema, @document) | +---------------------------------------+ | 1 | +---------------------------------------+ 1 row in set (0.00 sec)
JSON_SCHEMA_VALID()和CHECK约束。
json_schema_valid()
也可以用来强制执行吗检查
约束。考虑表格
地理
如下所示,创建了一个JSON列协调
表示地图上的纬度和经度点,由用作参数的JSON模式管理json_schema_valid()
调用,它作为表达式传递检查
对此表的约束:MySQL>创建表Geo( - >坐标JSON, - >检查( - > JSON_SCHEMA_VALID( - >'{'>“类型”:“对象”,'>“属性”:{'>“纬度”:{“类型”:“数字”,“最小”: - 90,“最大”:90},'>“经度”:{“类型”:“编号”,“最小”: - 180,“最大”:180}'>},'>“必填”:[“纬度”,“经度”]'>}', - >坐标 - >) - >) - >);查询OK,影响0行(0.45秒)
笔记因为一个mysql.
检查
约束不能包含对变量的引用,必须将JSON模式传递给json_schema_valid()
在线使用它来指定表的此类约束。我们指定表示坐标的JSON值为三个变量,如下所示:
mysql> set @ point1 ='{“纬度”:59,“经度”:18}';查询OK,0行受影响(0.00秒)mysql> set @ point2 ='{“纬度”:91,“经度”:0}';查询确定,0行受影响(0.00秒)MySQL> SET @ POINT3 ='{“经度”:120}';查询OK,影响0行(0.00秒)
第一个值是有效的,如下所示
插
声明:MySQL>插入Geo值(@ point1);查询OK,1行受影响(0.05秒)
第二个JSON值无效,因此无法满足约束,如下所示:
MySQL>插入Geo值(@ point2);错误3819(HY000):禁止检查约束“GEO_CHK_1”。
在MySQL 8.0.19及更高版本中,您可以获得有关失败性质的精确信息 - 在这种情况下,即
纬度
值超出架构中定义的最大值通过发出a显示警告
声明:MySQL> Show Warnings \ G *************************** 1.行***************************级别:错误代码:3934消息:JSON文档位置'#/纬度'在JSON架构位置'#/属性/纬度'的“最大”。*************************** 2.行***************************级别:错误代码:3819消息:检查约束'geo_chk_1'被禁止。套装2行(0.00秒)
上面定义的第三个坐标值也无效,因为它缺少所需的
纬度
财产。如前所述,您可以通过尝试将值插入到中来看地理
表,然后发出显示警告
之后:mysql>插入Geo值(@ point3);错误3819(HY000):禁止检查约束“GEO_CHK_1”。MySQL> Show Warnings \ G *************************** 1.行***************************级别:错误代码:3934消息:JSON文档位置'#'所需的失败要求在JSON Schema位置'#'。*************************** 2.行***************************级别:错误代码:3819消息:检查约束'geo_chk_1'被禁止。套装2行(0.00秒)
看第13.1.20.6节“检查约束”,以获取更多信息。
JSON架构支持为字符串指定正则表达式模式,但MySQL使用的实现默默地忽略无效模式。这意味着
json_schema_valid()
即使正常表达式模式无效,也可以返回TRUE,如下所示:mysql>选择json_schema_valid('{“类型”:“字符串”,“模式”:“(”}“,'ABC”'); + -------------------------------------------------------- + | json_schema_valid('{“类型”:“字符串”,“模式”:“(”}“,”abc“')| + ---------------------------------------------------------- + | 1 | + ----------------------------------------------------------------------------- + 1行(0.04秒)
json_schema_validation_report(
架构
那文档
)验证JSON.
文档
反对json.架构
.两个都架构
和文档
是必需的。与JSON_VALID_SCHEMA()一样,模式必须是一个有效的JSON对象,文档必须是一个有效的JSON文档。如果满足这些条件,该函数将返回一个关于验证结果的报告(作为JSON文档)。如果根据JSON Schema认为JSON文档是有效的,则该函数返回一个具有一个属性的JSON对象有效的
具有“真实”的价值。如果JSON文档失败验证,则该函数返回一个JSON对象,其中包括以下列出的属性:有效的
:始终为失败的架构验证“假”原因
:包含失败原因的人类可读字符串模式位置
:JSON指针URI片段标识符,指示JSON Schema在验证失败的位置(参见此列表的注意事项)文件位置
:JSON指针URI片段标识符,指示JSON文档中的验证失败(参见此列表的注意)schema-failed-keyword
:一个字符串,包含违反JSON架构中的关键字或属性的名称
笔记中定义的JSON指针URI片段标识符RFC 6901 - JavaScript对象表示法(JSON)指针.(这些都是不是与JSON路径表示法相同
json_extract()
和其他mysql json函数。)在这个表示法中,#
代表整个文件,和#/ myprop.
表示名为顶级属性中包含的文档的一部分myprop.
.请参阅刚刚引用的规范以及此部分稍后显示的示例以获取更多信息。在本例中,我们设置了一个用户变量
@Schema.
对于地理坐标的JSON模式的值,另一个@document
到包含一个这样的坐标的JSON文档的值。然后我们验证@document
根据验证@Schema.
用它们作为参数json_schema_validation_reort()
:mysql >设置@schema = '{ '> " id”:“http://json-schema.org/geo”,”>“美元模式”:“http://json-schema.org/draft-04/schema”,“>”的描述:“地理坐标”,”>“类型”:“对象”,”>“属性”:{”>“纬度”:{”>“类型”:“数量”,”>“最低”:-90年,”>“最大”:90 '> }, '> " 经度”:{”>“类型”:“数量”,”>“最小值”:-180 >“最大”:180 '> } '> }, '> " 要求”:【“纬度”、“经度”】“>}”;mysql> SET @document = '{'> "latitude": 63.444697, '> "longitude": 10.445118 '>}';查询确定,0行受影响(0.00 sec)mysql> select json_schema_validation_report(@schema,@document);+ ------------------------------------------- + |json_schema_validation_report(@schema,@document)|+ ------------------------------------------- + |{“有效”:真实} |+ ------------------------------------------- + 1行集合(0.00秒)
现在我们组
@document
这样它指定了一个属性的非法值,如下所示:mysql> SET @document = '{'> "latitude": 63.444697, '> "longitude": 310.445118 '>}';
的验证
@document
测试时失败json_schema_validation_report()
.函数调用的输出包含关于失败的详细信息(函数由json_pretty()
为了提供更好的格式),如下所示:mysql >选择JSON_PRETTY (JSON_SCHEMA_VALIDATION_REPORT (@schema @document)) \ G *************************** 1。JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)): {"valid": false, "reason": "The JSON document location '#/longitude' failed requirement 'maximum' at JSON Schema location '#/properties/longitude'", " Schema -location": "#/properties/longitude", "document-location":"#/longitude", "schema-failed-keyword": "maximum"}
自从
@Schema.
包含要求
属性,我们可以设置@document
到其他有效但不包含所需属性的值,然后测试它@Schema.
.输出json_schema_validation_report()
显示验证因缺少所需元素而失败,如下所示:mysql> set @document ='{}';查询确定,0行受影响(0.00秒)mysql>选择json_pretty(json_schema_validation_report(@schema,@document))\ g ******************************************* 1.行*************************** json_pretty(json_schema_validation_report(@schema,@document)):{“有效”:False,“原因”:“JSON文档位置'#'失败的要求在JSON Schema Location”#“,”架构位置“:”#“,”文档位置“:”#“,”架构“#”,“架构”-Failed-关键字“:”必需的“}}设置为1行(0.00秒)
如果我们现在设置价值
@Schema.
到同一个json架构但没有要求
属性,@document
验证是因为它是一个有效的JSON对象,即使它不包含任何属性,如图所示:mysql >设置@schema = '{ '> " id”:“http://json-schema.org/geo”,”>“美元模式”:“http://json-schema.org/draft-04/schema”,“>”的描述:“地理坐标”,”>“类型”:“对象”,”>“属性”:{”>“纬度”:{”>“类型”:“数量”,”>“最低”:-90年,”>“最大”:90 '> }, '> " 经度”:{”>“类型”:“数量”,”>“最小值”:-180, '> "maximum": 180 '> } '> } '>}'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document); +---------------------------------------------------+ | JSON_SCHEMA_VALIDATION_REPORT(@schema, @document) | +---------------------------------------------------+ | {"valid": true} | +---------------------------------------------------+ 1 row in set (0.00 sec)