\(@^0^@)/

[BOOK] 데이터베이스의 기본, ERD와 정규화 과정 본문

BOOKS/면접을 위한 CS 전공지식 노트

[BOOK] 데이터베이스의 기본, ERD와 정규화 과정

minjuuu 2023. 5. 9. 00:44
728x90

데이터베이스의 기본

  • 데이터베이스(DB, DataBase)
    • 일정한 규칙, 혹은 규약을 통해 구조화되어 저장되는 데이터의 모음
    • 데이터베이스 안에 있는 데이터들은 특정 DBMS마다 정의된 쿼리(query) 언어를 통해 삽입, 삭제, 수정, 조회 등을 수행할 수 있다.
    • 실시간 접근과 동시 공유가 가능하다.
  • DBMS(DataBase Management System)
    • 데이터베이스를 제어, 관리하는 통합 시스템

데이터베이스 위에 DBMS가 있고, 그 위에 응용 프로그램이 있다.
ex) MySQL이라는 DBMS가 있고 그 위에 응용 프로그램 Node.js, php

  • 엔터티(entity)
    • 사람, 장소, 물건, 사건, 개념 등 여러 개의 속성을 지닌 명사
    • 서비스의 요구 사항에 맞춰 속성이 정해진다.
    • 약한 엔터티와 강한 엔터티
      • A가 혼자서는 존재하지 못하고 B의 존재 여부에 따라 종속적이라면
        A는 약한 엔터티, B는 강한 엔터티
      • ex) 방은 건물 안에만 존재하기 때문에 약한 엔터티
        건물은 강한 엔터티
  • 릴레이션(relation)
    • 데이터베이스에서 정보를 구분하여 저장하는 기본 단위
    • 엔터티에 관한 데이터를 데이터베이스는 릴레이션 하나에 담아서 관리한다.
    • 관계형 데이터베이스 : '테이블'이라 하고,
      NoSQL 데이터베이스 : '컬렉션'이라 불린다.
    • 테이블과 컬렉션
      • 관계형 데이터베이스(MySQL)
        • 레코드-테이블-데이터베이스로 이루어져 있다.
      • NoSQL 데이터베이스(MongoDB)
        • 도큐먼트-컬렉션-데이터베이스로 이루어져 있다.
  • 속성(attribute) : 릴레이션에서 관리하는 구체적이며 고유한 이름을 갖는 정보
  • 도메인(domain) : 릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합

 

  • 필드와 레코드
    • 필드타입(MySQL 기준)
      • 숫자 타입 : TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
      • 날짜 타입 : DATE, DATETIME, TIMESTAMP
      • 문자 타입 : CHAR, VARCHAR, TEXT, BLOB, ENUM, SET
  • 관계
    • 데이터베이스에 테이블은 하나만 있지 않고,
      여러 개의 테이블이 있고 이러한 테이블은 서로의 관계가 정의되어 있다.
    • 1:1 관계 : ex) 유저당 유저 이메일
    • 1:N 관계 : ex) 한 유저당 여러 개의 상품을 장바구니에 넣는 경우
    • N:M 관계 : ex) 학생과 강의의 관계
  •   : 테이블 간의 관계를 조금 더 명확하게 하고 테이블 자체의 인덱스를 위해 설정된 장치
    • 기본키(Primary Key)
      • PK 또는 프라이머리키
      • 유일성과 최소성을 만족하는 키
      • 자연키 :
        • 중복된 값들을 제외하며 중복되지 않는 속성들을 추출하다가 나온 키
        • 언젠가는 변하는 속성
      • 인조키 : 
        • 인위적으로 생성한 키
        • 자연키와는 대조적으로 변하지 않는다.
        • 보통 기본키는 인조키로 설정
    • 외래키(Foreign Key)
      • FK라고 하며
      • 다른 테이블의 기본키를 그대로 참조하는 값으로 개체와의 관계를 식별하는 데 사용
      • 외래키는 중복되어도 괜찮다.
    • 후보키(candidate key)
      • 기본키가 될 수 있는 후보들이며 유일성과 최소성을 동시에 만족하는 키
    • 대체키(alternate key)
      • 후보키가 두 개 이상일 경우 어느 하나를 기본키로 지정하고 남은 후보키
      • 즉, 후보키 중에서 기본키로 선택되지 못한 키
    • 슈퍼키(super key)
      • 유일성이 있고 그 안에 포함된 후보키는 최소성까지 갖춘 키
      • 각 레코드를 유일하게 식별할 수 있는 유일성을 갖춘 키
      • 유일성 : 중복되는 값은 없으며, 최소성은 필드를 조합하지 않고 최소 필드만 써서 키를 형성할 수 있는 것 

ERD와 정규화 과정

  • ERD(Entity Relationship Diagram)
    • 데이터베이스를 구축할 때 가장 기초적인 뼈대 역할을 한다.
    • 릴레이션 간의 관계들을 정의한 것
    • 서비스를 구축한다면 가장 먼저 신경 써야 할 부분
  • ERD의 중요성
    • 시스템의 요구 사항을 기반으로 작성된다
    • ERD를 기반으로 데이터베이스를 구축한다.
    • 데이터베이스를 구축한 이후에도 디버깅
      또는 비즈니스 프로세스 재설계가 필요한 경우에 설계도 역할을 담당한다.
    • 비정형 데이터를 충분히 표현할 수 없다는 단점이 있다.
      • 비정형 데이터 : 비구조화 데이터, 미리 정의된 데이터 모델이 없거나 미리 정의된 방식으로 정리되지 않은 정보를 말한다.
  • 정규화과정
    • 릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나서 이를 해결하거나,
      저장 공간을 효율적으로 사용하기 위해 릴레이션을 여러 개로 분리하는 과정
    • 데이터베이스 이상 현상 : 회원이 한 개의 등급을 가져야 하는데 세 개의 등급을 갖거나 삭제할 때 필요한 데이터가 같이 삭제되고, 데이터를 삽입해야 하는데 하나의 필드 값이 NULL이 되면 안 되어서 삽입하기 어려운 현상
  • 정규형 원칙
    • 같은 의미를 표현하는 릴레이션이지만
    • 좀 더 좋은 구조로 만들어야 한다.
    • 자료의 중복성은 감소해야 한다.
    • 독립적인 관계는 별개의 릴레이션으로 표현해야 한다.
    • 각각의 릴레이션은 독립적인 표현이 가능해야 한다.
  • 제1 정규형
    • 모든 도메인이 더 이상 분해될 수 없는 원자 값만으로 구성되어야 한다.
    • 한 개의 기본키에 대해 두 개 이상의 값을 가지는 반복 집합이 있어서는 안 된다.
    • 반복 집합이 있다면 제거해야 한다.
  • 제2 정규형
    • 부분 함수의 종속성을 제거한 형태
    • 부분 함수의 종속성 제거 : 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속적인 것
    • 동등한 릴레이션으로 분해해야 한다.
    • 정보 손실이 발생하지 않는 무손실 분해로 분해되어야 한다.
  • 제3 정규형
    • 기본키가 아닌 모든 속성이 이행적 함수 종속(transitive FD)을 만족하지 않는 상태
    • 이행적 함수 종속 : A -> B와 B -> C가 존재하면 논리적으로 A -> C가 성립하는데,
      이때 집합 C가 집합 A에 이행적으로 함수 종속이 되었다고 한다.
  • 보이스/코드 정규형
    • 결정자가 후보키가 아닌 함수 종속 관계를 제거하여 릴레이션의 함수 종속 관계에서 모든 결정자가 후보키인 상태
    • 결정자 : 함수 종속 관계에서 특정 종속자를 결정짓는 요소, 'X' -> 'Y'일 때는 X는 결정자, Y는 종속자이다.

데이터베이스는 조금 더 친숙한 느낌이 있는데, 정규화 과정과 정규형은 정말 낯설다..

코딩 처음 배울 때, (물론 제대로 설계하진 못 했겠지만) 한 번 정도 팀원들과 같이 설계한 경험이 있다.
그 후 프런트엔드로 목표를 확실히 하고 백엔드와 협업할 땐 ERD를 백엔드 개발자들끼리 설계를 했던 기억이다.

그래서 그 후에는 ERD 관련해서 설계할 기회가 없고 생각도 하지 않고 있었는데, 올초 팀플 할 때 ERD 관련해서 백엔드와 다툼이 발생했었다.

백엔드 개발자 분이 같이 ERD를 작성하자 했고 vs 프런트 개발자분은 그건 백엔드의 영역이라고 하셨다.
꽤 오랜 시간 의견이 대립되었고, 결국 백엔드 개발자 분이 팀을 나가시게 되었다..

많은 팀플 경험과 현업 경험이 없는 나로서는 어느 것이 맞는 건지 판단을 내리기 어려웠고,
(다른 팀원 분들도 대부분 무경력) 지금도 확신은 없지만, 나는 처음부터 같이 설계해 보는 것이 좋다는 의견이다.
백엔드 개발자 분이 나가시기 전에 같이 약간의 ERD를 설계했었는데 (제대로 한건진 모르겠지만)
팀 회의했던 부분에서 생각나지 않던 부분들도 생각나서 추가하고, api를 어떤 식으로 넘겨받을지 등 같이 고민했었다.
서비스를 같이 만드는 입장에서라도 같이 생각하고 토론해서 설계하는 것이 좋은 것 같다는 입장이다 ㅎ.ㅎ

그렇지 않으면 가끔 백엔드에서 프런트엔드에 외주 준 것 같은 묘한 기분이 들었던 경험도 있어서..
중간에 합류하면 모르겠지만, 초기 서비스부터 만드는 플젝에 참여했다면 설계도 모두가 해야 하지 않을까~? 싶다

그러고 보니 어쩌다가 이런 글을 작성했지?😮

 

정규형 과정을 거쳐 테이블을 나눈다고 해서 성능이 100% 좋아지는 것은 아니라고 한다.
성능이 좋아질 수도 나빠질 수도 있다.
테이블을 나누게 되면 어떠한 쿼리는 조인을 해야 하는 경우도 발생해서 오히려 느려질 수도 있기 때문에
서비스에 따라 정규화 또는 비정규화 과정을 진행해야 한다!


출처 : 면접을 위한 CS 전공지식 노트

728x90