Chapter 1. Database 설계

김지민·2024년 10월 2일

UMC springboot

목록 보기
1/9

UMC springboot 파트에 들어가면서 관련한 스터디가 시작됐다. 이에 관한 내용을 간략히 정리하면서 남겨보려고 한다! 첫번째 내용은 백엔드 서버의 핵심인 데이터베이스와 관련된 내용이다. 데이터베이스를 효율적으로 설계하고 서버와 연결하는 것이 백엔드의 핵심이기 때문에 꼼꼼히 살펴보도록 하자.


1. 주제

  • SQL과 NoSQL에 대해 이해
  • 데이터베이스 설계 방법 학습
  • local DB 연결

2. SQL과 NoSQL

먼저 데이터베이스를 만드는 데 가장 기본이 되는 데이터베이스 언어에 대해 살펴봅시다. 언어는 크게 SQL과 NOSQL이 있는데, SQL은 Stands for Structured Query의 약자로 주로 관계형 데이터 베이스에 이용이 되고 NoSQL은 Not Only SQL의 약자로 SQL이 아닌 나머지를 의미합니다. 더 자세히 살펴봅시다.

  • SQL: 관계형 데이터베이스를 사용하는 시스템(RDBMS)에서 데이터를 관리하는 데 사용되는 언어 <- 주로 사용!!
    • 입출력 속도보다는 정확도와 입출력이 중요할 때 적합(데이터를 메모리 중심이 아닌, 테이블 구조로 저장하기 때문에 디스크 I/O 작업이 많아지는 데 영향)
    • 데이터가 일관되고 테이블 간의 관계가 잘 정의된 구조화된 데이터에 좋음
    • 관계를 맺고 있는 데이터가 자주 변경되는 경우 좋음
      • NoSQL에서는 관계를 맺고 있는 컬렉션들을 모두 수정해야 하기 때문에 비효율적
    • 우리가 주로 사용하는 MySQL, PostgreSQL ...이 모두 포함
  • NoSQL = Not Only SQL의 약자로 SQL이 아닌 나머지
    • key-value, document, graph 등 다양한 데이터 구조를 지원
    • 데이터가 미리 정의된 스키마를 따르지 않고 데이터 요소 간의 관계가 잘 정의되어 있지 않은 반정형 또는 비정형 데이터에 적합
    • 막대한 양의 데이터를 다뤄야 하는 경우 적합
    • MongoDB, Redis 등 존재
    보편적으로 SQL을 사용하므로, 이를 사용해 앞으로의 내용을 다뤄보자.

3. 데이터베이스 설계 - ERD

프로젝트 개발 시작과 동시에 설계하는 게 좋음.
- 기획과 디자인이 어느 정도 나와 기능이 정해지면, DB를 먼저 설계하고 코드 작업에 들어가야 합니다.
모든 서버 팀원이 인지하는 DB는 동일해야 함.
- 자기 마음대로 DB를 설계하고, 작업 후 나중에 합치는 행위는 혼동을 일으키고 비효율적인 중복 작업을 만들어낼 수 있으므로 자제해야합니다!! 😐

그렇다면, 데이터베이스 설계의 결과물인 ERD에 대해 더 살펴봅시다.

ERD(Entity-Relationship Diagram)란?

  • 데이터베이스에서 엔티티와 관계를 시각적으로 표현한 다이어그램
    • 엔티티란 뭐냐면... => 즉, 데이터베이스 테이블 간의 관계를 표현한 다이어그램이라고 생각하면 이해하기 쉽습니다!
      • 저장할 가치가 있는 데이터 객체
      • 현실 세계의 사물이나 개념 표현한 것
      • 데이터베이스 내에서 테이블로 표현
      • 독립적으로 존재
      • 여러 속성이 있음
      • 기본키를 통해 고유하게 식별 가능
  • 테이블, 속성, 관계를 그림으로 표현하여 데이터 모델을 설계할 때 사용
  • 저는 dbdigram로 그리는 게 제일 편했는데, 주로 ERDcloud를 통해 다같이 작업하는 편입니다.

+참고. sql 문법에 대한 기본 지식

  • 외래키
    • FK(Foreign Key)
    • 다른 테이블의 기본 키를 참조하는 키
    • 두 테이블 간의 연관 관계를 정의하며, 데이터의 일관성을 유지하는 데 사용
  • 기본키
    • PK(Primary Key)
    • 테이블에서 각 행을 유일하게 식별할 수 있는 키
    • 하나의 테이블에는 하나의!! 기본키만!! 존재
    • 중복 X, NULL X
    • 기본키가 존재하지 않을 수도 있기는 한데, 권장되지는 않음
    • 정의하는 방법
      • 기본 키 정의 방법 (SQL): 기본 키는 테이블을 생성할 때 PRIMARY KEY 제약 조건을 사용하여 정의할 수 있습니다.
      1. 단일 컬럼을 기본 키로 정의:
        CREATE TABLE Students (
            student_id INT PRIMARY KEY,  -- student_id가 기본 키로 정의됨
            name VARCHAR(100),
            age INT
        );
      • 이 경우, student_id는 기본 키로 설정되었고, 중복되거나 NULL 값을 가질 수 없게 됩니다.
    1. 복합 키(두 개 이상의 컬럼을 묶어 기본 키로 정의):
      CREATE TABLE Enrollment (
          student_id INT,
          course_id INT,
          enrollment_date DATE,
          PRIMARY KEY (student_id, course_id)  -- student_id와 course_id가 복합 기본 키로 정의됨
      );
    • 이미 존재하는 테이블에 기본 키 추가:
      : 테이블이 이미 만들어진 경우, 기본 키를 추가하려면 ALTER TABLE을 사용
      ALTER TABLE Students
      ADD PRIMARY KEY (student_id);
    • AUTO_INCREMENT 의 사용
      - PRIMARY KEY의 속성 중 하나
      - 삽입되는 레코드에 유니크한 값을 자동적으로 부여
      - 일반적으로 1부터 증가하며 값을 부여하지만, 별도의 다른 값을 부여할 수도 있음
      CREATE TABLE user {
           id int PRIMARY KEY AUTO_INCREMENT
                  }

자 이제 ERD를 작성하는 방법에 대해 더 자세히 살펴보도록 하자.

3-2. ERD 작성의 기본 규칙

  • 테이블 이름과 칼럼 이름은 모두 소문자, 단어 구분은 대소문자가 아닌 밑줄로 구분해줘야 함
    • SQL 표준에서 테이블 이름과 칼럼 이름의 대소문자를 구분하지 않는 것으로 처리하기 때문
  • 기본 키를 위해 index를 따로 두는 것이 편함.
  • 각 index를 위한 id를 book_id, member_id가 아닌, 그냥 id로 이름을 짓는 것이 좋음
  • 기본 키 타입은 int가 아닌 추후 서비스 확장을 고려해서 bigint로

기본 entity #1

MySQL에서 varchar(20)는 최대 20글자인데, 유니코드 기준 20글자니, 한글 20글자로 생각

  • varchar로 두는 경우는, enum으로 관리하는 경우 (ex. gender: man, woman)
  • created_at, 그리고 updated_at을 테이블마다 추가해주는 것이 좋음 - 최신순 정렬 등의 목적
    • Datetime VS Timestamp
      • datetime(6)에서 (6)은 밀리초 소수점 6자리까지 구분한다는 의미 - 밀리초 소수점까지 고려하지 않으면, 최신순 정렬이 어려울 수 있음
      • Timestamp 타입의 값은 현재 시각 → UTC 시각으로 변환되며 Datetime은 변환되지 않음. => Timestamp이 더 호환성 좋음!

기본 entity #2: member entity

  • member 테이블은 status와 inactive_date를 두는 것이 좋음
    => soft delete를 위함 (꼭 member가 아니어도 다양한 곳에 적용 가능)
    • Hard delete: 회원 탈퇴, 게시글 삭제 등의 연산을 HTTP Method 중 Delete로 바로 삭제를 해 버리는 방법 => No!
      • 문제가 발생할 수 있음. ex) 회원 탈퇴를 철회하고 다시 돌아오는 회원들이 존재하는 경우처럼 복구하기 어려움
    • Soft delete: 비활성 상태로 두고, 일정 기간동안 비활성인 경우 자동 삭제가 되도록 설계
      • status가 inactivate된 지 얼마 뒤에(inactivate_date로 count), batch 사용해서 삭제
        • batch: 정해진 시간에 자동으로 실행되는 프로세스로, 대개 하루가 끝날 때나 야간과 같이 컴퓨팅 리소스 사용량이 적은 시간에 task를 batch로 처리, batch는 HTTP Method 중 Patch - 레코드 자체를 삭제하는 것이 아니라, 레코드의 특정 필드(ex: is_deleted, deleted_at 등)만 업데이트하는 것이기 때문

3-3. 연관 관계

ERD에서 Entity 하나하나를 설계하는 것도 중요하지만, 이들간의 관계를 연결하는 것도 매우 중요합니다! 이에 대해 자세히 살펴봅시다.

  • 1:N의 경우, N 쪽이 외래키를 가짐

  • N:M의 경우
    양쪽에 대해 서로 a가 b 여러 개 적용 가능, b가 a 여러 개 적용 가능이면, N:M 관계
    가운데 매핑 테이블이 양쪽의 기본키(PK)를 외래키(FK)로 가지고 각각 1:N의 관계를 가짐

  • 알림과 같이, 알림 중에서 여러 type이 구분되는 경우를 연관관계를 활용해 다양하게 설계 가능!
    1. 슈퍼타입과 서브타입의 구성

    • 슈퍼 타입: 알림(alarm)
      공통적으로 모든 알림이 가져야 할 속성들을 정의 ⇒ 공통적인 알림의 동작과 속성들을 관리
      : 알림 ID, 제목, 내용,생성 시간,읽음 여부, 등등...
    • 서브 타입 ⇒ 각각의 알림 타입에 특화된 정보를 관리
      - 공지 알림(notice): 공지 사항과 관련된 알림.
      - 추가적으로 "공지사항 ID" 같은 공지 사항으로 이동할 때 필요한 정보를 포함.
      - 마케팅 알림(marketing): 마케팅과 관련된 알림.
      - 추가적으로 "마케팅 ID" 같은 마케팅 관련 정보를 포함.
      2. 하나의 테이블을 두고 dtype으로 구분

    3. 그냥 각각 테이블 다 나누기: 각 type마다 다른 알람 entity를 만드는 방법


4. local DB 접속해서 DB 설계하기

다음으로는, 실제로 local DB에 접속해서 설계한 ERD를 바탕으로 데이터베이스를 만들어보겠습니다.

intelliJ로도 접속할 수 있는 방법이 있어서 그 방법을 소개하겠습니다!
1. Intellij에 접속해서 DataBase로 들어가기

2. Data Source에서 MySQL을 클릭

3. mysql에 하는 것처럼 Host, User, Password에 알맞은 값을 넣고 Test Connection을 눌러서 Succeeded가 나오면 성공


오늘은 백엔드 서버의 핵심이 DB 설계와 ERD에 대해 배워봤는데요. 다음 시간에는 실제로 어떻게 SQL문을 작성해야하는지 알아봅시다!😊

profile
열혈개발자~!!

0개의 댓글