데이터 모델 개요
서비스에는 크게 두 가지 핵심 엔티티가 있습니다:
1. Webtoon (웹툰): 개별 웹툰 작품의 정보
2. Section (섹션): 홈 화면에 표시될 웹툰 그룹
그리고 이 둘을 연결하는 관계 테이블이 있습니다:
3. SectionWebtoon: 어떤 섹션에 어떤 웹툰이 포함되는지 (N:M 관계)
웹툰 데이터 모델
interface Webtoon {
id: string; // 고유 식별자 (UUID)
title: string; // 제목
author: string; // 작가
thumbnail: string; // 썸네일 URL
description: string; // 줄거리/설명
rating: number; // 평점 (0~5)
genre: string; // 장르
isComplete: boolean; // 완결 여부
isAdult: boolean; // 성인 웹툰 여부
serialDays: string[]; // 연재요일 ["월", "화", "수"]
tags: string[]; // 태그 ["감성", "일상", "드라마"]
deepLinks: Array<{ // 플랫폼별 딥링크 (배열)
platform: string; // "네이버", "카카오", "라인" 등
url: string; // 딥링크 URL
}>;
createdAt: Date; // 생성 날짜
updatedAt: Date; // 수정 날짜
}
설계 포인트 :
- `deepLinks`를 배열로 설계하여 하나의 웹툰이 여러 플랫폼에서 서비스되는 경우 대응
- `serialDays`와 `tags`를 배열로 저장하여 유연한 데이터 관리
- `isAdult` 플래그로 향후 성인 콘텐츠 필터링 대응
섹션 데이터 모델
interface Section {
id: string; // 고유 식별자 (UUID)
name: string; // 섹션 이름 ("이주의 추천", "인기 웹툰")
order: number; // 화면 표시 순서
isAdult: boolean; // 성인 섹션 여부
createdAt: Date; // 생성 날짜
updatedAt: Date; // 수정 날짜
}
MySQL 테이블 스키마
웹툰 테이블
CREATE TABLE webtoons (
id VARCHAR(36) PRIMARY KEY,
title VARCHAR(255) NOT NULL,
author VARCHAR(255) NOT NULL,
thumbnail VARCHAR(512) NOT NULL,
description TEXT,
rating DECIMAL(3,1),
genre VARCHAR(100),
isComplete BOOLEAN DEFAULT FALSE,
isAdult BOOLEAN DEFAULT FALSE,
serialDays JSON,
tags JSON,
deepLinks JSON NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
섹션 테이블
CREATE TABLE sections (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
`order` INT NOT NULL,
isAdult BOOLEAN DEFAULT FALSE,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
섹션-웹툰 관계 테이블
CREATE TABLE section_webtoons (
id VARCHAR(36) PRIMARY KEY,
sectionId VARCHAR(36) NOT NULL,
webtoonId VARCHAR(36) NOT NULL,
`order` INT NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sectionId) REFERENCES sections(id) ON DELETE CASCADE,
FOREIGN KEY (webtoonId) REFERENCES webtoons(id) ON DELETE CASCADE,
UNIQUE KEY unique_section_webtoon (sectionId, webtoonId),
INDEX idx_section_order (sectionId, `order`)
);
설계 포인트:
- `ON DELETE CASCADE`: 섹션이나 웹툰이 삭제되면 관계도 자동 삭제
- `UNIQUE KEY`: 같은 섹션에 같은 웹툰이 중복 추가되는 것 방지
- `idx_section_order`: 섹션 내 웹툰을 순서대로 조회할 때 성능 최적화
데이터 관계도
Section (섹션)
├─ id
├─ name
├─ order (섹션 순서)
└─ webtoonIds[] (섹션 내 웹툰들)
├─ webtoonId (Webtoon 참조)
└─ order (섹션 내 순서)
Webtoon (웹툰)
├─ id
├─ title
├─ author
├─ thumbnail
├─ deepLinks[] (플랫폼별)
├─ genre
├─ rating
├─ serialDays
├─ tags
└─ ...
인덱싱 전략
MVP 단계:
- Primary Key, Foreign Key 자동 인덱싱
- `idx_section_order`: 섹션 내 웹툰 정렬용
향후 확장 시 추가 인덱스 :
- `idx_title`: 제목 검색 최적화
- `idx_author`: 작가 검색 최적화
- `idx_genre`: 장르별 필터링 최적화