CodeGym /행동 /SQL SELF /JSON과 다른 타입 비교: ARRAY, TEXT, ...

JSON과 다른 타입 비교: ARRAY, TEXT, HSTORE

SQL SELF
레벨 34 , 레슨 3
사용 가능

PostgreSQL에서 많은 개발자들이 정보를 저장할 때 어떤 데이터 구조를 써야 할지 고민하곤 해. 좀 더 단순한 데이터 구조엔 배열(ARRAY)을 쓸까? 아니면 문자열엔 텍스트(TEXT) 컬럼을 쓸까? 혹은 "키-값" 쌍 저장엔 HSTORE가 나을까? 그리고, 언제 JSON이나 JSONB가 진짜 좋은 선택일까 하는 고민도 있지.

이걸 좀 더 쉽게 이해할 수 있게, 각 방식의 장점과 단점, 그리고 실제로 어떻게 쓰는지 예시도 보여줄게.

언제 배열(ARRAY)을 쓰고, 언제 JSONB를 써야 할까?

배열(ARRAY)은 같은 타입의 값들이 쭉 나열된 데이터에 딱 좋아. 예를 들어 학생들의 점수 리스트나, 어떤 레코드에 태그를 붙일 때 배열이 완전 잘 맞아.

배열 예시:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades INTEGER[] -- 점수 배열
);

INSERT INTO students (name, grades)
VALUES ('Alice', ARRAY[90, 85, 88]),
       ('Bob', ARRAY[70, 75, 78]);

반면에 JSONB는 좀 더 복잡하고, 중첩된 구조에 잘 어울려. 예를 들어 각 점수에 대한 설명 같은 추가 데이터를 저장하고 싶으면 JSONB가 좋아.

JSONB 예시:

CREATE TABLE students_json (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades JSONB -- 점수에 대한 데이터 객체
);

INSERT INTO students_json (name, grades)
VALUES ('Alice', '{"Math": 90, "Science": 85, "English": 88}'),
       ('Bob', '{"Math": 70, "Science": 75, "English": 78}');

주요 차이점

기준 배열(ARRAY) JSONB
구조 같은 타입의 데이터만 복잡하고 중첩된 데이터 구조
데이터 접근 인덱스로: grades[1] 키로: grades->'Math'
인덱스 지원 배열 전체에 GIN 또는 BTREE 키별로 GINBTREE 인덱스 편하게 사용
언제 사용 단순 리스트 데이터(태그, 점수, 아이디 등) 키와 값이 있는 복잡한 객체

배열과 JSONB 변환 예시

데이터를 배열에서 JSONB로, 또는 그 반대로 변환하는 방법을 볼게:

배열 → JSONB

SELECT to_jsonb(grades) AS grades_jsonb
FROM students;

-- 결과:
-- [{"90","85","88"}]

JSONB → 배열

SELECT array_agg(value::INTEGER) AS grades_array
FROM jsonb_array_elements_text('["90", "85", "88"]');
-- 결과:
-- {90,85,88}

JSONB와 텍스트 데이터(TEXT) 비교

텍스트 컬럼은 그냥 문자열이나, 구조 없는 작은 데이터를 저장할 때 딱이야. 예를 들어 상품 이름이나 설명처럼 문자열 검색이 필요하면 TEXT가 최고지.

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title TEXT,
    description TEXT
);

INSERT INTO books (title, description)
VALUES ('SQL Basics', 'SQL에 대한 간단한 소개'),
       ('Advanced PostgreSQL', 'PostgreSQL 성능에 대한 심층 가이드');

언제 JSONB를 쓰는 게 더 좋을까?

만약 네 문자열이 중첩 구조를 가진 정보(예: 카테고리와 태그 리스트가 들어간 설명)로 바뀐다면, JSONB가 더 나아.

CREATE TABLE books_json (
    id SERIAL PRIMARY KEY,
    info JSONB
);

INSERT INTO books_json (info)
VALUES ('{"title": "SQL Basics", "tags": ["beginner", "database"]}'),
       ('{"title": "Advanced PostgreSQL", "tags": ["performance", "optimization"]}');

주요 차이점

기준 텍스트(TEXT) JSONB
구조 구조 없는 데이터 구조화된, 중첩 데이터
검색 전체 텍스트 검색 키, 값, 중첩 구조로 검색
데이터 변경 전체 교체만 가능 개별 키만 수정 가능
언제 사용 단순 문자열 키-값 구조의 복잡한 데이터

JSONB와 HSTORE 비교

HSTORE는 JSONB의 형님 같은 존재로, "키-값" 쌍을 저장할 수 있어. 만약 네 데이터 구조가 단순하고(중첩이나 배열 필요 없음), HSTORE가 더 가볍고 빠를 수 있어.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    attributes HSTORE
);

INSERT INTO products (attributes)
VALUES ('"color"=>"red", "size"=>"M"'),
       ('"color"=>"blue", "size"=>"L"');

JSONBHSTORE를 대체했을까?

HSTORE는 "키-값" 쌍에 편리하지만, 중첩이나 배열을 지원하지 않아서 JSONB가 더 범용적으로 쓰이게 됐어. 단순한 객체에서 더 복잡한 구조로 넘어가면 JSONB가 자연스러운 선택이야.

주요 차이점

기준 HSTORE JSONB
구조 중첩 없는 "키-값" 쌍 완전한 중첩 구조
배열 지원 아니
검색 키로만 검색 키, 값, 중첩 구조로 검색
언제 사용 단순 키-값 복잡한 데이터 구조

적절한 데이터 타입 고르는 법?

만약 네가:

  • 단순 구조 — 리스트나 같은 타입 데이터면 배열(ARRAY)을 써.
  • 단순 문자열이나 설명이면 텍스트 컬럼(TEXT)을 써.
  • 중첩 없는 "키-값" 쌍이면 HSTORE를 골라.
  • 중첩 객체, 배열, 복잡한 데이터 구조면 JSONB가 필요해.

포맷 간 변환 예시

TEXT → JSONB

SELECT to_jsonb('간단한 텍스트 예시') AS jsonb_form;
-- 결과: "간단한 텍스트 예시"

JSONB → TEXT

SELECT info::TEXT AS text_form
FROM books_json;
-- 결과: {"title": "SQL Basics", "tags": ["beginner", "database"]}

HSTORE → JSONB

SELECT hstore_to_jsonb(attributes) AS jsonb_form
FROM products;
-- 결과: {"color": "red", "size": "M"}

JSONB → HSTORE

SELECT jsonb_to_hstore('{"color": "red", "size": "M"}') AS hstore_form;
-- 결과: "color"=>"red", "size"=>"M"

뭐에 신경 써야 할까?

최대의 유연성과 복잡한 구조 지원이 필요하면 JSONB를 골라. 하지만 네 작업이 배열, 텍스트, "키-값" 쌍처럼 단순한 데이터 구조라면 각각에 맞는 데이터 타입(ARRAY, TEXT, HSTORE)을 쓰는 게 좋아.

데이터 구조를 잘 고르면 나중에 개발할 때 골치 아픈 일도 줄고, 쿼리 성능도 더 좋아질 거야.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION