Loading...
MySQL 9.5 Reference Manual 9.5의 14.17.7 JSON Schema Validation Functions의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL은 JSON 스키마 사양인
JSON Schema specification Draft 4에
부합하는 JSON 스키마에 대해 JSON 문서를 검증하는 기능을 지원합니다.
이는 이 섹션에 설명된 두 함수 중 하나를 사용하여 수행할 수 있으며,
두 함수 모두 JSON 스키마와, 스키마에 대해 검증할 JSON 문서
이 두 개의 인자를 받습니다.
JSON_SCHEMA_VALID()은
문서가 스키마에 대해 검증에 성공하면 true를, 실패하면 false를 반환합니다;
JSON_SCHEMA_VALIDATION_REPORT()는
검증에 대한 리포트를 JSON 형식으로 제공합니다.
두 함수는 null 또는 유효하지 않은 입력을 다음과 같이 처리합니다:
인자 중 하나 이상이 NULL인 경우,
함수는 NULL을 반환합니다.
인자 중 하나 이상이 유효한 JSON이 아니면,
함수는 에러
(ER_INVALID_TYPE_FOR_JSON)를 발생시킵니다.
추가로, 스키마가 유효한 JSON 객체가 아니면,
함수는
ER_INVALID_JSON_TYPE를 반환합니다.
MySQL은 JSON 스키마에서 필수 프로퍼티의 포함을 강제하기 위한
required 속성을 지원합니다
(함수 설명에 나오는 예제를 참고하십시오).
MySQL은 JSON 스키마에서 id,
$schema, description,
type 속성을 지원하지만,
그중 어느 것도 필수로 요구하지는 않습니다.
MySQL은 JSON 스키마에서 외부 리소스를 지원하지 않습니다;
$ref 키워드를 사용하면
JSON_SCHEMA_VALID()이
ER_NOT_SUPPORTED_YET와 함께 실패합니다.
참고
MySQL은 JSON 스키마에서 정규 표현식 패턴을 지원하며,
올바르지 않은 패턴도 지원하지만 이를 조용히 무시합니다
(예제는 JSON_SCHEMA_VALID() 설명을 참조하십시오).
이 함수들은 다음 목록에서 자세히 설명합니다:
JSON _document_를
JSON _schema_에 대해 검증합니다.
_schema_와
_document_는 모두 필수입니다.
스키마는 유효한 JSON 객체여야 하고,
문서는 유효한 JSON 문서여야 합니다.
이 조건이 만족되면: 문서가 스키마에 대해 검증에 성공하면
함수는 true (1)을 반환하고, 그렇지 않으면 false (0)을 반환합니다.
이 예제에서는 사용자 변수 @schema를
지리 좌표에 대한 JSON 스키마 값으로 설정하고,
또 다른 변수 @document를
그러한 좌표 하나를 포함하는 JSON 문서 값으로 설정합니다.
그런 다음, 이 둘을 JSON_SCHEMA_VALID()의
인자로 사용하여
@document가 @schema에 따라
검증에 성공하는지 확인합니다:
1mysql> SET @schema = '{ 2 '> "id": "http://json-schema.org/geo", 3 '> "$schema": "http://json-schema.org/draft-04/schema#", 4 '> "description": "A geographical coordinate", 5 '> "type": "object", 6 '> "properties": { 7 '> "latitude": { 8 '> "type": "number", 9 '> "minimum": -90, 10 '> "maximum": 90 11 '> }, 12 '> "longitude": { 13 '> "type": "number", 14 '> "minimum": -180, 15 '> "maximum": 180 16 '> } 17 '> }, 18 '> "required": ["latitude", "longitude"] 19 '>}'; 20Query OK, 0 rows affected (0.01 sec) 21 22mysql> SET @document = '{ 23 '> "latitude": 63.444697, 24 '> "longitude": 10.445118 25 '>}'; 26Query OK, 0 rows affected (0.00 sec) 27 28mysql> SELECT JSON_SCHEMA_VALID(@schema, @document); 29+---------------------------------------+ 30| JSON_SCHEMA_VALID(@schema, @document) | 31+---------------------------------------+ 32| 1 | 33+---------------------------------------+ 341 row in set (0.00 sec)
@schema에 required 속성이
포함되어 있으므로, 필수 프로퍼티를 포함하지 않지만
그 외에는 유효한 값으로
@document를 설정한 다음,
다음과 같이 @schema에 대해 테스트할 수 있습니다:
1mysql> SET @document = '{}'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> SELECT JSON_SCHEMA_VALID(@schema, @document); 5+---------------------------------------+ 6| JSON_SCHEMA_VALID(@schema, @document) | 7+---------------------------------------+ 8| 0 | 9+---------------------------------------+ 101 row in set (0.00 sec)
이제 @schema의 값을
같은 JSON 스키마이지만
required 속성이 없는 값으로 설정하면,
@document에는 프로퍼티가 전혀 없더라도
유효한 JSON 객체이기 때문에 검증에 성공합니다.
다음과 같이 확인할 수 있습니다:
1mysql> SET @schema = '{ 2 '> "id": "http://json-schema.org/geo", 3 '> "$schema": "http://json-schema.org/draft-04/schema#", 4 '> "description": "A geographical coordinate", 5 '> "type": "object", 6 '> "properties": { 7 '> "latitude": { 8 '> "type": "number", 9 '> "minimum": -90, 10 '> "maximum": 90 11 '> }, 12 '> "longitude": { 13 '> "type": "number", 14 '> "minimum": -180, 15 '> "maximum": 180 16 '> } 17 '> } 18 '>}'; 19Query OK, 0 rows affected (0.00 sec) 20 21 22mysql> SELECT JSON_SCHEMA_VALID(@schema, @document); 23+---------------------------------------+ 24| JSON_SCHEMA_VALID(@schema, @document) | 25+---------------------------------------+ 26| 1 | 27+---------------------------------------+ 281 row in set (0.00 sec)
JSON_SCHEMA_VALID()와 CHECK constraints.
JSON_SCHEMA_VALID()는
CHECK 제약 조건을 강제하는 데에도 사용할 수 있습니다.
다음과 같이 생성된 geo 테이블을 고려해 보십시오.
이 테이블에는 지도 상의 위도와 경도 지점을 나타내는 JSON 컬럼
coordinate가 있으며, 이 컬럼은
JSON_SCHEMA_VALID() 호출의 인자로 전달되는
JSON 스키마에 의해 제약을 받습니다.
이 호출은 이 테이블에 대한 CHECK 제약 조건의
식으로 사용됩니다:
1mysql> CREATE TABLE geo ( 2 -> coordinate JSON, 3 -> CHECK( 4 -> JSON_SCHEMA_VALID( 5 -> '{ 6 '> "type":"object", 7 '> "properties":{ 8 '> "latitude":{"type":"number", "minimum":-90, "maximum":90}, 9 '> "longitude":{"type":"number", "minimum":-180, "maximum":180} 10 '> }, 11 '> "required": ["latitude", "longitude"] 12 '> }', 13 -> coordinate 14 -> ) 15 -> ) 16 -> ); 17Query OK, 0 rows affected (0.45 sec)
참고
MySQL의 CHECK 제약 조건은
변수에 대한 참조를 포함할 수 없으므로,
테이블에 대한 이러한 제약 조건을 지정하기 위해
JSON_SCHEMA_VALID()를 사용할 때는
JSON 스키마를 인라인으로 전달해야 합니다.
다음과 같이 좌표를 나타내는 JSON 값을 세 개의 변수에 할당합니다:
1mysql> SET @point1 = '{"latitude":59, "longitude":18}'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> SET @point2 = '{"latitude":91, "longitude":0}'; 5Query OK, 0 rows affected (0.00 sec) 6 7mysql> SET @point3 = '{"longitude":120}'; 8Query OK, 0 rows affected (0.00 sec)
이 값들 중 첫 번째는 유효하며,
다음 INSERT 문에서 볼 수 있습니다:
1mysql> INSERT INTO geo VALUES(@point1); 2Query OK, 1 row affected (0.05 sec)
두 번째 JSON 값은 유효하지 않으므로 다음과 같이 제약 조건을 통과하지 못합니다:
1mysql> INSERT INTO geo VALUES(@point2); 2ERROR 3819 (HY000): Check constraint 'geo_chk_1' is violated.
이 실패의 구체적인 원인—이 경우
latitude 값이 스키마에 정의된 최대값을 초과했음을—
알기 위해서는 다음과 같이
SHOW WARNINGS 문을 실행하면 됩니다:
1mysql> SHOW WARNINGS\G 2*************************** 1. row *************************** 3 Level: Error 4 Code: 3934 5Message: The JSON document location '#/latitude' failed requirement 'maximum' at 6JSON Schema location '#/properties/latitude'. 7*************************** 2. row *************************** 8 Level: Error 9 Code: 3819 10Message: Check constraint 'geo_chk_1' is violated. 112 rows in set (0.00 sec)
위에서 정의한 세 번째 좌표 값 역시,
필수 프로퍼티인 latitude가
누락되었기 때문에 유효하지 않습니다.
이전과 마찬가지로, 이 값을 geo 테이블에
INSERT 시도 후에 SHOW WARNINGS를 실행하여 확인할 수 있습니다:
1mysql> INSERT INTO geo VALUES(@point3); 2ERROR 3819 (HY000): Check constraint 'geo_chk_1' is violated. 3mysql> SHOW WARNINGS\G 4*************************** 1. row *************************** 5 Level: Error 6 Code: 3934 7Message: The JSON document location '#' failed requirement 'required' at JSON 8Schema location '#'. 9*************************** 2. row *************************** 10 Level: Error 11 Code: 3819 12Message: Check constraint 'geo_chk_1' is violated. 132 rows in set (0.00 sec)
자세한 내용은 Section 15.1.24.6, “CHECK Constraints”를 참고하십시오.
JSON 스키마는 문자열에 대해 정규 표현식 패턴을 지정하는 기능을
지원하지만, MySQL에서 사용하는 구현은 올바르지 않은 패턴을 조용히 무시합니다.
이는 다음과 같이, 정규 표현식 패턴이 올바르지 않더라도
JSON_SCHEMA_VALID()가 true를 반환할 수 있음을 의미합니다:
1mysql> SELECT JSON_SCHEMA_VALID('{"type":"string","pattern":"("}', '"abc"'); 2+---------------------------------------------------------------+ 3| JSON_SCHEMA_VALID('{"type":"string","pattern":"("}', '"abc"') | 4+---------------------------------------------------------------+ 5| 1 | 6+---------------------------------------------------------------+ 71 row in set (0.04 sec)
JSON _document_를
JSON _schema_에 대해 검증합니다.
_schema_와
_document_는 모두 필수입니다.
JSON_VALID_SCHEMA()와 마찬가지로,
스키마는 유효한 JSON 객체여야 하고,
문서는 유효한 JSON 문서여야 합니다.
이 조건이 만족되면, 함수는 검증 결과에 대한 리포트를
JSON 문서로 반환합니다.
JSON 문서가 JSON 스키마에 따라 유효하다고 간주되면,
함수는 valid라는 하나의 프로퍼티가
"true" 값을 가진 JSON 객체를 반환합니다.
JSON 문서가 검증에 실패하면,
함수는 다음 프로퍼티들을 포함하는 JSON 객체를 반환합니다:
valid: 스키마 검증 실패 시 항상
"false"
reason: 실패 원인을 담은
사람이 읽을 수 있는 문자열
schema-location: JSON 스키마에서
검증이 실패한 위치를 나타내는
JSON 포인터 URI 조각 식별자
(이 목록 뒤의 Note를 참고)
document-location: JSON 문서에서
검증이 실패한 위치를 나타내는
JSON 포인터 URI 조각 식별자
(이 목록 뒤의 Note를 참고)
schema-failed-keyword: JSON 스키마에서
위반된 키워드나 프로퍼티 이름을 담은 문자열
참고
JSON 포인터 URI 조각 식별자는
RFC 6901 - JavaScript Object Notation (JSON) Pointer에
정의되어 있습니다.
(이는 MySQL JSON 함수인
JSON_EXTRACT() 등에서 사용하는
JSON 경로 표기법과는 동일하지 않습니다.)
이 표기법에서 #는 전체 문서를 나타내며,
#/myprop는 최상위 프로퍼티 이름이
myprop인 부분에 포함된 문서를 나타냅니다.
자세한 내용은 앞서 인용한 사양과,
이 섹션 뒤쪽에 나오는 예제를 참고하십시오.
이 예제에서는 사용자 변수 @schema를
지리 좌표에 대한 JSON 스키마 값으로 설정하고,
또 다른 변수 @document를
그러한 좌표 하나를 포함하는 JSON 문서 값으로 설정합니다.
그런 다음, 이 둘을
JSON_SCHEMA_VALIDATION_REORT()의 인자로 사용하여
@document가 @schema에 따라
검증에 성공하는지 확인합니다:
1mysql> SET @schema = '{ 2 '> "id": "http://json-schema.org/geo", 3 '> "$schema": "http://json-schema.org/draft-04/schema#", 4 '> "description": "A geographical coordinate", 5 '> "type": "object", 6 '> "properties": { 7 '> "latitude": { 8 '> "type": "number", 9 '> "minimum": -90, 10 '> "maximum": 90 11 '> }, 12 '> "longitude": { 13 '> "type": "number", 14 '> "minimum": -180, 15 '> "maximum": 180 16 '> } 17 '> }, 18 '> "required": ["latitude", "longitude"] 19 '>}'; 20Query OK, 0 rows affected (0.01 sec) 21 22mysql> SET @document = '{ 23 '> "latitude": 63.444697, 24 '> "longitude": 10.445118 25 '>}'; 26Query OK, 0 rows affected (0.00 sec) 27 28mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document); 29+---------------------------------------------------+ 30| JSON_SCHEMA_VALIDATION_REPORT(@schema, @document) | 31+---------------------------------------------------+ 32| {"valid": true} | 33+---------------------------------------------------+ 341 row in set (0.00 sec)
이제 @document가
그 프로퍼티 중 하나에 대해 허용되지 않는 값을 지정하도록
다음과 같이 설정합니다:
1mysql> SET @document = '{ 2 '> "latitude": 63.444697, 3 '> "longitude": 310.445118 4 '> }';
이제 JSON_SCHEMA_VALIDATION_REPORT()로
테스트할 때 @document의 검증은 실패합니다.
함수 호출의 결과는 (가독성을 위해
JSON_PRETTY()로 감싸
더 나은 포맷을 제공하도록 하여) 다음과 같이
실패에 대한 상세 정보를 포함합니다:
1mysql> SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G 2*************************** 1. row *************************** 3JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)): { 4 "valid": false, 5 "reason": "The JSON document location '#/longitude' failed requirement 'maximum' at JSON Schema location '#/properties/longitude'", 6 "schema-location": "#/properties/longitude", 7 "document-location": "#/longitude", 8 "schema-failed-keyword": "maximum" 9} 101 row in set (0.00 sec)
@schema에 required 속성이
포함되어 있으므로, 필수 프로퍼티를 포함하지 않지만
그 외에는 유효한 값으로
@document를 설정한 다음
@schema에 대해 테스트할 수 있습니다.
JSON_SCHEMA_VALIDATION_REPORT()의 출력은
다음과 같이, 필수 요소의 부재로 인해
검증이 실패함을 보여줍니다:
1mysql> SET @document = '{}'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G 5*************************** 1. row *************************** 6JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)): { 7 "valid": false, 8 "reason": "The JSON document location '#' failed requirement 'required' at JSON Schema location '#'", 9 "schema-location": "#", 10 "document-location": "#", 11 "schema-failed-keyword": "required" 12} 131 row in set (0.00 sec)
이제 @schema의 값을
같은 JSON 스키마이지만
required 속성이 없는 값으로 설정하면,
@document에는 프로퍼티가 전혀 없더라도
유효한 JSON 객체이기 때문에 검증에 성공합니다.
다음과 같이 확인할 수 있습니다:
1mysql> SET @schema = '{ 2 '> "id": "http://json-schema.org/geo", 3 '> "$schema": "http://json-schema.org/draft-04/schema#", 4 '> "description": "A geographical coordinate", 5 '> "type": "object", 6 '> "properties": { 7 '> "latitude": { 8 '> "type": "number", 9 '> "minimum": -90, 10 '> "maximum": 90 11 '> }, 12 '> "longitude": { 13 '> "type": "number", 14 '> "minimum": -180, 15 '> "maximum": 180 16 '> } 17 '> } 18 '>}'; 19Query OK, 0 rows affected (0.00 sec) 20 21mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document); 22+---------------------------------------------------+ 23| JSON_SCHEMA_VALIDATION_REPORT(@schema, @document) | 24+---------------------------------------------------+ 25| {"valid": true} | 26+---------------------------------------------------+ 271 row in set (0.00 sec)
14.17.6 JSON Table Functions
14.17.8 JSON Utility Functions