포스트

물리적 모델링

물리적 모델링

물리적 모델링 개요

물리적 모델링이란?

논리적 모델을 특정 DBMS의 특성과 성능을 고려하여 구체적인 저장 구조, 즉 물리적 스키마로 변환하는 과정입니다.

물리적 모델링 프로세스

  • 테이블과 컬럼 변환
    • 논리적 모델의 한글 이름을 영문 이름으로 변환
    • 이때 테이블명 컬럼명을 정하는 규칙을 정하고 적용 (용어 사전 참고)
  • 데이터 타입 정의
    • 각 컬럼에 가장 적합한 데이터 타입을 선택
    • 이는 저장 공간과 성능에 직접적인 영향을 미침
  • 제약 조건 설정
    • 기본 키, 외래 키, NOT NULL 등 데이터의 무결성을 보장하기 위해 제약 조건을 구체적으로 설정
  • 인덱스 설계
    • 데이터 조회 성능을 극대화 하기 위해 어떤 컬럼에 인덱스를 생성할지 결정
  • 역정규화 및 성능 튜닝
    • 필요에 따라 정규화 원칙을 위배하여 테이블을 통합하거나 중복 데이터를 추가하는 역정규화를 구행하여 성능을 개선 (최후의 수단)
  • 파티셔닝, 샤딩 등 기타 기법 적용
    • 대용량 테이블의 경우 특정 기준으로 데이터를 분할아여 저장하는 파티셔닝 같은 고급 기법을 고려
  • 뷰, 저장 프로시저, 함수, 트리거 생성
    • 완성된 테이블 구조 위에서 필요한 뷰, 프로시저, 트리거 등 추가적인 DB 객체를 생성

테이블과 컬럼 변환 규칙

기본 규칙

일반적인 명명 규칙(Naming Convention)

  • 영어 사용
    • DB 객체의 이름은 영어를 사용하는 것이 국제적인 표준
    • 한글 이름을 사용할 경우, 개발 환경이나 라이브러리에서 호환성 문제가 발생할 수 있음
  • 소문자 스네이크 케이스(snake_case)
  • 명확하고 서술적인 이름
    • 이름만 보고도 그 역할과 의미를 명확히 알 수 있도록 짓기
    • 의미 없는 축약은 피하는 것이 좋음
    • 용어 사전에 등록 된 상황이라면 축약어로 쓰는 것이 더 좋음
  • 일관성 있는 접두사와 접미사
    • 모든 테이블의 PK테이블명_id 처럼 일관된 것이 좋음
  • 예약어 사용 금지

컬럼 이름 규칙

  • 기본 키(PK)테이블명_id 로 명명
  • 외래 키(FK)는 참조하는 테이블의 PK 이름을 그대로 사용
  • 날짜/시간 컬럼은 접미사로 용도를 명확히 한다.
    • _at: 특정 작업이 발생한 정확한 시점을 기록할 때 사용
      • 주로 특정 사건(이벤트)가 발생한 시간을 기록할 때 사용 주문 시각, 취소 시각, 로그인 시각 등
      • created_at, updated_at, deleted_at, logined_at, ordered_at, paid_at
    • _datetime, dt: 일시, 날짜와 시간 정보가 중요할 때 사용. 너무 길기 때문에 dt로 줄여서 많이 사용
      • 예약일시, 이벤트 시작/종료 시각이나 예약 시각 처럼 특정 기간이나 시점을 명시할때 유용
      • staert_dt, end_dt, reservation_dt
    • _date: 날짜 정보에만 사용. 시간 정보가 필요 없거나 의미가 없는 경우에 적함
      • 생년월일이나 상품 출시일 등
    • _time: 시간 정보에만 사용. 날짜와 관 없이 특정 시간 정보가 필요할 때 사용
      • 상점의 영업 시작 및 종료 시간이나, 매일 반복되는 알림 시간 설정 등
  • 불리언(Boolean) 타입은 'is_ 또는 has_' 접두사를 사용
  • 컬럼은 단수 명사 사용
  • 의미 있는 축약어
    • 팀 내에서 모두가 동의하고 그 의미를 명확히 알 수 있는 축약어가 아니라면, 완전한 단어를 사용하는 것이 좋음
  • 데이터의 성격을 명확히 표현
    • 단위나 종류 명시
      • 만약 여러 국가의 통화를 지원한다면, price 대신 price_krw, price_usd 처럼 통화 단위를 명시해 주는 것이 좋음
    • 문맥 제공
      • 여러 테이블에서 많이 사용하는 단어의 경우 테이블명 + 단어로 짓는것이 좋음
      • 예를 들어 name은 자주 사용하므로 member_name, product_name처럼 사용하는 것이 좋음

츅약어와 단수 복수

좋은 축약어의 조건

  • 보편성
    • id, avg, max, min 처럼 누가 봐도 그 의미를 알 수 있는, 업계에서 널리 통용되는 축약어야햐 함
  • 비모호성
    • 반드시 하나의 의미로만 해석되어야 함
    • 예를 들어 descdescription(설명)descending(내림차순)으로 모두 해석 될 수 있어 혼란을 야기함
  • 일관성 및 문서화
    • 만약 특정 비즈니스 도메인에서만 통용되는 축약어를 사용해야 한다면, 반드시 프로젝트의 데이터 사전이나 용어집에 그 의미를 명확히 기록해야 함

나쁜 축약어가 초래하는 장기적 비용

  • 유지보수 비용 증가
  • 버그 발생 가능성 증가

균형을 찾는 가이드라인

  • 테이블 이름으로 컨텍스트를 파악할 수 있다면 과감히 생략
  • 보편적인 약어는 적극적으로 활용
  • 이름이 너무 길다면, 모델링이 잘못된 것은 아닌지 의심해라

테이블 이름: 단수(Singular) vs 복수(Plural)

  • 한국에서는 주로 단수형을 사용

데이터 타입

문자, 숫자, PK 타입

문자열 타입

  • VARCHAR(M)
    • 장점: 공간 효율이 좋다
    • 단점: 길이가 변하기 때문에 데이터 수정 시 추가적인 작업이 필요할 수 있음
    • 용도: 이름, 제목, 주소 등 대부분의 문자열 데이터에 사용
  • CHAR(M)
    • 장점: 길이가 고정되어 있어 데이터 처리 속도가 VARCHAR보다 약간 빠를 수 있음
    • 단점: 공강 낭비가 심함
    • 용도: 주민등록번호, 전화번호, 설명 처럼 길이가 항상 고정된 데이터에 사용

💡 실무 가이드

일단 VARCHAR를 쓰자

💡 VARCHAR가 메모리 공간을 더 많이 쓰는 이유

MySQL이 쿼리를 처리하기 위해 메모리에 임시 공간을 할당할 때 VARCHAR에 설정된 최대 길이를 기준으로 삼기 때문입니다.

숫자 타입

타입저장곤강최소값최대값용도 예시
TINYINT1-128127나이, 상태 코드
SMALLINT2-32,76832,767작음 범위의 개수
MEDIUMINT3-8,388,6088,388,607 
INT4-2,147,483,6482,147,483,647일반적인 ID, 조회수, 재고 수량
BIGINT8약 -922경약 922경매우 큰 ID(주문 번호 등)
  • 소수 타입
    • DECIMAL(M, D)
      • M: 총 자리수, D: 소수점 이하 자릿수
      • 고정 소수 점 타입, 금융 계산처럼 정확한 소수점 계산이 필요할 때 반드시 사용
    • DOUBLE, FLOAT
      • 부동 소수점 타입
      • 과학 계산이나 근사치가 허용되는 빠른 계산에 사용
      • 소수점 계산 계산 시, 미세한 오차가 발생할 수 있어, 돈과 관련된 계산에는 절대 사용하면 안됨

PK 타입 선정

INTBIGINT의 용량 차이는 미미하므로 BIGINT 사용을 권장합니다.

날짜와 시간 타입

  • 회원 가입일, 주문일, 게시물 작성일 등 대부분의 경우 DATETIME을 사용
  • 생년월일처럼 시간 정보가 필요 없는 경우에는 DATE를 사용
  • 생성일과 수정일은 기본
    • 대부분의 테이블에 created_at, updated_at 컬럼을 추가함
    • 나중에 문제 추적이나 데이터 분석에 매우 유용하게 사용

생성일과 수정일 자동화

  • DEFAULT CURRENT_TIMESTAMP: 컬럼에 기본값읗 현재 시간으로 성정
  • ON UPDATE CURRENT_TIMESTAMP: 해당 로우의 데이터가 수정 될때마다, 자동으로 현재 시간으로 값을 갱신
1
2
3
4
5
CREATE TABLE sample
(
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)

💡 실무 팁

created_at은 데이터가 처음 DB에 저장된 물리적인 시간을 기록하는 용도로, ordered_at와 같은 컬럼은 주문 접수, 결제 완료 등 비즈니스 이벤트가 발생한 논리적인 시간을 기록하는 용도로 구분해서 사용하면 시스템을 더 정교하게 관리할 수 있습니다.

똑같아 보이지만, 애플리케이션에서 작업을 처리하고 DB에 넣는 시간이 있으므로 두 시간은 다르게 기록될 수 있습니다. 따라서 ordered_at은 주문이 들어온 시점이 기록되고 created_atDB에 저장된 시간을 의미하게 됩니다.

역정규화

데이터의 조회 성능읏향상 시키기 위해, 의도적으로 데이터 모델의 정규화 원칙을 위반하여 데이터의 중복을 허용하는 프로세스 입니다.

구분정규화역정규화
목표데이터의 일관성 및 무결성 확보데이터 조회 성능 향상
장점데이터 중복 최소화 쓰기(C/U/D) 성능에 유리읽기(SELECT) 성능 향상 (JOIN 감소)
단점읽기 성능 저하 가능성(JOIN 증가)데이터 중복 증가, 쓰기 성능 불리, 데이터 불일치 위험

실무에서 사용하는 역정규화 기법

  • 중복 컬럼 추가
  • 파생 컬럼 추가(계산된 값의 저장)
  • 테이블 통합 및 분할
    • 테이블 통합: 1:1 또는 1:N 관계에서 항상 함계 조회되는 테이블들을 하나의 테이블로 합쳐 JOIN을 원천적으로 제거
    • 테이블 분할: 하나의 이블에 컬럼이 너무 많고, 일부 컬럼만 자주 사용될 때 테이블을 수직으로 분할
      • 디스크 I/O 성능을 높임
      • 자주 사용하는 컬럼들과 그러지 않은 컬럼들을 별도의 테이블로 분리하는 것

역정규화 시 데이터 일관성 유지 방안

  • 애플리케이션 로직
  • DB 트리거
  • 배치 작업

역정규화, 언제 해야할까?

  • 섣불리 적용하지 마라: 먼저 정규화 원칙에 따라 데이터 모델을 설계하는 것이 기본
  • 데이터로 증명하라: 추측이 아닌 성능 테스트를 통해 병목이 되는 쿼리를 명확히 식별해서 해야 함
  • 읽기/쓰기 비율을 고려하라: 쓰기 작업보다 읽기 작업이 압도적으로 많은 경우 적용하는 것이 효과적
  • 비용을 계산하라: 역정규화를 통해 얻는 성능적 이점과, 그로 인해 발생하는 데이터 불일치 문제 해결 및 유지보수를 위한 개발 비용을 철저히 비교 분석해야 함

💡 역정규화는 언제 적용 하는가?

역정규화는 논리적 모델이 완성된 후, 실제 DB의 성능, 저장 공간 등을 고려하여 물리적인 저장 구조를 설계하는 물리적 모델링 단계에서 적용하는 기법입니다.

🌟 반드시 선 정규화, 후 역정규화 원칙을 지켜야 합니다.

테이블 정의서

테이블 정의서의 역할

  • 의사소통의 중심
  • 유지보수의 핵심
  • 데이터 품질 보증: 각 컬럼의 제약 조건, 기본 값, 혀옹되는 값의 범위 등을 명시함으로써 데이터의 일관성과 품질을 유지하는데 기여
  • DB의 청사진: 이 문서만 보면 누구나 DB의 전체 구조를 이해하고, 테이블을 생성 할 수 있어야 함
  • 개발의 가이드: 개발자는 이 문서를 보고 테이블과 컬럼의 이름을 정확히 사용하여 SQL을 작성하고, 애플리케이션 코드를 구현

테이블 정의서 구성 요소

  • 테이블 정보
    • 테이블 한글명(논리명)
    • 테이블 영문명(물리명)
    • 테이블 설명
  • 컬럼 정보
    • No: 컬럼의 순번
    • 컬럼 한글명(논리명)
    • 컬럼 영문명(물리명)
    • 데이터 타입
    • 제약 조건
    • NULL 허용 여부
    • 기본 값
    • 비고(설명)

쇼핑몰 테이블 정의서 예시

  • 테이블 정의: member
제목내용
테이블 한글명회원
테이블 영문명member
테이블 설명쇼핑몰에 가입한 회원의 기본 정보를 저장하는 테이블
  • 컬럼 정의
No.컬럼 한글명컬럼 영문명데이터 타입제약 조건NULL 허용 여부기본 값비고
1회원IDmember_idBIGINTPK  회원의 고유 식별자(대리 키)
2로그인IDlogin_idVARCHAR(50)UQ  회원이 로그인 시 사용하는 ID
3비밀번호passwordVARCHAR(255)   비밀번호(반드시 암호화해서 저장)
4회원명member_nameVARCHAR(50)   회원의 실명
5이메일emailVARCHAR(100)UQ  회원 인증 및 소통을 위한 이메일
6주소addrVARCHAR(255) NULL 성품 배송을 위한 주소
7가입일created_atDATETIME  CURRENT_TIMESTAMP회원 가입 시점
8수정일updated_atDATETIME  CURRENT_TIMESTAMP데이터 수정 시 자동 갱신
  • addr: 축약어 합의

🌟 용어 사전과 테이블 정의서는 필수

반드시 살아있는 문서로 관리해야 합니다.

참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.