포스트

배열을 데이터베이스에 저장할 때 무엇을 먼저 판단해야 하는가

애플리케이션에서는 배열이나 리스트를 자주 다루지만, 관계형 데이터베이스는 기본적으로 행과 열 중심의 구조를 가진다. 그래서 애플리케이션의 배열을 DB에 그대로 저장하려고 하면 설계 선택지가 여러 갈래로 나뉜다.

핵심은 “배열을 저장할 수 있느냐”보다 그 배열을 나중에 어떻게 조회하고 수정할 것인가를 먼저 보는 것이다.

가장 먼저 볼 질문

배열을 DB에 저장할 때는 먼저 이 질문부터 해야 한다.

  • 원소를 개별적으로 조회해야 하는가
  • 원소의 순서가 중요한가
  • 원소별 수정이 자주 일어나는가
  • 조건 검색이 필요한가

이 질문에 따라 모델링 방식이 달라진다.

1. 정규화해서 별도 테이블로 분리하는 방식

가장 일반적인 방법은 배열 원소를 별도 테이블의 여러 행으로 저장하는 것이다.

예를 들어 주문의 여러 상품 ID를 저장한다면:

  • orders
  • order_items

처럼 분리하는 방식이다.

이 방식의 장점:

  • 조건 검색이 쉽다
  • 인덱스를 걸기 쉽다
  • 원소 단위 수정과 확장이 쉽다

단점:

  • 조인이 필요하다
  • 단순 저장 구조보다 테이블 수가 늘어난다

대부분의 관계형 DB 실무에서는 이 방식이 기본값에 가깝다.

2. 문자열이나 JSON으로 한 컬럼에 넣는 방식

배열을 콤마 구분 문자열이나 JSON 배열로 넣을 수도 있다.

예:

  • "1,2,3,4"
  • ["A","B","C"]

장점:

  • 저장이 단순하다
  • 초기 구현 속도가 빠르다

단점:

  • 조건 검색이 어렵다
  • 부분 수정이 불편하다
  • 인덱스 활용이 제한적이다
  • 데이터 정합성을 DB 레벨에서 보장하기 어렵다

즉, 보여주기용 속성이나 단순 캐시성 데이터가 아니라면 장기적으로는 불리한 경우가 많다.

3. DB가 배열 타입을 지원하는 경우

일부 데이터베이스는 배열 타입이나 JSON 타입을 더 적극적으로 지원한다. 예를 들어 PostgreSQL은 배열과 JSONB를 다룰 수 있다.

이 경우 선택지는 더 넓어지지만, 여전히 중요한 것은 질의 패턴이다.

지원된다고 해서 무조건 좋은 것이 아니라:

  • 검색 조건이 복잡한가
  • 인덱스 전략이 충분한가
  • ORM이 이를 자연스럽게 다루는가

를 함께 봐야 한다.

언제 별도 테이블이 유리한가

다음 조건이면 보통 별도 테이블이 낫다.

  • 원소별 조회가 필요하다
  • 특정 원소 포함 여부를 자주 찾는다
  • 원소 단위 업데이트가 일어난다
  • 원소 자체가 독립 의미를 가진다

예:

  • 주문 항목
  • 사용자 권한 목록
  • 상품 옵션

이런 경우는 배열처럼 보여도 사실상 독립 엔티티에 가깝다.

언제 한 컬럼 저장이 허용될 수 있는가

다음처럼 제한된 경우에는 한 컬럼 저장도 실용적일 수 있다.

  • 조회 시 통째로만 사용한다
  • 부분 검색이 없다
  • 수정 빈도가 낮다
  • 데이터 규모가 작다

예:

  • 화면 설정값 목록
  • 단순 태그 캐시
  • 로그성 부가 정보

다만 이 경우에도 “나중에 검색이 필요해질 가능성”을 한 번은 점검해야 한다.

ORM 관점에서 생기는 문제

JPA 같은 ORM에서는 컬렉션 매핑을 쉽게 느낄 수 있지만, 실제 저장 구조와 쿼리 비용은 여전히 DB 모델링의 문제다.

즉:

  • 매핑이 가능하다고 좋은 모델은 아니다
  • 객체 구조와 테이블 구조를 구분해서 봐야 한다

배열이 객체에서는 자연스러워도, 테이블에서는 분리된 행이 더 자연스러운 경우가 많다.

정리

배열을 DB에 저장할 때 중요한 것은 저장 형식보다 조회와 수정 패턴이다.

  • 검색과 수정이 중요하면 별도 테이블
  • 통째로만 쓰는 작은 속성이면 컬럼 저장 가능
  • DB 지원 타입을 쓰더라도 질의 패턴을 먼저 본다

결국 배열을 어떻게 저장할지는 문법 문제가 아니라, 데이터가 이후에 어떤 방식으로 사용될 것인지를 먼저 정의하는 모델링 문제다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

댓글

아직 댓글이 없습니다