MongoDB 대신 단일 Postgres 테이블 사용
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- NoSQL 데이터베이스(예: MongoDB) 사용자
- 스키마 유연성과 SQL 기능을 동시에 필요로 하는 개발자
- 복잡한 데이터 구조를 관리하는 데 어려움을 겪는 프로젝트 팀
- 중간~고급 수준의 PostgreSQL 사용자
핵심 요약
- JSONB의 핵심 강점:
- 이진 형식으로 저장되어 성능이 우수한 JSONB
타입 사용
- GIN 인덱스
로 빠른 쿼리 처리 가능
- @>
, ?
, ->>
, #>
등 Native SQL 연산자 활용
- MongoDB 대체 시나리오:
- 사용자 선호도, 이벤트 로그, 제품 카탈로그 등 유연한 데이터 저장이 필요한 경우
- 하이브리드 스키마
를 통해 구조화된 필드와 유연한 JSONB 필드 동시 사용
- 실무 팁:
- GIN 인덱스
와 to_tsvector
를 활용한 풀텍스트 검색 구현
- 외래 키, 집계 연산, 빈번한 업데이트가 필요한 경우 일반 컬럼 사용 권장
섹션별 세부 요약
1. JSONB의 핵심 특징
- Binary Storage: JSONB는 이진 형식으로 저장되어 메모리 사용과 처리 속도가 향상
- GIN 인덱스: JSONB 필드에 대한 복잡한 쿼리 최적화 가능
- Native 연산자:
@>
(포함 여부),?
(키 존재 여부),->>
(텍스트 추출) 등 SQL 연산자 사용 가능 - SQL 기능: JSONB를 기반으로 SQL의 집계, 조인, 트랜잭션 등 전통적인 기능 활용
2. 인덱싱 전략
- 특정 경로 인덱싱:
CREATE INDEX idx_user_email ON users ((data->>'email'))
- 존재 여부 인덱싱:
CREATE INDEX idx_attributes ON products USING GIN (attributes)
- 포함 여부 인덱싱:
CREATE INDEX idx_preferences ON users USING GIN (preferences)
- 풀텍스트 검색:
to_tsvector('english', data->>'content')
와plainto_tsquery
조합
3. 실무 예시: 사용자 선호도 저장
- 하이브리드 테이블 구조:
```sql
CREATE TABLE users (
id UUID PRIMARY KEY,
email TEXT NOT NULL,
preferences JSONB,
metadata JSONB
);
```
- 쿼리 예시:
```sql
SELECT email FROM users
WHERE preferences @> '{"theme": "dark", "notifications": {"email": true}}';
```
- 업데이트 예시:
```sql
UPDATE users
SET preferences = jsonb_set(preferences, '{notifications,push}', 'true')
WHERE email = 'john@example.com';
```
4. 이벤트 로그 저장
- 다양한 이벤트 데이터 저장:
```sql
CREATE TABLE events (
id UUID PRIMARY KEY,
event_type TEXT,
data JSONB
);
```
- 인덱싱 예시:
```sql
CREATE INDEX idx_events_type_data ON events (event_type)
WHERE event_type IN ('purchase', 'signup', 'feedback');
```
- 쿼리 예시:
```sql
SELECT * FROM events
WHERE event_type = 'purchase'
AND data @> '{"discount": "SUMMER20"}';
```
5. 제품 카탈로그 저장
- 다양한 속성 저장:
```sql
CREATE TABLE products (
id UUID PRIMARY KEY,
name TEXT,
attributes JSONB
);
```
- 쿼리 예시:
```sql
SELECT name, price FROM products WHERE attributes @> '{"5g": true}';
```
- 복잡한 조건 쿼리:
```sql
SELECT * FROM products
WHERE (attributes->'screen'->>'size')::FLOAT > 6.0;
```
6. 하이브리드 스키마 설계
- 일반 컬럼과 JSONB 혼합:
```sql
CREATE TABLE orders (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
total NUMERIC(10,2) NOT NULL,
status TEXT NOT NULL,
line_items JSONB,
metadata JSONB
);
```
- 이점: 외래 키, 집계 연산, 빈번한 업데이트에 대한 안정성 확보
7. MongoDB에서 PostgreSQL로 마이그레이션
- Python 예제 코드:
```python
import psycopg2
from pymongo import MongoClient
for doc in mongo.mydb.mycollection.find():
postgres.execute(
"INSERT INTO my_table (id, data) VALUES (%s, %s)",
(str(doc['_id']), Json(doc))
)
```
결론
- JSONB 활용 시: 사용자 설정, 이벤트 로그, 제품 카탈로그 등 유연한 데이터 저장이 필요한 경우 JSONB 사용 권장
- 전통적 컬럼 활용 시: 외래 키, 집계 연산, 빈번한 업데이트가 필요한 경우 일반 컬럼 사용
- 하이브리드 스키마를 통해 구조화된 데이터와 유연한 JSONB의 장점을 동시에 활용하는 것이 최적의 선택
- GIN 인덱스와 풀텍스트 검색을 통해 성능 최적화를 달성할 수 있음