2015년 9월 2일 수요일

JSON Labs Release: JSON Functions, Part 1


아래 글은  MySQL Server Blog에 Rick Hillegas님이 게시한 JSON Labs Release: JSON Functions, Part1 원문을 한국 MySQL 사용자 그룹 (MySQL Korea User Group) 멤버들이 번역한 내용입니다. 번역내용 중 이상한부분이 있으시면 덧글로 알려주시기 바랍니다. 번역자들이 전문 번역가가 아니다보니 매끄럽지 못하거나 오역이 있을 수 있습니다. 참고해서 읽어주시면 감사하겠습니다.
해당 내용의 저작권은 전적으로 원문 게시자에게 있으며, 원문 작성자가 해당 글의 게시에 대해 문제가 있다고 하시면 내리겠습니다.
출처 : http://mysqlserverteam.com/json-labs-release-json-functions-part-1-manipulation-json-data/


* 원문에 준해서 번역을 하다보니 최신 내용이 반영이 안되었네요. JSON function 명이 5.7.7 lab버전까지는 jsn_xxx()형태였는데, 5.7.8에서는 json_xxx()로 변경되었다고 합니다. 이전의 JSON UDF 버전을 테스트해보신 분이셨다면 해당 블로그의 jsn_xxx() 형태가 헷갈리셨을 듯한데요. 그래서 아마도 json_xxx()형태로 변경된 듯합니다. 그리고 GA이전 버전이다 보니 버전 업될때마다 변경사항들이 있는 듯합니다. 사용전 체크하시는게 좋을 듯 싶습니다.

JSON Labs Release: JSON 함수, Part 1 - JSON 데이터 다루기

MySQL 5.7.7 JSON Lab release는 네이티브 JSON 데이터 타입을 소개합니다. 이 새로운 데이터 타입에 대한 자세한 사항은 Knut Anders Hatlen’s blog post을 참조하세요. 이번 릴리즈에서는 JSON 도큐먼트를 생성하고 쿼리하기 위한 다수의 함수도 소개합니다. 이 포스트에서는 JSON 도큐먼트를 다루는데 관련된 새로운 함수들을 살펴볼 것입니다.
  • jsn_array()
  • jsn_object()
  • jsn_insert()
  • jsn_remove()
  • jsn_set()
  • jsn_replace()
  • jsn_append()
  • jsn_merge()
  • jsn_extract()
Dag Wanvik’s follow up blog post에서는 JSON 도큐먼트의 쿼리와 검색과 관련된 함수를 살펴볼 것입니다. 모든 새로운 JSON 함수들에 대한 자세한 정보는 WL#7909에 첨부된 하이 레벨 스펙에서 찾을 수 있습니다.

Creating JSON Data (JSON 데이터 생성)

몇가지 간단한 JSON 데이터를 생성하면서 시작해봅시다. 스마트 온도조절기로 부터 많은 양의 온도 기록들을 저장하기 위해 JSON 데이터 타입을 사용한다고 가정합니다. 다음 테이블이 적절하다고 생각됩니다.
 
'capabilities' 도큐먼트는 단지 태그들의 배열이라고 생각해둡시다. 새로운 JSN_ARRAY() 함수를 사용해서 그 배열들중에 하나를 생성해 봅시다. 이 함수는 익스프레션들의 변수 길이 리스트를 평가하고 그것들을 차례로 JSON 배열로 입력합니다.
 

아주 쉽습니다. 또 다른 방법으로는 단순히 적절한 JSON 텍스트를 JSON 컬럼에 입력할 수 있습니다. MySQL은 텍스트를 파싱(분석)하고 그 텍스트를 네이티브 JSON 바이너리 저장 포맷으로 변환합니다:



JSN_ARRAY()외에, JSN_OBJECT() 구성 함수도 있습니다. 짐작했을지도 모르겠지만, JSN_OBJECT()는 키/값 형식으로된 변수 길이 리스트로부터  JSON 오브젝트를 빌드합니다. 예제입니다:
 


또한 다른 방법으로 단지 적절한 JSON 텍스트를 우리의 온도조절기 기록 테이블로 넣을 수 있습니다:
 

Schema Evolution: Adding Data (스키마 진화: 데이터 추가)

물론 실제로 데이터는 그 데이터를 사용하는 어플리케이션과 더불어 계속해서 변합니다. 온도조절기 생산자로써 온도조절기가 실제로 켜져있는지 그리고 동작하는지에 대해서 말할 수 없다고 가정합시다. 모든 우리의 온도조절기를 원격으로 업그레이드해서 온도조절기가 on/off 상태를 알려주기 시작한다고 해봅시다. 결국 온도조절기 측정 테이블은 on/off 상태를 알려주지 못하는 오래된 레코드뿐만 아니라 상태를 알려주는 새로운 레코드도 포함할 것입니다:
 

 
이제 우리는 또한 on/off 상태를 포함하도록 하기위해 오래된 데이터를 수정하기 원합니다. 이를 위해 오래된 레코드는 on/off 상태가 NULL ("상태 모름"을 의미)이라고 이야기하면 좋을 것입니다. 이제 새로운 JSN_INSERT() 함수를 사용할 것입니다. JSN_INSERT()는 JSON 도큐먼트에 빠진 데이터를 추가합니다. 그러나, 이미 있는 데이터는 덮어쓰기를 하지 않습니다. JSN_INSERT()는 3개의 아규먼트(argument)를 가집니다: 수정될 도큐먼트, 수정된 도큐먼트의 부분을 표시하는 패스 익스프레션(아래 참조) 그리고 지정된 위치에 추가될 값:
 

기존의 row들은 on/off 상태가 무엇이었는지 모르고 있었다는 것을 알려주고 있다는 것에 주목하세요 (NULL값). 또한, 신규 row들은 수정되지 않았다는 것에 주목하세요.

UPDATE문을 좀더 자세히 들여다보면, 여러분은 궁금할 수도 있습니다:
  1. What’s that strange ‘$.on‘ argument?
  2. Why do I need to CAST my NULL to JSON?
  3. 특이한 '$.on' argument는 무엇인가요?
  4. 왜 NULL은 JSON으로 캐스트될 필요가 있나요?
먼저, '$.on' 아규먼트에 대해서 이야기해 봅시다. 그것은 path expression입니다. JSON 도큐먼트 안의 값들의 주소입니다. Path expression은 $로 시작합니다. $는 path의 루트를 의미합니다. 모든 신규 JSON 함수들의 경우, 루트는 항상 $로 지정되고 "선택된 도큐먼트"를 의미합니다. $ 다음에 임의 길이의 멤버 이름과 배열 인덱스가 오게됩니다. 이는 도큐먼트안에서 (가능한 깊이) 내포된 값으로 탐색합니다. 멤버 이름은 . 로 지정되고 key의 이름이 이어집니다. 배열 인덱스는 단지 대괄호 안에 있는 숫자들에 불과합니다. 예를 들어 path expression $.fred.children[3]는 "선택된 도큐먼트안의 fred의 3번째 아이"를 의미합니다. 지금 당장은 너무 걱정하지 마세요. 이 블로그에서 path expression는 아주 간단합니다. 예를들어 이번 위의 UPDATE문에서 $.on은 "선택된 도큐먼트의 'on' 멤버"를 의미합니다.

자, 이제 CAST는 무엇인가요? CAST가 없다면 NULL 아규먼트는 모든 JSN_INSERT()문이 NULL로 평가하는 원인이 됩니다. 그래서 기존 row들을 이상하게 만들수 있습니다. 게다가, CAST(NULL AS JSON)은 같은 효과를 가질 수 있습니다. 문제는 JSON null 문자 자체와 SQL NULL이 다르다는 것입니다. JSON null 문자를 만든 방법은 단지 null문자를 포함한 몇몇 적절한 JSON 텍스트를 CAST하는 것입니다.

이것이 지금은 이상해 보일지 몰라도 걱정하지 마세요. 새로운 JSON함수들을 다루면서 빠르게 JSON null 문자를 다루는 법을 익히게 될 것입니다. 이 블로그 포스트에서는 SQL NULL들에 대해서 신경쓸 필요가 없습니다.

Schema Evolution: Removing Data (스키마 진화: 데이터 삭제)

데이터를 추가할 때마다, 나중에 그것을 지울 수도 있다는 것에 대해서 생각할 필요가 있습니다. 온도조절기 제작자로써 on/off 상태를 추가하는 것은 나쁜 아이디어였다고 결정했다고 가정해봅시다. 다시 모든 온도조절기를 원격으로 업그레이드할 필요가 있습니다. on/off 상태를 리포트하는 것도 중지해야 합니다. 그 후, 기존 온도조절기에서 받은 on/off 값들을 제거하기를 원합니다. 이를 위해, 신규 JSN_REMOVE()함수를 사용합니다. JSN_REMOVE()는 제거될 데이터의 위치를 알려주는 path expression으로 된 도큐먼트 아규먼트를 가집니다. 어떻게 모든 on/off 값들을 제거하는지 보세요:


Schema Evolution: Updating Data (스키마 진화: 데이터 수정)

온도조절기 제작자로서 온도조절기를 업그레이드해서 새로운 종류의 데이터 ("spread"나 온도조절기 설정과 실제 방의 온도의 차이)를 추가한다고 생각해 봅시다. 새로운 온도조절기 기록은 이러한 신규 데이터를 포함하겠지만, 기존의 데이타는 포함하지 않을 것입니다:
 

기존의 레코드를 수정하기 위해 JSN_SET() 함수를 사용할 수 있습니다. JSN_SET()는 기존 값들을 덮여쓰기 한다는 것을 제외하고는 JSN_INSERT()와 매우 유사하게 동작합니다.
 

"spread" 값은 그 값을 가지지 않은 레코드에 추가된다는 것에 주목하세요. 그리고 기존의 "spread"값을 업데이트 합니다. 오! 고의로 그런건 아닙니다. 계산은 뒤에서 이루어집니다. 즉, 온도조절기 설정에서 실제 온도값을 뺌으로서 온도조절기가 계산을 하는 방법으로 "spread"를 계산합니다. 문제없습니다. 이제 그것을 고쳐봅시다. 일단 고치기 전에 막 소개된 JSN_EXTRACT()에 함수에 대해서 궁금해 할 수 있습니다. JSN_EXTRACT()는 JSON 도큐먼트 안에 내포된 값을 리턴합니다. JSN_EXTRACT()는 path 주소로 값을 찾아줍니다.

자, 이제 온도조절기의 기록을 고쳐봅시다. 이를 위해 또 다른 업데이트 함수 JSN_REPLACE()를 사용합니다. JSN_REPLACE()는 JSN_INSERT()와 반대로 동작합니다. JSN_REPLACE()는 빠진 데이터가 있는 레코드를 건드리지 않습니다. JSN_REPLACE()는 오직 데이터가 있는 레코드만 변경합니다.
 

Schema Evolution: Appending Data (스키마 진화: 데이터 추가)

 자, 이제 기존 데이터를 완전히 삭제하는 대신 신규 데이터를 기존 데이터에 추가할 필요가 있다고 가정합시다. 온도조절기 제작자로서 온도조절기들을 업그레이드합니다. 온도조절기에 스피드 팬 조절이라는 변수를 추가합니다. 업그레이드 이후, 온도조절기의 메터데이터에 새로운 용량(capability) 을 추가할 필요가 있습니다. 이를 위해 JSN_APPEND()를 사용합니다. JSN_APPEND()는 배열의 끝에 값을 추가합니다.


이제 몇가지 보안 기능이 추가된 온도조절기로 업그레이드 한다고 가정합시다. 우리의 메타데이터를 서로 맞게 업데이트하는 신규 JSON_MERGE()함수를 사용합시다. JSN_MERGE()는 아주 강력한 함수입니다. 두 개의 배열들을 합칠 수 있으며, 그것이 우리가 하고자 하는 것입니다. (두 개의 오브젝트들을 멤버 또는 레벨에 맞춰 합칠 수도 있습니다.) JSN_MERGE()는 JSON 도큐먼트의 변수 길이 리스트를 얻은 후, 하나의 합성된 도큐먼트로 그것들을 합칩니다.
 

Schema Evolution: Indexing JSON Data (스키마 진화: JSON 데이터 인덱싱)

 힙(heap)으로 온도조절기의 기록들을 덤프해서 복사하기 시작했습니다. 시간이 지나, 이제 이들 기록들을 쿼리하고자 합니다. 그래서 유용한 인덱스를 원하게 됩니다. 온도조절기 기록 테이블에 가상의 컬럼을 추가하고 그 컬럼을 인덱스합시다. 이는 우리가 온도조절기의 유일한 id를 기준으로 하여 온도조절기 기록을 빠르게 찾을 수 있게 할 것입니다.
 


MySQL 5.7.7 JSON Lab release에 또한 추가된 새로운 "functional index" 동작에 대한 더 자세한 사항은 Jummy Yang의 blog post를 참조하세요.


자, 이제 JSON 데이터를 생성하고 다루는 준비가 되었습니다. 이 주제에 대해서 Dag Wanvik의 follow up blog post를 읽어보기를 권합니다. 즉, 그의 블로그 포스트는 MySQL 5.7.7 JSON Lab release에서 소개된 새로운 쿼리와 검색과 관련된 JSON 함수를 설명합니다.
  • jsn_search()
  • jsn_contains()
  • jsn_contains_path()
  • jsn_valid()
  • jsn_type()
  • jsn_keys()
  • jsn_length()
  • jsn_depth()
  • jsn_unquote()
  • jsn_quote()
이 모든 새로운 JSON 기능에 대한 여러분의 생각을 알려주세요! 이번 JSON 지원에 관련되어 여러분이 알고싶어하시는 모든 피드백을 환영합니다. 이 새로운 기능에 대해 어떤 문제라도 있다면, 이 포스트의 comment로 알려주시고, bugs.mysql.comsupport ticket에 케이스를 오픈 해주세요. 

MySQL을 사용해 주셔서 감사합니다!


참고 URLs:
JSON Functions
https://dev.mysql.com/doc/refman/5.7/en/json-functions.html
JSON Labs Release: Effective Functional Indexes in InnoDB
http://mysqlserverteam.com/json-labs-release-effective-functional-indexes-in-innodb/

댓글 1개:

  1. 문득 드는 생각입니다만, pma에선 저 결과가 어떻게 뜰지 궁금해지는군요.

    답글삭제