从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支持这一点要求
属性,以强制包含必需的属性(参见函数描述中的示例)。
MySQL支持这一点id
,$架构
,描述
, 和类型
属性,但不需要任何这些。
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 '>}' >}' >}';查询OK, 0 rows affected (0.00 sec) mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);+---------------------------------------+ | JSON_SCHEMA_VALID (@schema @document ) | +---------------------------------------+ | 1 | +---------------------------------------+ 1行集(0.00秒)
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> INSERT INTO geo VALUES(@point1);查询OK,影响1行(0.05秒)
第二个JSON值无效,因此无法满足约束,如下所示:
mysql> INSERT INTO geo VALUES(@point2);ERROR 3819 (HY000): Check constraint 'geo_chk_1' is违犯。
在MySQL 8.0.19及更高版本中,您可以获得有关失败性质的精确信息 - 在这种情况下,即
纬度
值超出架构中定义的最大值通过发出a显示警告
声明:MySQL> Show Warnings \ G *************************** 1.行***************************级别:错误代码:3934消息:JSON文档位置'#/纬度'在JSON架构位置'#/属性/纬度'的“最大”。*************************** 2.行***************************级别:错误代码:3819消息:检查约束'geo_chk_1'被禁止。套装2行(0.00秒)
上面定义的第三个坐标值也无效,因为它缺少所需的
纬度
财产。如前所述,您可以通过尝试将值插入到中来看地理
表,然后发出显示警告
之后:mysql>插入Geo值(@ point3);ERROR 3819 (HY000): Check constraint 'geo_chk_1' is违犯。MySQL> Show Warnings \ G *************************** 1.行***************************级别:错误代码:3934消息:JSON文档位置'#'所需的失败要求在JSON Schema位置'#'。*************************** 2.行***************************级别:错误代码:3819消息:检查约束'geo_chk_1'被禁止。套装2行(0.00秒)
看到第13.1.20.6节“检查约束”,以获取更多信息。
JSON Schema支持为字符串指定正则表达式模式,但是MySQL使用的实现会静默地忽略无效模式。这意味着
JSON_SCHEMA_VALID ()
即使正常表达式模式无效,也可以返回TRUE,如下所示:mysql >选择JSON_SCHEMA_VALID('{“类型”:“字符串”,”模式 ":"("}', '" 美国广播公司");+---------------------------------------------------------------+ | JSON_SCHEMA_VALID('{“类型”:“字符串”,”模式 ":"("}', '" 美国广播公司 "') | +---------------------------------------------------------------+ | 1 | +---------------------------------------------------------------+ 1行集(0.04秒)
json_schema_validation_report(
模式
,文档
)验证JSON.
文档
反对json.模式
。这两个模式
和文档
是必需的。与JSON_VALID_SCHEMA()一样,模式必须是一个有效的JSON对象,文档必须是一个有效的JSON文档。如果满足这些条件,该函数将返回一个关于验证结果的报告(作为JSON文档)。如果根据JSON Schema认为JSON文档是有效的,则该函数返回一个具有一个属性的JSON对象有效的
具有“真实”的价值。如果JSON文档失败验证,则该函数返回一个JSON对象,其中包括以下列出的属性:有效的
:对于模式验证失败总是“false”原因
:包含失败原因的人类可读字符串模式位置
:一个JSON指针URI片段标识符,指示JSON模式中验证失败的位置(请参见下面的列表)文件位置
:一个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 '>}';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 '>}' >}' >}';mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document);+---------------------------------------------------+ | JSON_SCHEMA_VALIDATION_REPORT (@schema @document ) | +---------------------------------------------------+ | {" 有效”:真 } | +---------------------------------------------------+ 1行集(0.00秒)