포시코딩

DB 모델링, ERD, 인덱스 본문

MySQL

DB 모델링, ERD, 인덱스

포시 2023. 1. 25. 11:08
728x90

ERD

(Entity Relationship Diagram)

개체 관계 다이어그램

 

엔티티 (Entity)

개념적으로 혹은 실제로 존재하는 개체

고유해야한다.

예시

리스트: 연구직, 생산직, 판매직, ...

개념별: 프로젝트, 스토리, 태스크, ...

 

애트리뷰트 (Attribute)

엔티티의 구성 요소

예시

프로젝트를 구성하는 요소

  • 프로젝트 번호
  • 프로젝트 이름
  • 프로젝트 시작일
  • 프로젝트 종료일
  • 프로젝트 목표
  • 최종 책임자

프로젝트 단가 테이블

  • 프로젝트 번호(FK. 위 프로젝트 테이블에서)
  • 계약금 금액
  • 계약금 납입일자
  • 중도금 금액
  • 중도금 납입일자
  • 잔금 금액
  • 잔금 납입일자

 

릴레이션 (Relation)

엔티티와 엔티티의 관계를 나타내는 것. 보통 카디널리티 비율로 표기한다.

카디널리티 비율: 1:1, 1:N, M:N 관계가 있다.

 

1:N

유저 엔티티와 게시글 엔티티

유저 한명에 대해 게시글이 여러개 작성될 수 있지만

한 게시글에 대해 여러 유저가 작성자가 될 수 없다.

 

M:N

자동차 종류 엔티티와 색깔 엔티티

한 종류의 자동차에 대해 여러 종류의 색깔이 칠해질 수 있고

한 색깔에 대해 여러 종류의 자동차가 칠해질 수 있다.

 

join을 강제적으로 해줘야되는 상황에서 다대다 관계가 사용된다.

 

 

데이터베이스 모델링 시 기본 원칙

  • 업무에서 필요로 하는 모든 데이터가 모델에 정의되어 있어야한다.
  • 두 개의 엔티티가 비슷한 애트리뷰트로 구성되어 있으면 하나의 엔티티로 통합
  • 애트리뷰트는 누구라도 알 수 있게 작성
  • 애트리뷰트의 이름은 너무 길게 작성하지 않는다.
  • 애트리뷰트가 여러 개의 값을 가지게 되면 엔트리로 바꾸는 것이 나을 수 있다.
  • 엔티티, 애트리뷰트는 명사이고 관계는 동사이다.
  • Data Redundancy 이슈가 발생하지 않아야 한다.
    • Data Redundancy: 데이터가 중복되는 것
    • 데이터가 중복 저장되면 저장 공간이 그만큼 쓸데없이 사용되며 일관성을 유지하기 위해
      필요없는 유지보수 작업을 지속적으로 해야할 수 있다.

 

인덱스

데이터베이스의 본질 중 하나는 빠르게 원하는 데이터를 탐색하여 가지고 오기 위함이고

이것을 위해서는 인덱스의 역할이 필수적이다.

보통 PK, FK와 같은 키들을 통해 인덱스라는 것을 간접적으로 경험해보았을 것이다.

 

인덱스란 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이며 

인덱스를 저장하기 위한 추가적인 공간이 필요하다.

테이블의 모든 데이터를 검색(풀스캔)하면 시간이 오래 걸리기 때문에

데이터 + 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있다.

 

인덱스를 구현할 수 있는 자료구조는 크게 2가지가 있다.

  • B-트리: 일반 트리에 비해 검색 속도가 O(logN)으로 빠르다.
  • 해시 테이블: 검색 속도는 O(1)이지만 같은 해시값에 대해 더 늘어날 수 있다.
    해시 함수 수행 시간이 곧 검색 속도

하지만 실제로는 인덱스를 구현할 때 해시 테이블을 사용하지 않고 B-트리를 많이 사용한다.

 

이유 ->

해시테이블은 어떤것을 딱 지정했을 때는 속도가 빠를 수 있지만

B-트리는 범용적으로 레인지 검색도 무리가 없기 때문. 속도도 해시 테이블보단 느릴지언정 안빠르다는것도 아니니까

검색할 때 id = 1 인것만 가져오지 않으므로 

 

인덱스의 종류는 다음 두가지가 있다.

  • Clustered Index
    • 클러스터형 인덱스는 정렬된 데이터 row들을 탐색 키 값으로 가진다.
      테이블당 클러스터형 인덱스는 하나만 있을 수 있다. (보통 PK)
    • 인덱스의 포인터는 row를 가리키는 것이 아닌 row가 저장된 데이터 블록을 가리킨다.
    • 정렬이 되어 있다는 전제조건이 있기 때문에 검색 시 성능이 매우 빠르다.
    • 하지만, 전제조건을 지키기 위해 삽입, 수정, 삭제를 할 때는 성능이 살짝 아쉬울 수 있음
      ex) 정렬된 배열에서의 새 원소 삽입, 기존 원소 삭제를 생각
    • 빈 테이블이 아니라 기존에 레코드가 많이 보유된 테이블에 클러스터형 인덱스를 새로 생성하게 되면
      데이터 페이지를 전부 다시 정렬해야 하므로 부하가 매우 커질 수 있어서
      시작할 때 생성하거나 점검시간 때 생성해야 한다.
  • Non-Clustered Index
    • 비클러스터형 인덱스는 정렬되지 않은 데이터 row들을 탐색 키 값으로 가진다.
      비클러스터형 인덱스는 비클러스터형 인덱스 키 값이 있으며
      각 키 값 항목에는 해당 키 값이 포함된 데이터 row에 대한 포인터가 있다.
    • 비클러스터형 인덱스가 생성되면 별도의 페이지에서 인덱스를 구성하기 때문에 추가적인 용량이 필요하다.
    • 클러스터형 인덱스에 비해 검색은 느리지만 삽입, 수정, 삭제는 빠르다.
      ex) 링크드리스트가 배열에 비해 어떤 장점이 있는지 생각

 

추가 질문

실제로 데이터베이스는 대부분 R 빈도 >>> CUD 빈도이다.

당연히 검색 성능은 데이터베이스에서 가장 중요한 이슈이므로 항상 검색 기능을 신경써야 하는데, 

인덱스를 무조건 쓰면 검색 성능이 좋아질까?

인덱스를 써도 쓰지 않는 것과 별반 차이가 나지 않는 경우가 있는데 

테이블의 레코드가 어떻게 구성되면 이런 경우가 발생할까?

 

  1. R(검색) 빈도가 낮고 나머지 CUD의 빈도가 높은 테이블의 경우 ex) 채팅
  2. 레코드 자체가 많지 않아서 인덱스를 걸지 않아도 되는 경우
  3. (정답) 예시로 헬스장에서 회원 명부 관리 시에 성별 인덱스를 건다면 어떻게 될까?
    검색하면 찾을 수는 있겠지만 인덱스가 엄청 많을 것이다. 
    왜냐면 인덱스가 회원번호id로 생각했을 때 남녀로 밖에 구분이 되지 않아 찾는데 오래 걸릴 것이기 때문
    이러한 컬럼에 인덱스를 걸면 인덱스 성능이 나오지 않는다. 
    이런걸 셀렉티비티가 낮다고 한다. 더 자세한건 아래 링크 참고

 

이어서 참고하면 좋은 자료

https://soft.plusblog.co.kr/87

 

Cardinality vs Selectivity (카디널리티와 선택도의 차이)

데이터를 다루는 DB나 빅데이터 분야에서 ‘카디널리티(Cardinality)’와 ‘선택도(Selectivity)’는 자주 언급되는 용어다. 이 용어의 차이점을 잘 알고 있어야 데이터의 특성을 잘 파악할 수 있다. 카

soft.plusblog.co.kr

https://www.youtube.com/watch?v=iNvYsGKelYs 

728x90