티스토리 뷰
| 질문 |
| 부서테이블과 사용자를 설계하고 사용자가 각종 신청을 할때 신청 당시의 부서와 현재의 부서가 달라졌을때, 그리고 부서의 명칭과 부서가 소멸되는 경우의 케이스도 존재, 부서테이블과 사용자만으로는 기존의 부서 정보를 알 수 없어 히스토리성 테이블을 두고자하면 정규화의 위배일까요? |
결론부터 말씀드리면, 질문하신 설계 방식은 정규화 위배가 아니라, 오히려 '데이터 무결성'과 '이력 관리'를 위한 매우 정석적인 설계입니다.
정규화는 "현재 시점의 데이터 중복"을 제거하는 것에 초점을 맞춥니다. 하지만 비즈니스 로직에서 **"과거 특정 시점의 상태"**를 보존해야 한다면, 이를 별도의 이력(History) 테이블이나 스냅샷 컬럼으로 관리하는 것은 데이터베이스 설계의 필수 요소입니다.
상황별로 가장 효율적인 설계 패턴 2가지를 제안해 드립니다.
1. 신청(Request) 테이블에 스냅샷 저장 (가장 권장)
사용자가 신청을 하는 시점의 부서 정보를 신청 테이블 자체에 기록하는 방식입니다.
- 방법: 신청_테이블에 신청당시_부서ID, 신청당시_부서명 컬럼을 포함시킵니다.
- 이유: 부서명이 바뀌거나 부서가 사라져도, 해당 신청 건이 발생했을 때의 "정황"은 변하지 않아야 하기 때문입니다. 이는 정규화 위배가 아니라 **데이터의 불변성(Immutability)**을 확보하는 것입니다.
2. 부서 이력(History) 테이블 운영
부서의 명칭 변경, 신설, 소멸 과정을 모두 기록하는 방식입니다.
- 구조: 부서_ID, 부서명, 시작일자, 종료일자, 상태(사용/폐지)
- 활용: 사용자의 신청 테이블에는 신청일시가 있으므로, 이 일자를 조건으로 부서_이력_테이블과 조인하여 그 당시에 해당 부서의 이름이 무엇이었는지 찾아낼 수 있습니다.
3. 정규화 관점에서의 해석
왜 이것이 정규화 위배가 아닌지 명확히 짚어드릴게요.
| 구분 | 일반적인 정규화 (Current State) | 이력 관리 설계 (Temporal Data) |
| 목적 | 현재 데이터의 중복 제거 및 무결성 | 시간의 흐름에 따른 데이터 변화 추적 |
| 중복 판단 | "지금 부서명이 두 번 들어가 있네? 중복이다!" | "그때의 부서명과 지금 부서명은 서로 다른 시점의 데이터다!" |
| 설계 원칙 | 함수적 종속성 제거 | 데이터 스냅샷 또는 이력 보존 |
⚠️ 주의할 점 (부서 소멸 케이스)
부서 테이블에서 데이터를 실제로 DELETE 하시면 안 됩니다.
- Soft Delete 방식: 사용여부(Y/N) 또는 삭제일시 컬럼을 두어 논리적으로만 삭제 처리해야 합니다. 그래야 과거 신청 기록에서 참조하는 외래키(FK) 무결성이 깨지지 않습니다.
요약하자면:
기존 부서 테이블만으로 알 수 없는 정보를 위해 히스토리 테이블을 두는 것은 아주 훌륭한 설계입니다. 오히려 이를 고려하지 않고 현재 부서 정보만 참조하게 설계하면, 나중에 통계를 낼 때 "퇴사자나 사라진 부서"의 데이터가 누락되는 심각한 오류가 발생합니다.
| 질문 |
| 말씀하신 부서의 이력테이블과 신청테이블에 스냅샷 저장을 두가지 방법을 다 DB테이블에 구현 해도되나요? |
네, 두 가지 방법을 동시에 구현하는 것은 실무에서 매우 흔하며, 시스템의 안정성과 편의성을 모두 잡는 전략입니다.
이를 전문 용어로는 **'이력 관리(History Management)'**와 **'역정규화를 통한 스냅샷(Denormalization for Snapshot)'**의 결합이라고 부릅니다. 각각의 역할이 다르기 때문에 중복 투자가 아니라 '상호 보완' 관계에 가깝습니다.
1. 두 방법을 병행했을 때의 역할 분담
A. 신청 테이블의 스냅샷 (조회 최적화)
- 역할: "이 신청서가 작성된 그 순간, 신청자의 소속은 어디였나?"를 즉시 보여줍니다.
- 장점: 복잡한 조인(Join) 없이 신청서 한 장만 읽어도 정보를 알 수 있습니다. 부서명이 바뀌거나 부서 코드가 재사용되어도 신청 당시의 텍스트가 박혀 있어 데이터 불변성이 보장됩니다.
B. 부서 이력 테이블 (추적 및 통계)
- 역할: "A 부서가 2024년에 B 부서와 통합되었고, 2025년에 명칭이 바뀌었다"는 조직의 흐름을 기록합니다.
- 장점: 특정 시점의 전체 조직도를 복구하거나, 부서 변경 이력을 추적하여 인사이트를 도출할 때 필수적입니다.
2. 통합 설계 예시 (ERD 구조)
두 방식을 함께 적용하면 다음과 같은 구조가 됩니다.
테이블 구조 상세
- 부서 테이블 (TB_DEPT)
- DEPT_ID (PK), DEPT_NAME, STATUS (사용/폐지), CREATED_AT
- 부서 이력 테이블 (TB_DEPT_HIST)
- HIST_ID (PK), DEPT_ID (FK), DEPT_NAME, START_DATE, END_DATE
- 부서명이 바뀔 때마다 새 레코드를 쌓음
- 신청 테이블 (TB_REQUEST)
- REQ_ID (PK), USER_ID (FK)
- 스냅샷 컬럼: REQ_DEPT_ID, REQ_DEPT_NAME (신청 시점의 값 복사)
3. 이 방식이 '정규화 위배'가 아닌 이유
데이터베이스 이론에서 정규화는 "현재의 유효한 상태"를 정의할 때 적용됩니다. 하지만 **시간(Time)**이라는 축이 개입하면 이야기가 달라집니다.
- 함수적 종속성 측면: 신청 당시의 부서명은 신청 ID에 종속된 값입니다. 즉, 시간이 지나 부서 테이블의 이름이 바뀌어도 이 신청서의 부서명은 바뀌면 안 되기 때문에, 이 값을 신청 테이블에 두는 것은 논리적으로 타당합니다.
- 성능 측면: 매번 신청서를 조회할 때마다 수만 건의 이력 테이블을 뒤져서 "신청일 기준 유효했던 이름"을 찾는 비용보다, 컬럼 하나에 이름을 저장해두는 비용이 훨씬 저렴합니다.
4. 구현 시 주의사항
- 데이터 일관성: 신청 로직을 짤 때, USER 테이블에서 현재 부서 ID를 가져옴과 동시에 그 시점의 부서명을 반드시 함께 INSERT 하도록 트랜잭션을 묶어야 합니다.
- 용량 관리: 신청 건수가 수백만 건 이상으로 아주 많다면, 모든 텍스트 정보를 저장하는 것이 부담될 수 있습니다. 이럴 때는 핵심 정보(부서 ID)만 남기고 이력 테이블 조인을 활용하는 방식으로 선회하기도 합니다.
결론적으로 두 가지를 모두 사용하시는 것을 추천합니다. 운영 단계에서 "부서가 없어졌는데 옛날 신청서에 부서명이 안 나와요!"라는 민원을 원천 차단할 수 있는 가장 확실한 방법이기 때문입니다.
※ 해당 내용은 Google Gmini3.0에서 작성되었습니다.
'WEB > DB' 카테고리의 다른 글
| DB 이관 도구 및 스크립트 개발 이건 어떤식으로 이루어지나요? (0) | 2026.03.16 |
|---|---|
| DB데이터 이관 수행 절차 (0) | 2026.03.16 |
| 데이터 베이스 정규화(Normalization) (0) | 2026.03.16 |
| 챗 GPT가 알려주는 데이터베이스 이관 (1) | 2024.07.28 |
| 챗GPT가 알려주는 SQL (1) | 2024.07.28 |
- Total
- Today
- Yesterday
- // 사진직: 데이터가 없으면 DEFAULT_IMG 사용 const profileSrc = (d.img && d.img !== "") ? d.img : DEFAULT_IMG;('#user-photo').attr('src'
- 탭메뉴자바스크립트
- 파비콘 #파비콘 사이트에 적용
- 썬크림 #닥터지썬크림 #내돈내산 #내돈내산썬크림 #썬크림추천 #spf50썬크림 #닥터지메디유브이울트라선
- jQuery #jQuery이미지슬라이드 #이미지슬라이드
- 자바스크립트countiue
- 무료폰트 #무료웹폰트 #한수원한돋움 #한수원한울림 #한울림체 #한돋움체
- 좋은책
- sw기술자평균임금 #2025년 sw기술자 평균임금
- lg그램pro #lg그램 #노트북 #노트북추천 #lg노트북
- jdk #jre
- 광주분식 #광주분식맛집 #상추튀김 #상추튀김맛집 #광주상추튀김
- 정보처리기사 #정보처리기사요약 #정보처리기사요점정리
- 쇼팬하우어 #좋은책
- 자바스크립트 #javascript #math
- css미디어쿼리 #미디어쿼리 #mediaquery
- 와이파이증폭기추천 #와이파이설치
- iptime와이파이증폭기 #와이파이증폭기설치
- 자바스크립트break
- ajax
- 테스크탑무선랜카드 #무선랜카드 #아이피타이무선랜카드 #a3000mini #무선랜카드추천
- thymeleaf
- 자바스크립트정규표현식
- 좋은책 #밥프록터 #부의원리
- 바지락칼국수 #월곡동칼국수 #칼국수맛집
- 증폭기 #아이피타임증폭기
- SQL명령어 #SQL
- 연명의료결정제도 #사전연명의료의향서 #사전연명의료의향서등록기관 #광주사전연명의료의향서
- 파비콘사이즈
- echart
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
