좋은 기획이다. “시대별 영화 지도”는 사용자 경험과 콘텐츠 분류 모두에서 훌륭한 주제다.
이제 질문한 핵심으로 돌아가 보자.
✅ 질문 요약
🎯 movieBgTime을 "19911231,20131231"로 저장하는 게 나은가? 아니면 시작/종료시기를 칼럼으로 분리하는 게 나은가? 더 나은 방법은?
✅ 결론 먼저
시작 시기와 종료 시기를 각각 칼럼으로 분리하는 방식이 가장 좋다.
movieBgStartDate DATE
movieBgEndDate DATE
✅ 이유
1. 검색/필터링이 쉽다
예: "1800년 ~ 1850년 사이에 시작된 영화"
SELECT * FROM movie
WHERE movieBgStartDate >= '1800-01-01' AND movieBgStartDate <= '1850-12-31';
- 반대로 VARCHAR로 "19911231,20131231"처럼 저장하면, 날짜를 자르고 파싱해야 해서 비효율적임
- 인덱스를 활용한 검색도 불가능
2. 타입 안정성
- DATE 타입을 사용하면 날짜 유효성 검사가 자동으로 된다
- 잘못된 날짜 형식(ex. 19911340)은 저장 불가
- 정렬, 범위 비교 등 날짜 연산도 안전하게 수행됨
3. 확장성
- 향후 세기 계산, 기간 길이 계산, 타임라인 그래프, 히스토그램 분포 등에 활용 가능
- 문자열 저장 시 이런 연산이 불가능하거나 복잡함
✅ 추천 테이블 구조 예시
CREATE TABLE movie (
movieNo INT PRIMARY KEY AUTO_INCREMENT,
movieTitle VARCHAR(255) NOT NULL,
movieBgStart DATE NOT NULL,
movieBgEnd DATE NOT NULL
);
- DATE 타입을 사용하면, 프론트엔드에서도 JS Date 또는 ISO 문자열로 쉽게 다룰 수 있음
✅ 추가 아이디어
🎯 시대 구분을 SQL에서 처리하기 쉬운 형태로 만드는 방법
예를 들어, 19세기 초를 계산할 수 있도록 하고 싶다면:
- 프론트에서 "19세기", "초"를 선택 → startYear = 1800, endYear = 1833
- 아래와 같은 쿼리 작성 가능:
SELECT * FROM movie
WHERE movieBgStart >= '1800-01-01'
AND movieBgEnd <= '1833-12-31';
이처럼 구조화된 DATE 타입을 쓰면 프론트에서 선택한 필터 → DB 검색이 자연스럽게 연결된다.
✅ 정리
방식 추천 여부 이유
"19911231,20131231" 문자열 1개 | ❌ | 검색 어려움, 타입 불안정, 비효율 |
시작/종료 칼럼 2개 (DATE) | ✅ | 검색, 정렬, 타입 안전, 확장성 탁월 |
타임레인지 타입 (ex. PostgreSQL tsrange) | ⚠️ 가능하지만 과함 | 일반적인 MySQL이나 SQLite 등에서는 비권장 |
필요하다면, "세기"나 "초/중/후"를 자동 계산해주는 SQL 함수, 혹은 API 로직도 도와줄 수 있다.
좋다. 아래는 movieBgStart 날짜를 기준으로 세기(century) 와 초/중/후(duration) 를 계산하는 SQL 로직을 보여주겠다.
기본적으로 MySQL을 기준으로 작성하며, DATE 타입을 사용한다는 전제하에 설명한다.
✅ 목표
예: movieBgStart = '1852-06-01'일 때
- 세기 (Century): 19C
- 시기 (Duration):
- 1800~1833 → 초
- 1834~1866 → 중
- 1867~1899 → 후
✅ 1. 세기 계산
SELECT
movieTitle,
movieBgStart,
CONCAT(FLOOR((YEAR(movieBgStart) - 1) / 100) + 1, 'C') AS century
FROM movie;
📌 설명
- YEAR(movieBgStart) → 연도 추출
- (연도 - 1) / 100 + 1 → 세기 계산 공식
- 1801~1900 → 19C
- 1901~2000 → 20C
✅ 2. 초/중/후 계산
이건 세기 내에서 연도를 나누는 계산이 필요하다. 먼저 기준을 정의한다:
SELECT
movieTitle,
movieBgStart,
CONCAT(FLOOR((YEAR(movieBgStart) - 1) / 100) + 1, 'C') AS century,
CASE
WHEN YEAR(movieBgStart) % 100 BETWEEN 0 AND 33 THEN '초'
WHEN YEAR(movieBgStart) % 100 BETWEEN 34 AND 66 THEN '중'
ELSE '후'
END AS duration
FROM movie;
📌 설명
- YEAR(movieBgStart) % 100 → 해당 세기 내에서 몇 번째 해인지
- 0~33 → 초, 34~66 → 중, 67~99 → 후
✅ 예시 결과
movieTitle movieBgStart century duration
Anne of Green Gables | 1832-05-01 | 19C | 초 |
Les Misérables | 1860-10-10 | 19C | 중 |
Titanic | 1912-04-10 | 20C | 초 |
La La Land | 2016-12-25 | 21C | 후 |
✅ 필요하다면 뷰(view)로 만들어 관리
CREATE VIEW movie_with_period AS
SELECT
movieNo,
movieTitle,
movieBgStart,
movieBgEnd,
CONCAT(FLOOR((YEAR(movieBgStart) - 1) / 100) + 1, 'C') AS century,
CASE
WHEN YEAR(movieBgStart) % 100 BETWEEN 0 AND 33 THEN '초'
WHEN YEAR(movieBgStart) % 100 BETWEEN 34 AND 66 THEN '중'
ELSE '후'
END AS duration
FROM movie;
✅ 정리
항목 SQL 함수
세기 구하기 | FLOOR((YEAR(...) - 1) / 100) + 1 |
초/중/후 | CASE WHEN ... THEN ... 구문 |
이렇게 정리된 결과를 기준으로 React에서 필터링하면, 매우 직관적인 UI + 빠른 쿼리 응답을 만들 수 있다.
원하면 이 결과에 따라 React에서 DurationMenu 필터 기능도 구현해줄 수 있다.
'X 1인웹개발' 카테고리의 다른 글
20/11/10 1. spring 프로그래밍에서 매개변수를 주고 받는 방법 (0) | 2020.11.11 |
---|---|
가정과 사무실에서 프로젝트를 이어서 작업하는 경우 db연결에 주의할 사항 (0) | 2020.11.10 |
20/11/7 집 컴퓨터와 연동하기 (0) | 2020.11.08 |
20/11/5 1.상품 상세 페이지에 db 레코드를 뿌리려 할 때 classcastexception 발생 (0) | 2020.11.08 |
20/11/4 2. 상품 상세 페이지에 db 레코드를 뿌리려 할 때 classcastexception 발생 (0) | 2020.11.08 |