DB

[MySQL] (JSON6️⃣) 실무에서 JSON 타입을 쓸 때 주의할 점

인생아 2025. 7. 17. 21:35
반응형

MySQL의 JSON 타입은 유연하지만 실무에서는 신중하게 사용해야 한다.
단순 저장엔 편리하지만, 검색, 수정, 인덱싱에서 예상 외의 문제가 자주 발생한다.

⚠️ 1. JSON은 인덱스를 직접 만들 수 없다

MySQL에서는 JSON 컬럼에 직접 인덱스를 걸 수 없다.
즉, JSON 내부 값을 조건으로 조회하면 풀스캔이 발생할 수 있다.

-- 아래 쿼리는 인덱스를 타지 않음
SELECT * FROM users
WHERE JSON_EXTRACT(profile, '$.nickname') = 'hong';

해결 방법은 생성 컬럼 + 인덱스 조합이다.

ALTER TABLE users
ADD COLUMN nickname VARCHAR(100)
       GENERATED ALWAYS AS (JSON_UNQUOTE(profile->'$.nickname')) STORED,
ADD INDEX idx_nickname (nickname);
반응형

📦 2. 과도한 데이터 저장은 피하라

JSON 컬럼에 너무 많은 데이터를 담으면 오히려 복잡성과 성능 문제를 키운다.
아래처럼 user_info를 몽땅 JSON에 때려넣는 방식은 비추천이다.

-- 나쁜 예
user_info = {
  "name": "지수",
  "phone": "010-1234-5678",
  "birth": "1994-05-12",
  "marketing_optin": true
}

✅ 실무에서는 name, phone, birth 등은 별도 컬럼으로 분리하고
✅ marketing_optin 같이 부가 옵션만 JSON으로 보관하는 것이 좋다

🧩 3. JSON 구조가 불안정하면 코드도 깨진다

JSON은 스키마가 없기 때문에,
키가 누락되거나 타입이 바뀌면 프론트/백엔드 양쪽에서 오류가 날 수 있다.

-- 어떤 유저는 "age"가 있고
{ "name": "준호", "age": 30 }

-- 어떤 유저는 없음
{ "name": "소연" }

-- 어떤 유저는 타입도 다름
{ "name": "하나", "age": "서른" }

✅ 구조가 유동적인 경우엔 프론트 단에서 기본값 설정 or null 처리 필요
✅ 백엔드에서는 IFNULL, CAST 등으로 안정성을 확보하는 처리 필요

🧠 4. 복잡한 데이터는 별도 테이블로 분리하는 게 낫다

아래처럼 배열이나 중첩된 객체를 많이 쓰는 경우,
JSON보다 자식 테이블로 분리하는 게 훨씬 낫다.

-- JSON으로 넣은 예
{
  "addresses": [
    { "type": "home", "addr": "서울시..." },
    { "type": "work", "addr": "성남시..." }
  ]
}

→ 이건 user_address라는 별도 테이블로 빼는 게 검색, 수정, JOIN 등 모든 면에서 유리하다

반응형

🧪 5. JSON 수정은 항상 신중하게

JSON_SET, JSON_REPLACE, JSON_INSERT 등으로 값을 바꿀 수 있지만
쿼리가 복잡해지고 오류 발생 가능성도 높다.

-- 실수로 key 중복되면 의도와 다르게 동작할 수 있음
SELECT JSON_SET('{"opt":true}', '$.opt', false);
-- 결과: {"opt": false}

✅ 기본값 설정은 INSERT 단계에서 미리 처리
✅ UPDATE 시에는 기존 JSON 값 추출 후 가공해서 다시 저장하는 방식 권장

🔒 6. 보안 이슈도 고려해야 한다

JSON 내부에 개인정보, 인증 토큰 등을 저장하면
로그, 에러 출력, 덤프 백업 등에 노출될 수 있다.

✅ JSON 안에 민감 정보는 절대 저장하지 말 것
✅ 로그 필터링, 접근 권한 관리도 필수

📌 요약 체크리스트

  • 자주 조회되는 값은 별도 컬럼 + 인덱스
  • 대용량/중첩 JSON은 자식 테이블로 분리
  • 생성 컬럼으로 인덱싱 구조 확보
  • 프론트/백엔드에서 구조 변화에 대비한 방어 코드 작성
  • 민감 정보는 JSON에 저장하지 말기

MySQL의 JSON은 강력하지만 만능은 아니다.
적재적소에 쓰되, 검색/성능/유지보수 관점에서 구조를 잘 설계하는 것이 중요하다.

📘 공식 문서 참고

https://dev.mysql.com/doc/refman/8.0/en/json.html

 

반응형