데이터베이스 자료형에 대해 알아보자!
728x90

먹물 프로젝트를 진행하면서, 데이터베이스 설계 시 자료형을 어떤 것을 쓸지 선택하는 것이 성능, 저장소 효율성 등에 큰 영향을 끼친다는 것을 느꼈습니다. 이를 계기로 데이터베이스 자료형에 대해서 알아보자는 목표를 갖게 되어 해당 내용을 정리하게 되었습니다.

 

데이터베이스 자료형

자료형(Data type)은 데이터베이스에서 각 필드에 저장할 데이터의 속성을 정의하는 요소이다. 올바른 자료형을 선택해야 데이터 무결성을 보장하고, 저장 공간을 최적화하며, 쿼리 성능을 향상시킬 수 있어 자료형을 정할 때 꼭 유의해야 한다.

 

데이터베이스마다 자료형은 약간씩 차이가 있다. 일단 MySQL을 기반으로 자료형에 대해서 살펴보겠다.

 

(1) 숫자형(Numeric)

  • 정수형: INT, BIGINT, MEDIUMINT, SMALLINT, TINYINT
    • 데이터 크기를 고려하여 선택해야한다.
    • TINYINT: -128 ~ 127 범위, 작은 숫자를 저장할 때 사용.
    • INT: -2,147,483,648 ~ 2,147,483,647 범위, 일반적인 숫자 저장에 적합.
    • BIGINT: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807, 대규모 데이터 처리에 사용.
    • (ex) BIGINT는 매우 큰 숫자를 다룰 때만 사용한다.
[주의]
INT(5)에서 괄호 안 숫자는 화면 표시용 숫자 자릿수로, 데이터 저장 크기에 영향을 미치지 않는다.
예: INT(5)는 00001처럼 앞에 0을 붙여 표시.
ZEROFILL은 사용이 제한되거나 비권장(Deprecated)될 가능성이 있으므로 주의해야 한다.

 

  • 실수형: FLOAT, DOUBLE(Deprecated), DECIMAL 
    • 정확도를 보장하는 데이터 타입에 대해 구분하여 사용해야 한다.
    • FLOAT: 부동소수점 숫자 저장. 저장 크기가 작지만, 정밀도가 떨어짐.
    • DOUBLE: 더 큰 범위를 지원하는 부동소수점 (현재 Deprecated).
    • DECIMAL: 고정소수점 숫자. 금액과 같은 정확도가 필요한 값에 적합.
    • (ex) 금액 계산에는 부동소수점(FLOAT) 대신 정확도를 보장하는 DECIMAL을 사용해야 한다.
왜 DOUBLE은 Deprecated인가?
DOUBLE은 정밀도가 낮아 금액 계산 같은 데이터에서 오류가 발생할 가능성이 큽니다. DECIMAL을 사용하여 정밀도를 보장하는 것이 권장됩니다.

 

(2) 문자형(String)

  • 고정 길이: CHAR (고정된 길이의 문자열, 짧은 데이터에 적합) -> 데이터가 고정된 경우 성능이 더 좋음.
    • CHAR는 짧고 고정된 데이터(예: 국가 코드, 우편 번호)에서 유리합니다.
  • 가변 길이: VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT (가변 길이 문자열, 긴 데이터에 적합) -> 가변 길이. 저장 공간 효율적임.
    • VARCHAR:
      • 최대 65,535 바이트까지 저장 가능 (row 크기 제한 포함).
      • 인덱스를 지원하며, 검색 성능이 뛰어남.
      • 데이터 크기만큼의 저장 공간만 사용.
    • TEXT:
      • 최대 4GB 크기의 데이터 저장 가능.
      • 인덱스 생성 시, 앞부분 일부만 인덱싱.
      • TEXT는 메모리에서 직접 조작되지 않고 별도의 저장 공간을 사용하므로, VARCHAR보다 검색 성능이 떨어질 수 있음.

 

(3) 날짜와 시간형(Date and Time)

  • DATE, TIME, DATETIME, TIMESTAMP, YEAR
    • YEAR: 1901~2155 범위의 연도를 저장.
      • 특정 연도만 저장할 때 공간을 절약할 수 있다.
    • DATETIME: 1000-01-01 00:00:00부터 9999-12-31 23:59:59까지의 값을 저장.
    • TIMESTAMP: 1970-01-01 00:00:01 UTC부터 2038-01-19 03:14:07 UTC까지 값을 저장. (시간대 정보를 포함한다.)
      • 2038년 문제: TIMESTAMP는 UNIX 시간을 기반으로 하여 범위를 초과하면 데이터가 올바르게 저장되지 않을 수 있음.
-- TIMESTAMP 사용 예제
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

-- DATETIME 사용 예제
event_date DATETIME;
TIMESTAMP는 시간대(Timezone)를 저장하지만 DATETIME은 시간대 정보를 포함하지 않습니다.
TIMESTAMP는 자동으로 CURRENT_TIMESTAMP를 기본값으로 설정할 수 있으나, DATETIME은 별도의 설정이 필요합니다.

 

(4) 이진형(Binary)

  • BLOB, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
    • BLOB
      • 대용량 바이너리 데이터를 저장.
      • 파일이나 이미지는 외부 스토리지를 사용하는 것이 일반적.
    • JSON
      • 비정형 데이터를 저장.
      • MySQL 5.7 이상부터 JSON 자료형을 지원하며, JSON 함수로 효율적으로 쿼리 가능.
MySQL은 BLOB 데이터를 조작할 때 메모리를 많이 사용하므로 성능 문제가 발생할 수 있으니, 파일 스토리지 사용을 고려해야 한다.
또한, JSON 데이터는 인덱싱에 제약이 있으므로 검색 속도가 느려질 수 있다. 분석과 조회가 빈번하다면 정규화된 관계형 데이터로 변환을 고려해야한다.

 

(5) 기타 자료형

  • ENUM, SET, JSON

 

 

자주 쓰이는 필드들에 대해서 어떤 자료형을 쓸지 고민하게 되는 때가 있다. 대표적으로 몇 가지의 예시만 들어보겠다.

자료형 선택 사례

사용자 ID

  • UUID vs BIGINT
    • UUID: 고유성을 보장. 하지만 크기가 크고, 인덱싱 성능 저하 가능성 있음.
    • BIGINT: 숫자 기반의 간단한 ID.

상태 코드

  • ENUM vs TINYINT
    • ENUM: 값 제한이 간단한 경우 유용.
    • TINYINT: 상태 변경이 자주 발생하거나 다국어 지원이 필요한 경우 별도 테이블과 함께 사용.

로그 데이터

  • TEXT vs JSON
    • TEXT: 단순 로그 데이터.
    • JSON: 구조화된 로그 데이터로 추가 분석 가능.

금액 필드

  • FLOAT vs DECIMAL
    • 금액은 DECIMAL 사용이 필수.

 

 

DB를 설계하고, 자료형을 선택할 때 생각해야할 체크리스트!

  • 데이터 범위를 초과하지 않는 자료형인가?
  • 적절한 길이의 자료형인가?
  • 검색 속도 등 성능을 고려한 자료형인가?
  • 연산 시 정확도를 보장하는 자료형인가?
  • DBMS 간 자료형 매핑을 고려하였는가?
  • 정규화를 통해 데이터 중복을 줄이고 자료형 선택을 간소화하였는가?
  • 적절한 인덱스 설정하였는가?
728x90
반응형