메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
MySQL의 네이티브 JSON 열 타입은 삽입 시 JSON을 검증하고, 효율적인 접근을 위해 바이너리 형식으로 저장하며, 전체 문서를 파싱하지 않고 개별 필드를 읽고 수정하는 함수 집합을 제공합니다.

JSON 저장하기

MySQL은 삽입 시 JSON을 검증합니다. 잘못된 형식의 JSON을 삽입하면 오류가 발생합니다.

JSON 필드 읽기

JSON_EXTRACT(column, path) 또는 축약형 ->를 사용하세요:
둘 다 JSON 값을 반환합니다 — 따옴표가 붙은 문자열 "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 문서에서 단일 필드를 읽으려면 바이너리 구조를 파싱해야 하는데, 이것은 텍스트를 파싱하는 것보다 빠르지만 네이티브 열을 읽는 것보다 느립니다. 자주 접근하는 필드에는 생성 열 + 인덱스 패턴이 읽기 성능을 네이티브 열과 같은 수준으로 끌어올립니다.

문제 해결

함께 보기