테이블(엔티티) 찾아내기
테이블을 찾아내는 일반적인 순서는
요구사항 수집 -> 명사 도출 -> 엔티티 정의
-
요구사항 수집 -> 문서, 워크샵, 사용자 인터뷰 등을 통해 요구사항을 수집
-
명사 도출 -> 요구사항을 수집한 정보와 자료들 중에서 중요한 명사를 찾아내, 이 중에서 엔티티 후보 선별
-
엔티티 정의 -> 각 명사가 실제 엔티티 인지 확인하고, 해당 엔티티마다 필요한 속성을 찾아냄. 기능 하나에 집중에서 엔티티를 찾다보면, 전체적인 관점에서 엔티티를 찾는것보다 훨씬 쉽게 접근 가능
비교 및 분석, 검증
요구사항을 수집하여 나온 명사들과 실제 엔티티 목록을 비교하여 빠진것들이 있는지 살펴볼 것.
- 모든 엔티티 타입에 CRUD가 한 번 이상 표기되었는가?
- 모든 엔티티 타입에 C가 한 번 이상 존재하는가?
- 모든 엔티티 타입에 R이 한 번 이상 존재하는가?
- 모든 단위 프로세스 하나 이상의 엔티티 타입에 표기가 되었는가?
- 두 개 이상의 단위 프로세스가 하나의 엔티티 타입을 생성하는가?
- 이 경우 반드시 잘못되었다기 보다 로직의 검토 대상이 됨
각 엔티티의 속성 찾기
속성은 요구사항 속에 단서가 존재.
고객이 사용하는 문서가 그 예. 이러한 문서를 참고하여 빠진게 있는지 살펴보기.
DB 설계 단계에서 모든 속성을 찾는것은 어려울 수 있으니, 어느정도 타협하는게 개발 비용 면에서 이득.
완벽하게 속성을 찾아내는 것 보다, 엔티티 목록과 관계를 찾아내는 것이 더욱 중요
안전하고 효율적인 구조
정규화 과정을 통해 중복된 데이터를 삭제하는것이 1차적인 목표
정규화
DB 설계시, 중복된 데이터를 제거하고 무결성을 유지하기 위해 테이블의 구조를 개선하는 작업이 정규화.
총 5단계가 있으나, 실무에서는 3차까지 적용됨.
- 1차 정규화
- 하나의 컬럼에 한 종류의 데이터만 사용하는 것이 원칙
- 즉, 한칸에 하나의 데이터가 원칙.
- 관계 중복을 제거하는 과정
- 2차 정규화
- 한개 이상의 컬럼을 엮어야지만 다른 컬럼들을 확정지을 수 있는 것이 복합 키 인데, 복합 키의 일부 컬럼에 의해서 결정되는 컬럼을 별도의 테이블로 나누는 것이 2차 정규화.
- 복합 키의 일부에 의해서 결정되는 컬럼이 한 테이블에 있으면 안된다는 규칙.
- 관계 중복과 데이터 중복을 동시에 제거하는 과정.
- 3차 정규화
- 단역을 별도의 테이블로 분리하는 작업
- 테이블의 주 목적에 맞지 않는 별도의 관계가 테이블 내에 존재할 때, 이 부분을 별도의 테이블로 분리하는 과정
- 하나의 테이블에는 하나의 주종관계만 있어야 한다는 규칙.
설계의 핵심 요소
설계의 각 요소들은 서로를 보완하거나 검증하기도 함. 스케치에서부터 점진적으로 그림을 그려나가듯 반복적인 활동이 필요함.
- 기능 설계
- 개발 범위와 개발 일정을 예측하는 근거 자료.
- 기능 설계 단계의 산출물은 기능 목록이 대표적
- 동적 설계
- 적은 비용으로 요구사항과 아이디어를 검증할 수 있음.
- 동적 설계 단계의 산출물은 상태 다이어그램과 시퀀스 다이어그램 등 이 있음.
- 단, 하나의 도면에 너무 많은 시나리오를 적용하면 이해하는데 방해될 수 있음.
- 구조 설계
- 보다 효율적인 시스템을 구축, 복잡한 문제를 쉽게 접근할 수 있음.
- 구조 설계 단계의 산출물은 ERD, 화면 레이아웃, 클래스 다이어그램 등 이 있음.
Primary key 분류
Primary key는 3가지로 분류할 수 있음
자동 순번 (Auto-Incrementing Key)
-
데이터베이스에서 자동으로 증가하는 순번으로, 주로 숫자 형식
-
간단하고 쉬운 관리: 새로운 레코드가 추가될 때마다 데이터베이스 시스템이 자동으로 값을 할당.
-
중복 위험 없음: 시스템이 자동으로 값을 관리하기 때문에 유일성이 보장.
-
의미 없는 값: 이 키는 단순히 유일성을 보장하기 위한 목적이므로, 비즈니스 로직에서 의미를 가지지 않음.
-
순차적 증가로 인한 보안 이슈: 순차적인 값은 예측이 가능하므로, 보안에 취약.
단일키 (Single Key)
-
하나의 속성 또는 열을 기본 키로 사용하는 것
-
단순성: 하나의 속성만 관리하면 되므로, 복잡성이 적다.
-
쿼리 성능: 하나의 열만 인덱싱하므로, 쿼리 성능이 좋을 수 있다.
-
유일성 확보의 어려움: 하나의 열로 유일성을 확보하기 어려울 수 있다.
-
변경 가능성: 비즈니스 요구사항의 변화로 인해 단일키가 변경될 수 있다.
복합키 (Composite Key)
- 두 개 이상의 속성 또는 열을 결합하여 기본 키로 사용하는 것
- 유일성 확보: 단일키만으로는 유일성을 보장하기 어려운 경우, 여러 열의 조합으로 유일성을 확보할 수 있다.
- 복잡성: 여러 열을 관리해야 하므로, 복잡성이 증가.
- 쿼리 성능: 여러 열에 대한 인덱싱으로 인해 쿼리 성능이 단일키에 비해 떨어질 수 있다.
숫자로 코드를 관리?
장점
- 데이터 일관성 -> 숫자나 상수를 사용하면 데이터의 일관성을 더 잘 유지
- 데이터 크기 절약 -> 문자열보다는 숫자나 상수를 사용하는 것이 데이터베이스 공간을 더 효율적으로 사용
- 빠른 검색 속도 -> 코드를 사용하면 데이터 조회 속도가 일반적으로 더 빠름
- 국제화 용이 -> 상태를 코드로 관리하면 다국어 환경에서의 변환이 쉽다. 예를 들어, '1'을 "배송중", "Shipping", "出荷中" 등으로 쉽게 매핑
단점
- 가독성 저하 -> 코드 자체로는 의미를 바로 알기 어려워, 주석이나 문서가 필요
- 유지보수 비용 문제 -> 상태가 추가되거나 변경될 때마다, 해당 코드를 이해하고 있는 개발자가 수정해야 하므로 유지보수 비용이 발생
문자열로 관리?
장점
단점
- 데이터 일관성 -> 문자열이므로 오타나 다른 문제로 인해 데이터 일관성을 잃을 위험
- 데이터 크기 증가 -> 문자열을 사용하면 데이터베이스에 더 많은 공간이 필요
- 검색 속도 저하 -> 문자열 검색은 일반적으로 코드 검색보다 느림
- 국제화 어려움 -> 다양한 언어로의 변환 어려움
캐시 적립(반정규화)
- 쿼리 성능 향상
- 서비스 로직이 간단해 질 수 있음
- 테이블 사이의 무결성 유지가 어려움
- 데이터가 중복하므로 데이터베이스 공간이 더 필요함
인덱스 작성 시 유의사항
- 선택도(Selectivity): 선택도가 높은 컬럼은 인덱스로 좋은 후보.
- 읽기와 쓰기의 비율: 읽기가 빈번하다면 인덱스 추가가 유리.
- 인덱스의 크기: 컬럼의 크기가 클 경우 인덱스 관리 비용이 증가.
- 복합 인덱스: 컬럼의 순서가 중요. (선택도가 높은 컬럼을 먼저)
- 정렬 순서: 오름차순, 내림차순도 쿼리 성능에 영향을 준다.
- 과도한 인덱스: 쓰기 성능 저하와 디스크 공간 문제가 발생할 수 있다.
- 인덱스 갱신: 데이터 변경 시 인덱스도 갱신되어 성능에 부하가 있을 수 있다.
- 비트맵 인덱스: 낮은 카디널리티 컬럼의 경우 비트맵 인덱스 등의 특별한 인덱스 유형을 고려할 수 있다. (주로 읽기 작업이 많은 OLAP 환경에서 유용)
- 데이터 양: 데이터 양이 적더라도 특정 쿼리 성능이 중요하다면 인덱스를 고려.
- 변경이 많은 필드: 데이터가 자주 변경되면 인덱스 오버헤드가 발생할 수 있다.
- 클러스터링된 인덱스: 변경이 적고 검색이 많은 필드에 대해서는 클러스터링된 인덱스를 고려.
- 배치 작업: 변경이 주로 되며 배치 작업이 많은 테이블의 경우 인덱스를 피할 것. (배치 작업 전후로 인덱스를 재구성하는 전략을 고려할 수 있음)