데이터 타입 고르는 건 마치 작업할 때 도구 고르는 거랑 똑같아. 못 박는데 드라이버 쓰진 않잖아(그렇지?). 데이터베이스도 마찬가지로, 제대로 된 데이터 타입을 쓰면 성능, 메모리 절약, 데이터 관리가 훨씬 쉬워져. 예를 들어, 돈을 REAL로 저장하면 정확도 문제 생길 수 있고, 짧은 문자열에 TEXT 대신 VARCHAR 쓰면 메모리도 아낄 수 있어.
데이터 타입 고를 때는 몇 가지 포인트를 생각해야 해:
데이터 성격
데이터가 어떤 카테고리인지 파악해봐: 숫자, 문자열, 논리값, 날짜, 아니면 JSON 같은 좀 더 복잡한 구조인지.
데이터 양
얼마나 많은 데이터를 저장할 건지 생각해봐. 예를 들어, 50자 이하 텍스트면 TEXT보다 VARCHAR(50)가 더 좋아.
정확도랑 범위
(특히 금융 계산처럼) 높은 정확도가 필요한지? 값의 범위를 제한하고 싶은지?
쿼리 빈도랑 성격
데이터를 얼마나 자주, 어떻게 조회할 건지 생각해봐. JSONB 같은 복잡한 타입은 처리에 리소스 더 들어가.
데이터 타입 고르는 예시
데이터마다 상황이 다 달라. 어떤 건 1원 단위까지 정확해야 하고, 어떤 건 그냥 다 들어가기만 하면 돼. 아래에 상황별로 어떤 데이터 타입이 좋은지 예시를 모아봤어.
금융 데이터
돈 저장할 땐, 회계처럼 실수하면 안 돼. 그래서 NUMERIC 타입이 제일 좋아. 이건 정확도가 높거든. 예를 들어, 이런 컬럼이 있는 테이블을 만들고 싶다고 해보자:
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| id | SERIAL | 기본 키 |
| amount | NUMERIC(10, 2) | 총 10자리, 소수점 아래 2자리 |
| currency_code | CHAR(3) | ISO 통화 코드, 예: "USD", "EUR" |
| transaction_date | TIMESTAMP | 거래 시간, 기본값은 현재 시간 |
왜 REAL은 안 되냐고? 실수 타입은 정확도 잃을 수 있어서, 금융 데이터엔 치명적이야.
문자열 데이터
유저 이름, 주소 같은 문자열 저장할 땐, 가능하면 최대 길이 항상 정해주는 게 좋아. 예를 들어, TEXT 대신 VARCHAR(50) 쓰는 식. 이러면 에러도 줄고, 메모리도 아낄 수 있어.
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| id | SERIAL | 기본 키 |
| username | VARCHAR(50) | 유저 로그인, 유니크하고 필수 |
| VARCHAR(255) | 이메일 | |
| bio | TEXT | 소개글, 길이 제한 없음 |
문자열 길이가 딱 정해져 있으면(예: 2자리 국가 코드), CHAR 쓰는 게 좋아:
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| code | CHAR(2) | ISO 국가 코드(예: "US"), 기본 키 |
| name | VARCHAR(100) | 국가 이름, 필수 |
타임스탬프 데이터
이벤트 시간이나 스케줄 저장할 땐 TIMESTAMP가 제일 좋아. 날짜랑 시간이 같이 들어가거든.
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| id | SERIAL | 기본 키 |
| event_name | VARCHAR(100) | 이벤트 이름 |
| start_time | TIMESTAMP | 이벤트 시작 시간, 필수 |
| end_time | TIMESTAMP | 이벤트 종료 시간, 필수 |
날짜만 필요하면 DATE, 시간만 필요하면 TIME 쓰면 돼.
고유 식별자
글로벌하게 유니크한 식별자 만들어야 할 땐 UUID가 딱이야. 예를 들어, 트랜잭션 고유 식별자 만들 때:
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| request_id | UUID | 요청 고유 식별자, 기본값은 gen_random_uuid()로 생성 |
| endpoint | VARCHAR(255) | 호출하는 API 엔드포인트 주소 |
| timestamp | TIMESTAMP | 요청 시간, 기본값은 현재 시간 |
JSONB: 복잡한 구조
구조가 자주 바뀌거나 복잡한 데이터(예: 유저 설정, 메타데이터) 저장할 땐 JSONB가 편해.
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| user_id | SERIAL | 기본 키(유저 ID) |
| preferences | JSONB | 유저 설정(JSON 형식) |
JSONB는 다루기 편하지만, 대량 insert/update 할 땐 성능이 좀 떨어질 수 있다는 점 참고!
배열
동일한 타입의 값 여러 개 저장해야 할 땐 배열이 좋아. 예를 들어, 태그 리스트:
| 컬럼 이름 | 데이터 타입 | 코멘트 |
|---|---|---|
| id | SERIAL | 기본 키 |
| title | VARCHAR(255) | 글 제목 |
| tags | TEXT[] | 태그 배열 |
작업별 데이터 타입 정리
| 작업 타입 | 추천 데이터 타입 | 예시 |
|---|---|---|
| 레코드 식별자 | SERIAL, BIGSERIAL, UUID |
id SERIAL PRIMARY KEY |
| 수량, 정수 | INTEGER, BIGINT |
quantity INTEGER |
| 금융 계산 | NUMERIC |
price NUMERIC(10, 2) |
| 문자열 저장 | VARCHAR(n), TEXT |
username VARCHAR(50) |
| 짧은 고정 문자열 | CHAR(n) |
status CHAR(1) |
| 날짜와 시간 | DATE, TIME, TIMESTAMP |
created_at TIMESTAMP DEFAULT NOW() |
| 고유 식별자 | UUID |
id UUID PRIMARY KEY DEFAULT gen_random_uuid() |
| 복잡한 구조(JSON) | JSONB |
metadata JSONB |
| 값 리스트 | ARRAY |
tags TEXT[] |
| 논리값 | BOOLEAN |
is_active BOOLEAN |
아마 SERIAL 빼고는 다 익숙할 거야. SERIAL은 사실 INTEGER랑 똑같은데, 테이블에서 행 식별자로 쓰는 거야.
새 행 추가할 때마다 자동으로 1씩 증가해. 테이블에 10개 행 넣으면 첫 번째 행 id는 1, 두 번째는 2 이런 식. 자세한 건 다음 강의에서 더 알려줄게 :)
GO TO FULL VERSION