MySQL은 전통적으로 관계형 데이터베이스(RDBMS)로, 엄격한 스키마(테이블 구조)를 요구했습니다. 그러나 현대 애플리케이션은 점점 더 유연한 데이터 구조를 요구하게 되었고, 다양한 형태의 데이터를 저장할 수 있는 NoSQL 데이터베이스가 주목받기 시작했습니다. 이 흐름에 대응하기 위해 MySQL은 5.7 버전부터 JSON 타입을 도입했습니다.
MySQL JSON 타입의 등장 이유:
JSON 타입을 사용하면 좋은 상황:
MySQL의 JSON 타입은 유연성과 관계형 데이터베이스의 장점을 모두 살리고 싶을 때 매우 유용한 선택지가 됩니다.
이 문서에서는 "MySQL JSON 함수"를 통해 구조화된 데이터에서 특정 값을 검색과 수정, 획득하는 방법을 알아봅니다.
JSON_EXTRACTJSON 데이터에서 특정 경로(Path)에 해당하는 값을 추출할 때 사용합니다.
SELECT JSON_EXTRACT('{"user": {"name": "Alice", "age": 30}}', '$.user.name') AS username;
결과: "Alice"
JSON_UNQUOTEJSON 형식으로 추출된 문자열 값에서 따옴표를 제거합니다.
SELECT JSON_UNQUOTE(JSON_EXTRACT('{"user": {"name": "Alice"}}', '$.user.name')) AS username;
결과: Alice
JSON_SET기존 JSON 오브젝트에 키-값 쌍을 추가하거나 값을 업데이트합니다.
SELECT JSON_SET('{"name": "Alice"}', '$.age', 30);
결과: {"name": "Alice", "age": 30}
JSON_ARRAYAGG여러 행의 값을 하나의 JSON 배열로 집계합니다.
SELECT JSON_ARRAYAGG(name) FROM users;
JSON_OBJECTAGG여러 키-값 쌍을 모아 하나의 JSON 오브젝트를 생성합니다.
SELECT JSON_OBJECTAGG(id, name) FROM users;
JSON_INSERT특정 경로에 데이터가 없을 경우에만 삽입합니다.
SELECT JSON_INSERT('{"name": "Alice"}', '$.age', 30);
JSON_REPLACE특정 경로에 데이터가 존재하면 값을 교체합니다.
SELECT JSON_REPLACE('{"name": "Alice", "age": 25}', '$.age', 30);
JSON_REMOVE특정 키를 제거합니다.
SELECT JSON_REMOVE('{"name": "Alice", "age": 25}', '$.age');
SELECT JSON_EXTRACT('{
"user": {
"profile": {
"name": "Alice",
"age": 30
}
}
}', '$.user.profile.name') AS username;
결과: "Alice"
SELECT JSON_EXTRACT('{
"users": [
{"name": "Alice"},
{"name": "Bob"},
{"name": "Charlie"}
]
}', '$.users[1].name') AS second_user;
결과: "Bob"
SELECT JSON_ARRAY_APPEND('["Alice", "Bob"]', '$', 'Charlie');
결과: ["Alice", "Bob", "Charlie"]
SELECT JSON_SET('{
"user": {
"name": "Alice",
"age": 30
}
}', '$.user.age', 31);
결과: {"user": {"name": "Alice", "age": 31}}
SELECT id, data
FROM users
WHERE JSON_EXTRACT(data, '$.status') = '"active"';
MySQL의 JSON 데이터 타입은 전통적인 인덱스를 직접 적용할 수 없습니다. 검색 최적화를 위해 가상 컬럼(generated column)을 생성하고 해당 컬럼에 인덱스를 걸어야 합니다.
ALTER TABLE users ADD COLUMN status VARCHAR(255) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.status'))) STORED;
CREATE INDEX idx_status ON users(status);
JSON 데이터는 문자열로 취급될 수 있으므로, 숫자나 불리언 값을 검색할 때 타입 주의가 필요합니다.
JSON 데이터가 지나치게 크거나 깊을 경우 쿼리 성능이 급격히 저하될 수 있습니다. 필요한 경우 데이터 정규화 또는 별도 테이블 분리 전략을 고려해야 합니다.
| [MySQL] 데이터 암호화, 복호화 (0) | 2017.07.10 |
|---|---|
| [MySQL] 인덱스 생성, 조회, 삭제 (0) | 2017.05.19 |
| [MySQL] Select에서 랜덤 값 가져오기 (0) | 2017.05.15 |
| [MySQL] 데이터 형식 (0) | 2017.05.15 |
| [MySQL] 테이블 초기화시키기 (0) | 2017.05.14 |