기록
PostgreSQL의 JSON/JSONB 배운 것 정리
als982001
2025. 4. 19. 18:05
1. JSON과 JSONB의 차이점
항목 | JSON | JSONB |
저장 방식 | 텍스트를 그대로 저장 | 이진(Binary) 형식으로 저장 |
검색 성능 | 느림 | 빠름(인덱싱 가능) |
키 순서 | 보존함 | 보존하지 않음 |
중복 키 | 허용 | 마지막 키만 유지됨 |
사용 추천 | 로깅 등 읽기 전용 | 대부분의 경우 JSONB 권장 |
2. JSON 데이터 조회의 주요 연산자
연산자 | 설명 |
-> | JSON 객체에서 값 추출 (JSON 형식 그대로 반환) |
->> | 문자열로 추출 |
#> | 중첩 경로로 접근 |
#>> | 중첩 경로에서 문자열 추출 |
? | 해당 키 존재 여부 확인 |
@> | 포함 여부 확인 |
JSONB_ARRAY_LENGTH() | 배열 길이 구하기 |
|| | 병합 연산자로 두 JSONB 값을 합쳐서 하나의 JSONB 객체로 만드는 역할 (JSONB 전용) |
2-1. 연산자 활용 관련
상황 | 사용 예 |
JSON 컬럼에서 특정 필드 값만 추출 | profile ->> 'name' |
배열 길이 계산 | JSONB_ARRAY_LENGTH(profile -> 'hobbies') |
필드 존재 여부 검사 | profile ? 'email' |
키-값 조건으로 필터링 | profile -> 'hobbies' ? 'reading' |
3. 예시 코드
3-1. 테이블 생성 및 데이터 삽입
CREATE TABLE users (
user_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
profile JSONB
);
INSERT INTO users (profile) VALUES
('{"name": "Taco", "age": 30, "city": "Budapest"}'),
('{"name": "Giga", "age": 25, "city": "Tbilisi", "hobbies": ["reading", "climbing"]}');
3-2. JSON 생성 함수
SELECT JSON_BUILD_OBJECT('name', 'Taco', 'age', 30, 'city', 'Budapest');
-- → {"name": "Taco", "age": 30, "city": "Budapest"}
3-3. 기본 조회
SELECT
profile ->> 'name' AS name,
profile -> 'city' AS city,
profile -> 'hobbies' -> 0 AS first_hobby
FROM users;
3-4. 특정 키 존재 여부 확인
SELECT * FROM users WHERE profile ? 'hobbies';
3-5. 배열 안에 특정 값 포함 확인
SELECT * FROM users WHERE profile -> 'hobbies' ? 'climbing';
3-6. 여러 키 중 하나라도 포함 확인
SELECT * FROM users WHERE profile ?| ARRAY['reading', 'traveling'];
SELECT * FROM users WHERE profile ?| ARRAY['name', 'email'];
3-7. 문자열 필터링
SELECT * FROM users WHERE profile ->> 'city' LIKE 'B%';
3-8. 키 추가/병합
UPDATE users
SET profile = profile || JSONB_BUILD_OBJECT('email', 'x@x.com');
3-9. 키 삭제
UPDATE users
SET profile = profile - 'email'
WHERE profile ->> 'name' = 'Giga';
3-10. 배열 값 덮어쓰기
UPDATE users
SET profile = profile || JSONB_BUILD_OBJECT(
'hobbies',
JSONB_BUILD_ARRAY('climbing', 'traveling')
)
WHERE profile ->> 'name' = 'Taco';
3-11. 배열에 요소 추가 (덧붙이기)
UPDATE users
SET profile = profile || JSONB_SET(
profile,
'{hobbies}',
(profile -> 'hobbies') || JSONB_BUILD_ARRAY('cooking')
);