콘텐츠로 이동

데이터 타입

테이블 컬럼을 만들 때 저장할 데이터의 종류에 맞는 타입을 지정해야 한다. 잘못된 타입 선택은 저장 공간 낭비, 성능 저하, 정합성 문제를 일으킨다.

핵심: 데이터 타입은 저장 공간, 연산 성능, 정확도, 범위를 모두 고려하여 선택해야 합니다. 특히 금액, 날짜, 문자열은 타입 선택이 매우 중요합니다.

어떻게 쓰는지

컬럼 정의 시 타입 지정

CREATE TABLE product (
    id          BIGINT PRIMARY KEY AUTO_INCREMENT,
    name        VARCHAR(255) NOT NULL,
    price       DECIMAL(10, 2),          -- 금액 (정수 10자리, 소수 2자리)
    discount    DECIMAL(5, 2) DEFAULT 0, -- 할인율
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

타입 변환 (CAST)

-- 문자를 숫자로
SELECT CAST('123' AS INT);

-- 숫자를 문자로
SELECT CAST(123 AS VARCHAR(10));

-- 날짜 포맷 변환
SELECT DATE_FORMAT(created_at, '%Y-%m-%d') FROM product;

언제 쓰는지

상황 타입 이유
정수 ID(PK) ✅ INT / BIGINT 4/8 byte, 빠른 인덱싱
금액/통화 ✅ DECIMAL 정확한 소수점 계산
과학 계산 ✅ FLOAT / DOUBLE 근사치 연산 가능
이메일·URL ✅ VARCHAR(255) 가변 길이, 효율적
고정 길이 ✅ CHAR(n) 주민번호, 국가코드
긴 텍스트 ✅ TEXT / LONGTEXT 게시글, 설명
상태 플래그 ✅ TINYINT / BOOLEAN 1 byte 절약
생성 일시 ✅ DATETIME / TIMESTAMP DATETIME 권장
JSON 저장 ✅ JSON MySQL 5.7+
파일 저장 ✅ VARCHAR (URL) 실제 파일은 S3 등

장점

장점 설명
저장 공간 절약 적절한 타입 선택으로 메모리 효율성
검색 성능 올바른 타입 = 인덱스 효율성 향상
연산 속도 DECIMAL vs FLOAT는 성능 차이 크다
정확성 금액은 DECIMAL, 날짜는 DATETIME
범위 관리 타입으로 저장 가능한 범위 명확

단점

단점 설명
마이그레이션 비용 타입 변경은 대용량 테이블에서 많은 시간
DBMS 호환성 JSON, DECIMAL 지원 버전 다름
유연성 부족 범위 초과 시 타입 자체 변경 필요
암묵적 형변환 FLOAT 오차, 문자열 자동 변환 위험

숫자형

타입 크기 범위 사용 예
TINYINT 1 byte -128 ~ 127 (UNSIGNED: 0~255) boolean 대용, 상태값
SMALLINT 2 byte -32,768 ~ 32,767
INT / INTEGER 4 byte 약 ±21억 일반 정수, PK
BIGINT 8 byte 약 ±922경 대용량 PK, 타임스탬프
DECIMAL(p, s) 가변 정밀한 소수 금액·통화 (정확도 우선)
FLOAT / DOUBLE 4 / 8 byte 부동소수점 과학 계산 (근사치)

위험: 금액에 FLOAT/DOUBLE을 쓰면 부동소수점 오차로 계산이 틀릴 수 있다. 반드시 DECIMAL을 사용한다.

문자형

타입 특징 사용 예
CHAR(n) 고정 길이, 빈 공간은 공백 패딩 주민번호, 국가코드 등 길이가 항상 일정한 값
VARCHAR(n) 가변 길이, 실제 길이만큼만 저장 이름, 이메일 등 길이가 다양한 문자열
TEXT 최대 65,535 byte 게시글 본문 등 긴 텍스트
LONGTEXT 최대 4GB 매우 큰 텍스트

: CHAR(10)은 항상 10바이트를 차지하지만 읽기 속도가 빠르다. VARCHAR(10)은 저장 공간을 아끼지만 길이 정보를 별도로 관리한다. 길이가 고정된 값이라면 CHAR가 유리하다.

날짜·시간형

타입 형식 범위 특징
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-31 날짜만 저장
TIME HH:MM:SS 시간만 저장
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 ~ 9999 시간대 변환 없음
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970 ~ 2038 UTC 저장, 조회 시 시간대 변환

주의: TIMESTAMP는 2038년 문제(Unix 32bit 오버플로)가 있다. 장기 보존 데이터는 DATETIME을 쓰되 애플리케이션 레벨에서 UTC 관리를 권장한다.

기타

타입 설명
BOOLEAN / BOOL MySQL에서는 내부적으로 TINYINT(1)
JSON MySQL 5.7+, PostgreSQL 9.2+ 지원. JSON 형식 데이터 저장 및 경로 조회 가능
BLOB 이진 데이터 (이미지·파일). 실무에서는 파일 자체는 S3 등 외부 저장소에 두고 DB에는 URL만 저장하는 방식을 선호

주의할 점

  • FLOAT/DOUBLE금액에 절대 사용하지 않는다. DECIMAL(10, 2) 같은 형식을 사용한다.
  • VARCHAR 크기는 여유 있게 설정하되 너무 크면 메모리 낭비가 생긴다. (MySQL VARCHAR(255)가 관행)
  • TIMESTAMP의 2038년 문제를 인지하고, 신규 개발에서는 DATETIME + 애플리케이션 UTC 관리를 권장한다.
  • TEXT/BLOB 컬럼은 인덱스를 전체 컬럼에 걸 수 없다. 필요하면 접두사 인덱스(INDEX (col(100)))를 사용한다.