VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
JSON 열 타입은 삽입 시 JSON을 검증하고, 효율적인 접근을 위해 바이너리 형식으로 저장하며, 전체 문서를 파싱하지 않고 개별 필드를 읽고 수정하는 함수 집합을 제공합니다.
JSON 저장하기
JSON 필드 읽기
JSON_EXTRACT(column, path) 또는 축약형 ->를 사용하세요:
"Acme"입니다. 따옴표 없는 일반 문자열을 얻으려면 ->>를 사용하세요(JSON_UNQUOTE(JSON_EXTRACT(...))의 축약형입니다):
$.key— 객체 필드에 접근$.array[0]— 인덱스로 배열 요소에 접근$.array[*]— 배열의 모든 요소$.**— 재귀 와일드카드(모든 깊이의 모든 값)
JSON 필드로 필터링하기
->>는 문자열을 반환하므로, CAST(attributes ->> '$.ram_gb' AS UNSIGNED)처럼 명시적으로 캐스팅하지 않는 한 (16이 아니라) '16'과 비교하는 것이 올바릅니다.
JSON 수정하기
JSON 필드에 인덱스 만들기
JSON 열 자체에는 직접 인덱스를 만들 수 없습니다. 특정 JSON 필드에 인덱스를 만들려면, 생성 열을 만들고 그것에 인덱스를 만드세요:WHERE attributes ->> '$.brand' = 'Acme'가 idx_brand를 사용할 수 있습니다. MySQL은 생성 열 표현식이 쿼리 조건과 일치한다는 것을 인식합니다.
이것은 MySQL 데이터 타입 선택하기에서 더 자세히 다룹니다 — 인덱스가 필요할 만큼 JSON 필드를 자주 쿼리할 때마다 권장되는 패턴입니다.
JSON 대 정규화된 열
구조가 정말로 가변적일 때(사용자가 설정할 수 있는 속성, 이벤트 메타데이터, 서드파티 API 페이로드) JSON을 사용하세요. 구조가 고정되어 있고 필드에 대해 필터링, 조인, 집계가 필요할 때 정규화된 열을 사용하세요.
자주 묻는 질문
포함 쿼리를 위해 JSON 배열에 인덱스를 만들 수 있나요?
표준 인덱스로는 직접 만들 수 없습니다.JSON_CONTAINS 쿼리에서는 배열을 별도의 자식 테이블로 추출(정규화)하거나 배열을 평탄화하는 생성 열에 전문 인덱스를 사용하지 않는 한, 유일한 선택지는 전체 테이블 스캔입니다. 처리량이 높은 포함 쿼리에는 정규화가 더 나은 길입니다.
->와 ->>의 차이는 무엇인가요?
->는 JSON 값을 반환합니다(문자열은 둘러싼 따옴표를 포함합니다). ->>는 따옴표를 뗀 문자열을 반환합니다. 표시, 연결, 그리고 텍스트를 소비하는 모든 것에는 ->>가 원하는 것입니다. 그래도 동등 비교는 ->를 통해서도 동작합니다: MySQL이 다른 피연산자를 먼저 JSON으로 강제 변환하므로, attributes -> '$.brand' = 'Acme'는 일치합니다.
JSON을 저장하면 성능이 나빠지나요?
큰 JSON 문서에서 단일 필드를 읽으려면 바이너리 구조를 파싱해야 하는데, 이것은 텍스트를 파싱하는 것보다 빠르지만 네이티브 열을 읽는 것보다 느립니다. 자주 접근하는 필드에는 생성 열 + 인덱스 패턴이 읽기 성능을 네이티브 열과 같은 수준으로 끌어올립니다.문제 해결
함께 보기
- MySQL 데이터 타입 선택하기 — JSON 대 정규화된 열을 언제 사용할지
- MySQL의 생성 열 — 가상 생성 열로 JSON 필드에 인덱스 만들기
- SQL에서 HTTP 요청 보내기 — HTTP API 응답에서 JSON 파싱하기