물리적 모델링
물리적 모델링 개요
물리적 모델링이란?
논리적 모델을 특정 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처럼 누가 봐도 그 의미를 알 수 있는, 업계에서 널리 통용되는 축약어야햐 함
- 비모호성
- 반드시 하나의 의미로만 해석되어야 함
- 예를 들어
desc는description(설명)과descending(내림차순)으로 모두 해석 될 수 있어 혼란을 야기함
- 일관성 및 문서화
- 만약 특정 비즈니스 도메인에서만 통용되는 축약어를 사용해야 한다면, 반드시 프로젝트의 데이터 사전이나 용어집에 그 의미를 명확히 기록해야 함
나쁜 축약어가 초래하는 장기적 비용
- 유지보수 비용 증가
- 버그 발생 가능성 증가
균형을 찾는 가이드라인
- 테이블 이름으로 컨텍스트를 파악할 수 있다면 과감히 생략
- 보편적인 약어는 적극적으로 활용
- 이름이 너무 길다면, 모델링이 잘못된 것은 아닌지 의심해라
테이블 이름: 단수(Singular) vs 복수(Plural)
- 한국에서는 주로 단수형을 사용
데이터 타입
문자, 숫자, PK 타입
문자열 타입
- VARCHAR(M)
- 장점: 공간 효율이 좋다
- 단점: 길이가 변하기 때문에 데이터 수정 시 추가적인 작업이 필요할 수 있음
- 용도: 이름, 제목, 주소 등 대부분의 문자열 데이터에 사용
- CHAR(M)
- 장점: 길이가 고정되어 있어 데이터 처리 속도가 VARCHAR보다 약간 빠를 수 있음
- 단점: 공강 낭비가 심함
- 용도: 주민등록번호, 전화번호, 설명 처럼 길이가 항상 고정된 데이터에 사용
💡 실무 가이드
일단
VARCHAR를 쓰자
💡
VARCHAR가 메모리 공간을 더 많이 쓰는 이유MySQL이 쿼리를 처리하기 위해 메모리에 임시 공간을 할당할 때
VARCHAR에 설정된 최대 길이를 기준으로 삼기 때문입니다.
숫자 타입
| 타입 | 저장곤강 | 최소값 | 최대값 | 용도 예시 |
|---|---|---|---|---|
| TINYINT | 1 | -128 | 127 | 나이, 상태 코드 |
| SMALLINT | 2 | -32,768 | 32,767 | 작음 범위의 개수 |
| MEDIUMINT | 3 | -8,388,608 | 8,388,607 | |
| INT | 4 | -2,147,483,648 | 2,147,483,647 | 일반적인 ID, 조회수, 재고 수량 |
| BIGINT | 8 | 약 -922경 | 약 922경 | 매우 큰 ID(주문 번호 등) |
- 소수 타입
DECIMAL(M, D)- M: 총 자리수, D: 소수점 이하 자릿수
- 고정 소수 점 타입, 금융 계산처럼 정확한 소수점 계산이 필요할 때 반드시 사용
DOUBLE, FLOAT- 부동 소수점 타입
- 과학 계산이나 근사치가 허용되는 빠른 계산에 사용
- 소수점 계산 계산 시, 미세한 오차가 발생할 수 있어, 돈과 관련된 계산에는 절대 사용하면 안됨
PK 타입 선정
INT와 BIGINT의 용량 차이는 미미하므로 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_at은DB에 저장된 시간을 의미하게 됩니다.
역정규화
데이터의 조회 성능읏향상 시키기 위해, 의도적으로 데이터 모델의 정규화 원칙을 위반하여 데이터의 중복을 허용하는 프로세스 입니다.
| 구분 | 정규화 | 역정규화 |
|---|---|---|
| 목표 | 데이터의 일관성 및 무결성 확보 | 데이터 조회 성능 향상 |
| 장점 | 데이터 중복 최소화 쓰기(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 | 회원ID | member_id | BIGINT | PK | 회원의 고유 식별자(대리 키) | ||
| 2 | 로그인ID | login_id | VARCHAR(50) | UQ | 회원이 로그인 시 사용하는 ID | ||
| 3 | 비밀번호 | password | VARCHAR(255) | 비밀번호(반드시 암호화해서 저장) | |||
| 4 | 회원명 | member_name | VARCHAR(50) | 회원의 실명 | |||
| 5 | 이메일 | VARCHAR(100) | UQ | 회원 인증 및 소통을 위한 이메일 | |||
| 6 | 주소 | addr | VARCHAR(255) | NULL | 성품 배송을 위한 주소 | ||
| 7 | 가입일 | created_at | DATETIME | CURRENT_TIMESTAMP | 회원 가입 시점 | ||
| 8 | 수정일 | updated_at | DATETIME | CURRENT_TIMESTAMP | 데이터 수정 시 자동 갱신 |
- addr: 축약어 합의
🌟 용어 사전과 테이블 정의서는 필수
반드시 살아있는 문서로 관리해야 합니다.