[DB] 데이터 모델링

데이터모델링

1. 데이터모델링 프로세스

  • 업무파악 → 개념적 데이터모델링 → 논리적 데이터모델링 → 물리적 데이터모델링

2. 업무파악

  • 서비스의 UI를 그려보는 것으로 고객과 같이 요구사항을 이해하고 개념을 파악할 수 있다. (ovenapp.io 등 툴 협의할 때 사용 추천)

3. 개념적 데이터모델링

  • 업무에 어떤 개념들이 있고 이들이 어떤 상호 작용을 하는지 찾아내는 단계. ER다이어그램을 사용한다. 모든 모델링 단계 중 가장 중요하다.(이후 단계는 기계적으로 해결 가능)
    1. ERD : 현실에서 개념을 추출하는 필터를 제공해주고 개념에 대해서 다른 사람과 대화하게 해주는 언어의 역할을 한다. [정보]와 정보들의 모임인 [그룹] 간의 [관계]로 표현한다. (draw.io 서비스 사용 추천)
      1. Identifier(식별자) : Attribute 중 데이터를 식별할 수 있는 속성
      2. Candidate key(후보키) : Primary Key가 될 수 있는 후보 속성들을 말한다.
      3. Primary Key(기본키) : 식별키로 선정된 속성
      4. Alternate Key : 후보키중 기본키를 제외한 속성들 (나중에 추가 인덱스 생성 유력 후보)
      5. Composite Key(중복키) : 둘 이상의 속성을 합쳐서 키로 사용하는 것
      6. Relation : 두 개체 사이의 행위를 표현
      7. Cardinality : 1:1관계, 1:N 관계, N:M(실제 테이블로는 표현할 수 없어 중간 테이블을 두고 1:N관계로 변형한다)
      8. Optionality : 한 개체에게 다른 개체는 optional한가 (가질 수도 있고 안 가질 수도 있음). 필수로 있어야 하는가(Mandatory) 에 따라 각각 ERD에서 원과 선으로 표현한다.

4. 논리적 데이터모델링

  • RDBMS에서 사용할 수 있는 이상적인 형태의 테이블명과 필드명, 관계등으로 표현하는 단계
    1. Mapping Rule : ERD에서 만든 모델을 RDBMS에 맞는 형식으로 변환할 때 사용할 수 있는 방법론.
      1. Entity → Table, Attribute → Column, Realation → PK, FK
      2. 1:N의 경우 1에 PK, N에 FK 설정하면 된다. 1:1이 헷갈릴 수 있는데 [사용자]와 [휴면사용자]의 사이라면 [사용자]가 부모 테이블이 될 것이다.(사용자의 데이터 중 일부로 구성되는 테이블이기 때문) 이런 때에는 부모 테이블에 PK, 자식 테이블에 FK를 설정하면 된다
      3. N:M 관계의 처리 : 양쪽 다 관계 표현을 위해 컬럼을 추가 해보면 한 레코드에 둘 이상의 값이 들어가야 해서 표현이 불가능하다는 것을 알 수 있다. 따라서 Mapping Table을 만들어 둘 사이의 관계를 표현한다.
    2. 정규화 : 정제되지 않은 표를 관계형 데이터베이스에 어울리는 테이블로 만드는 방법
      1. 제1정규화 : 모든 컬럼이 원자적이어야 한다.(컬럼은 1가지 값만 가져야 한다) 두가지 이상 값을 가지거나 나머지 컬럼의 값을 중복하게 만든다면 제1정규화를 통해 별도 테이블로 분리 해야 한다.
      2. 제2정규화 : 부분 종속성이 없어야 한다. 일부 컬럼이 Composite key중 일부 키에만 종속하고 있다면 일부 행이 중복이 발생할 수 있다. 따라서 제2정규화를 적용해야 한다. 부분 종속 관계에 있는 key 컬럼과 나머지 컬럼들을 별도의 테이블로 분리한다. 그렇게 하면 중복행이 정리가 되어 삭제될 수 있다.
      3. 제3정규화 : no transitive dependencies(이행적 종속성). 키가 아닌 컬럼에 종속된 컬럼들이 있을 경우 이행적 종속성이 있다고 하고 별도의 테이블로 분리한다. 보통 컬럼명에 aa_id, aa_name 등 접미사 등으로 비슷한 성격의 컬럼인 것이 보일 때가 있는데 이 때 제3정규화를 고려 하는 것도 팁이다.

5. 물리적 데이터모델링

  • 실제 사용할 DBMS에 맞는 최적화된 스키마를 고려하고 그를 생성할 수 있는 쿼리를 작성하는 단계
    1. 일단 논리적 모델을 가지고 데이터 스키마를 생성하고 테스트 해보기
    2. 느린 쿼리를 찾고 index를 만들어 보고, app단에서 캐싱을 고려해보기도 한다.
    3. 최후의 보루로 역정규화를 고려한다.
      1. 정규화가 적용된 테이블은 많은 join 연산을 필연적으로 가지게 되는데 read 성능에서 안좋은 영향을 끼치기도 한다.
      2. join을 없애기. 데이터 중복성을 포기하고 테이블을 합쳐서 join 연산을 필요없게 만드는 방법이 있다.
      3. 파생컬럼(count 값 등)을 추가하고 평상시 유지해서 매번 집계 연산에 드는 비용과 연산 시간을 줄이는 방법.
      4. FK를 일부러 추가해서 join을 단순화 하는 방법