JSON은 인터넷 상에서 서로 다른 애플리케이션 간에 데이터를 주고 받기 위해서 사용하는 오픈 파일 포맷이다. XML과 비슷하다고 볼 수 있다. 그렇다면 이미 널리 사용하고 있었던 XML 대신 JSON 이라는 새로운 포맷이 나온 이유가 뭘까 ? 참고로 XML은 1998년 표준 권고안이 나왔고 JSON은 2013년 ECMA-404를 통해서 표준이 만들어졌다. (물론 2005년경 야후에서 JSON을 사용하기는 했지만)
JSON의 장점 하면 나오는 특징들은 아래와 같다.
모든 브라우저에서 지원한다.
읽고 쓰기 쉽다.
간단한 구문
JavaScript에서 기본으로 구문분석을 할 수 있다.
손쉬운 작성과 조작
모든 JavaScript 프레임워크에서 지원
대부분의 백엔드 기술에서 지원
JSON은 JavaScript로 인식된다.
최신의 다른 프로그래밍 언어들도 잘 지원한다.
나는 자바스크립트와 한몸인데, 그 자바스크립트가 인터넷 세계의 표준 언어라서 JSON을 사용하는 거라고 생각한다.
테스트 환경
Docker로 실행했다.
# docker run -e MYSQL_ROOT_PASSWORD=1234 --name json_mysql mysql
Mysql 버전은 (2020년 3월 현재 최신버전)8.0.19다.
mysql -u root -p -h 172.17.0.2
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.19 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
MySQL JSON Data type
Mysql 5.7 부터 Json 데이터 타입을 지원한다. Json 데이터 타입을 저장하기 위한 칼럼은 JSON으로 설정하면 된다. 테스트를 위한 데이터베이스를 만들었다.
select * from users where JSON_EXTRACT(info, "$.age") = 38;
잘 작동하지만 색인이 걸려있지 않기 때문에 비효율적으로 작동 할 것이다. EXPLAIN을 이용해서 쿼리를 측정해보자.
mysql> EXPLAIN select * from users where info->"$.age" = 38;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
type필드는 테이블에서 행을 어떻게 찾았는지를 알려준다. ALL은 SQL문을 수행하기 위해서 전체 레코드를 전부 스캔했음을 의미한다. 실제 서비스에서 SQL문을 사용해서는 안될 것이다.
MYSQL 5.7.14 부터는 JSON 컬럼의 Key에 대해서도 색인을 만들 수 있다. 테이블을 다시 만들었다.
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(64) NOT NULL,
info JSON,
age_virtual INT GENERATED ALWAYS AS (info->'$.age')
);
CREATE TABLE로 테이블을 만들 때, 아래와 같이 컬럼을 추가 할 수 있다.
`column_name` datatype GENERATED ALWAYS AS (expression)
여기에서 핵심은 GENERATED ALWAYS와 AS다. GENERATED ALWAYS라는 문구는 선택사항이다. 테이블 열이 generated된 컬럼임을 명시적으로 나타내려는 경우에만 필요하다. 필요한 것은 생성된 컬럼에 원하는 값을 리턴하는 AS문이다.
`age_virtual` INT GENERATED ALWAYS AS (info->'$.age')
나는 age_virtual 이라는 INT 데이터를 저장하는 컬럼을 만들었다. 이 컬럼에는 info컬럼의 age에 접근한다는 걸 알려주기 위해서 info->'$.age' 문을 사용했다. 이제 age_virtual 컬럼은 info->'$.age'를 가리키게 된다.
테이블 구성을 살펴보자.
mysql> desc users;
+-------------+-------------+------+-----+---------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| email | varchar(64) | NO | | NULL | |
| info | json | YES | | NULL | |
| age_virtual | int(11) | YES | | NULL | VIRTUAL GENERATED |
+-------------+-------------+------+-----+---------+-------------------+
Contents
왜 JSON 인가?
테스트 환경
MySQL JSON Data type
MySQL JSON Path 표현식
JSON SELECT
JSON 함수들
JSON_ARRAY
JSON_EXTRACT
JSON_OBJECT
JSON_SET
JSON_INSERT
JSON_REPLACE
JSON_VALID
JSON 색인
JSON_STORAGE_SIZE & JSON_STORAGE_FREE
정리
참고
Recent Posts
Archive Posts
Tags