프로젝트 작업일지 : DB 테이블 설계, ERD 작성

작업일지에 들어가며

프로젝트에 돌입한지 3일차가 되었다.

 

우리는 구현할 기능에 맞는 DB 테이블 설계나누고 취합하여 더 좋은 방향을 논의하기로 하였다.

 

나는 메인 페이지와 필터에 필요한 DB 테이블 설계를 맡게 되었다.

 

ERD 작성은 그래도 이전 프로젝트에서 한번은 경험은 해보았지만 테이블 구조가 단순하여 그래도 쉽게 작성했다고 생각했는데, 이번에는 상대적으로 복잡한 테이블 구조를 가질 것 같아서 잘 해낼 수 있을 지 걱정이다.

 

걱정을 제쳐두고 이번 프로젝트의 테이블 설계와 ERD 작성 과정을 기록해보겠다. 


테이블 설계

우선 나는 메인과 필터 테이블 설계를 맡게되엇다. 메인페이지 화면을 나누어 보게 된다면 위치, 필터, 카테고리, 배너 부분과 주변 맛집 추천(음식점) 부분으로 나누고 설계를 진행하였다.

1. 위치 테이블

기본적으로 PK로 설정할 아이디와 이름, 주소, 위도와 경도 정도만 있으면 될 것 같았다.

2. 필터 테이블

고민을 해야할 것이 필터 테이블 하나를 두고 그 안에 타입(정렬, 테마, 서비스)과 이름(타입별 이름, 정렬의 경우 별점순, 리뷰순, ...) , 설명 등을 넣을 것인지 아니면 세분화하여 필터 타입별로 테이블을 따로 둘 지 생각해봐야했다.

 

필터 테이블을 한 곳에서 통합하여 관리하게 된다면, 장점으로는 필터 타입으로 데이터를 관리하므로 DB 구조가 간단해지고 쿼리가 단순해질것이고, 단점으로는 필터 타입이 늘어나면 관리가 어려워지고 각 타입별로 고유한 필드가 필요한 경우 확장성이 부족해진다.

 

세분화한다면 장점으로 각 필터 타입의 고유한 정보를 개별 테이블에서 관리가 가능해져 확장성이 상승한다. 단점으로는 쿼리가 복잡해지고 테이블 간 조인을 해야한다는 점이다.

 

팀장님과 논의한 경과 필터를 세분화하는 것이 이후 시스템 확장 시 유리하다고 판단하여 세분화하는 방향으로 진행하였다.

 

그래서 필터 타입을 3분류로 나누어 테이블을 생성하기로 하였다.

 

정렬순, 테마별, 서비스별로 나누어 각각 PK로 사용할 아이디와 타입 이름, 설명을 DB 내에 저장하면 될 것 같다.

3. 카테고리 테이블

카테고리도 마찬가지로 아이디와 카테고리명, 설명정도만 있으면 되지 않나 싶다.

4. 배너 테이블

배너 아이디와 타이틀, 설명, 이미지, 배너 게시 시작일, 종료일을 생각해보았다.

5. 음식점 테이블

마지막으로 추천 맛집의 경우 아무래도 여러 카테고리나 테마에 해당할 수도 있는 것을 고려해봤을 때 다른 테이블과 연관된 부분이 많을 것 같아서 필터를 설계했을 때와 마찬가지로 테이블을 세분화하여 설계하기로 하였다.

 

크게 음식점 테이블의 필드로는 음식점마다 고유의 아이디를 주고, 식당 이름, 주소, 설명, 평점, 이미지 정도 넣어주고 이렇게 하위 관계 테이블을 따로 두어 관리하면 될 것 같았다.

  • 음식점-카테고리
  • 음식점-테마
  • 음식점-서비스
  • 음식점-위치
  • 음식점-리뷰

이로써 내가 맡은 부분의 테이블 설계가 마무리되었다.

다른 팀원들의 테이블을 취합한 후 회의를 통해 ERD 작성을 마무리하면 되겠다.

6. 쿼리문

(지피티의 도움을 받아 작성!)

메인

-- 위치 테이블
CREATE TABLE locations (
    location_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    address VARCHAR(255) NOT NULL,
    latitude DECIMAL(10, 8),
    longitude DECIMAL(11, 8)
);

-- 카테고리 테이블
CREATE TABLE categories (
    category_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    FOREIGN KEY (parent_category_id) REFERENCES categories(category_id)
);

-- 배너 테이블
CREATE TABLE banners (
    banner_id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    image VARCHAR(255) NOT NULL,
    start_date DATE,
    end_date DATE
);

-- 음식점 테이블
CREATE TABLE restaurants (
    restaurant_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    address VARCHAR(255) NOT NULL,
    description TEXT,
    rating DECIMAL(3, 2),
    image VARCHAR(255)
);

-- 음식점-카테고리 관계 테이블
CREATE TABLE restaurant_category (
    id INT AUTO_INCREMENT PRIMARY KEY,
    restaurant_id INT NOT NULL,
    category_id INT NOT NULL,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id),
    FOREIGN KEY (category_id) REFERENCES categories(category_id)
);

-- 음식점-테마 관계 테이블
CREATE TABLE restaurant_theme (
    id INT AUTO_INCREMENT PRIMARY KEY,
    restaurant_id INT NOT NULL,
    theme_id INT NOT NULL,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id),
    FOREIGN KEY (theme_id) REFERENCES themes(theme_id)
);

-- 음식점-서비스 관계 테이블
CREATE TABLE restaurant_service (
    id INT AUTO_INCREMENT PRIMARY KEY,
    restaurant_id INT NOT NULL,
    service_id INT NOT NULL,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id),
    FOREIGN KEY (service_id) REFERENCES services(service_id)
);

-- 음식점-위치 관계 테이블
CREATE TABLE restaurant_location (
    id INT AUTO_INCREMENT PRIMARY KEY,
    restaurant_id INT NOT NULL,
    location_id INT NOT NULL,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id),
    FOREIGN KEY (location_id) REFERENCES locations(location_id)
);

-- 음식점-리뷰 관계 테이블
CREATE TABLE restaurant_review (
    id INT AUTO_INCREMENT PRIMARY KEY,
    restaurant_id INT NOT NULL,
    review_id INT NOT NULL,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(restaurant_id)
    -- 리뷰 테이블의 review_id에 대한 FOREIGN KEY 추가 필요
);

필터

-- 정렬 테이블
CREATE TABLE sorts (
    sort_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL, -- 정렬 기준 이름
    description TEXT
);

-- 테마 테이블
CREATE TABLE themes (
    theme_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT
);

-- 서비스 테이블
CREATE TABLE services (
    service_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT
);

7. 전체 DB 테이블 구상안

프로젝트 DB 테이블 구상안

- 회원 (점주 구분하여 별도의 테이블 추가 여부)
- 위치(지역) : 위도, 경도
- 카테고리 (음식)
- 배너 (이미지) : url
- 음식점 : 별점, 이미지(배너 테이블 참조 여부 결정), 리뷰
* 하위 테이블은 상위 테이블과 연관관계만 정의하는 중재 역할
    - 카테고리
    - 서비스 (상세 메뉴)
    - 테마 (분위기 : 반영 여부 결정)
    - 위치
    - 리뷰

* 필터 테이블에서 참조 여부 결정
    - 정렬 (정렬 조건 선택 -> 테마, 서비스, 지역 우선순위 선택 등)
    - 테마
    - 서비스

- 리뷰 (별점 리뷰)
    : 회원 - 리뷰 - 식당
- 북마크(좋아요)
    : 회원 - 좋아요 - 식당 / 회원 - 좋아요 - 리뷰 / 회원 - 좋아요 - 댓글
- 댓글 (자유 댓글)
    : 좋아요(FK), 대댓글 여부(들여쓰기), : 회원 - 댓글 - 음식점

ERD

 

 

💡 ERD란?
Entity Relationship Diagram 개체-관계 모델. 테이블간의 관계를 설명해주는 다이어그램이라고 볼 수 있으며,
이를 통해 프로젝트에서 사용되는 DB의 구조를 한눈에 파악할 수 있다.
즉, API를 효율적으로 뽑아내기 위한 모델 구조도라고 생각하면 된다.

작업일지를 마치며 

✨ 나의 생각

데이터베이스 설계 자체가 개발 과정에 있어 매우매우 중요한 부분이라고 생각된다.

이전 프로젝트를 생각해봤을 때 개발 중간중간에 필드가 추가되고 새로운 테이블을 따로 만드는 경우가 많았기 때문에 이번에는 개발 단계에 들어가기전 기반을 확실히 해두고 싶었다. 그렇지만 이번에도 개발하다가 테이블이나 필드들을 추가해야하지 않나 싶다.

완벽하지 않더라도 아직 걸음마도 떼지 못한 개발자? 우리를 개발자라고 불러도 괜찮을까? 연습생이라고 생각해야겠다. 우리는 연습생이기 때문에 진정으로 개발자로 데뷔하기 전에 최대한 많은 시행착오를 겪어보는 것도 좋은 경험이 될 것 같기도하다

Reference

🙏 [DataBase] ERD란?