오늘은 배열을 좀 더 깊게 파보고, JSONB랑 비교해서 각각의 장단점을 알아보고, 실제로 어떻게 쓰는 게 좋은지 베스트 프랙티스까지 같이 살펴볼 거야.
배열 vs JSONB: 데이터 미니 거북이 vs 박스 속 유연함
이미 알다시피, PostgreSQL 배열에는 한 가지 데이터 타입만 저장할 수 있어. 예를 들어 학생의 점수 리스트처럼 모든 요소가 숫자인 경우지.
-- 학생과 그들의 점수 테이블
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT,
grades INTEGER[] -- 점수 배열
);
JSONB는 배열과 다르게 데이터를 JSON 구조로 저장해. 이건 우리가 잘 아는 JavaScript 객체랑 비슷한데, 빠른 파싱과 인덱싱이 장점이야. JSONB에는 순서 있는 리스트도, 키-값 쌍을 가진 객체도 저장할 수 있어.
-- 학생과 다양한 정보를 담은 테이블
CREATE TABLE students_details (
id SERIAL PRIMARY KEY,
name TEXT,
details JSONB -- 유연한 JSON 구조
);
JSONB 데이터 예시:
{
"grades": [90, 82, 77],
"address": {
"city": "Berlin",
"zip": "352912"
}
}
정리하자면, 배열은 값 리스트를 다루는 간단한 방법이고, JSONB는 복잡한 데이터를 훨씬 더 유연하게 다룰 수 있어.
배열과 JSONB의 주요 차이점
| 특징 | 배열 | JSONB |
|---|---|---|
| 구조 타입 | 선형 데이터 구조 | 계층적 데이터 구조 |
| 요소 타입 | 한 가지 데이터 타입만 | 여러 가지 데이터 타입 |
| 구조 크기 | 고정(선형) | 유연, 리스트와 객체 모두 가능 |
| 접근 속도 | 고정 데이터에서 빠름 | 복잡한 검색은 느림 |
| 인덱싱 | 인덱싱 잘 지원함 | GIN 타입 인덱스 필요 |
| 사용 예시 | 간단한 값 리스트나 배열 | 복잡한 데이터: 중첩 객체/리스트 |
이제 실제로 어떻게 쓰는지 살펴보자.
언제 배열을 써야 할까?
예를 들어, 책 데이터베이스가 있고, 한 책이 여러 장르에 속할 수 있다고 해보자. 이럴 땐 배열이 딱이야.
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
genres TEXT[] -- 장르 배열
);
-- 여러 장르가 있는 책 삽입 예시
INSERT INTO books (title, genres)
VALUES ('1984', ARRAY['Dystopia', 'Political Fiction', 'Science Fiction']);
배열이 좋은 경우는 이런 거야:
- 데이터를 리스트로만 딱 저장하면 충분할 때,
- 리스트가 작고, 타입이 한 가지(예: 문자열이나 숫자)일 때,
- 그냥 리스트 저장하고 꺼내 쓰기만 하면 될 때(복잡한 연산 필요 없음).
배열의 장점
- 동일한 타입 데이터 저장이 간단함.
- 태그, 카테고리, 점수처럼 작은 리스트에 딱 좋아.
언제 JSONB를 써야 할까?
이번엔 책에 대해 더 복잡한 정보를 저장하고 싶다고 해보자. 예를 들어 장르, ISBN, 평점까지. 이럴 땐 배열로는 부족하고 JSONB가 필요해.
CREATE TABLE books_details (
id SERIAL PRIMARY KEY,
title TEXT,
details JSONB -- 책 상세정보를 JSONB로 저장
);
-- 복잡한 책 정보 삽입 예시
INSERT INTO books_details (title, details)
VALUES (
'1984',
'{"genres": ["Dystopia", "Political Fiction", "Science Fiction"],
"isbn": "9780451524935",
"rating": 8.9}'
);
JSONB가 좋은 경우는 이런 거야:
- 복잡하거나 다양한 데이터(숫자, 문자열, 리스트, 객체 등)를 저장할 때,
- 테이블 구조 바꾸지 않고 동적으로 파라미터를 추가하고 싶을 때,
- 중첩 데이터(예: 주소, 속성, 설정 등)를 저장할 때.
JSONB의 장점
- 엄청 유연함. 테이블 구조 안 바꿔도 키-값을 계속 추가할 수 있어.
- API의 JSON 응답처럼 복잡한 데이터 저장에 딱 맞아.
배열과 JSONB 중 뭘 고를까?
동일한 타입의 리스트만 저장하면 된다면 배열을 써. 예를 들어:
-- 이벤트 참가자 ID 저장
CREATE TABLE events (
id SERIAL PRIMARY KEY,
participant_ids INTEGER[]
);
데이터가 다양하거나 복잡하다면 JSONB가 더 좋아. 예를 들어:
-- 주소 등 고객 정보 저장
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
info JSONB
);
인덱싱은 배열과 JSONB가 방식이 달라. 배열엔 GIN 인덱스를 주로 쓰고, JSONB엔 데이터 구조에 따라 GIN이나 BTREE를 써.
성능
일반적인 검색 작업에선 배열이 더 빨라. JSONB는 약간 느리지만 유연성이 훨씬 좋아. 만약 그냥 요소(예: 장르나 ID)만 찾으면 배열이 훨씬 빠르지:
-- GIN 인덱스와 배열 사용
CREATE INDEX idx_genres ON books USING GIN(genres);
-- 장르로 책 필터링
SELECT * FROM books WHERE genres @> ARRAY['Science Fiction'];
데이터 존재 여부 확인
JSONB는 키로 필터링할 때 더 다양한 방법이 있어:
-- "genres" 키가 있는지 확인
SELECT * FROM books_details WHERE details ? 'genres';
-- 리스트에 요소가 있는지 확인
SELECT * FROM books_details WHERE details->'genres' ?| ARRAY['Fantasy', 'Dystopia'];
배열은 값을 바로 검색할 수 있어:
-- 배열에 요소가 있는지 확인
SELECT * FROM books WHERE genres @> ARRAY['Fantasy'];
구조의 유연성
데이터가 복잡하게 중첩되어 있다면 JSONB가 필수야:
{
"genres": ["Fantasy", "Adventure"],
"ratings": {"goodreads": 8.5, "amazon": 4.7}
}
배열로는 이걸 하려면 정규화나 추가 필드가 필요해서 귀찮아.
결론적으로, 배열과 JSONB는 경쟁자가 아니라 각각 다른 용도의 도구야. 데이터가 리스트처럼 생겼으면 배열을 쓰고, 복잡하거나 중첩되거나 다양한 데이터면 JSONB를 써. 중요한 건 성능과 인덱싱을 꼭 기억하는 거야!
GO TO FULL VERSION