테이블 설계 - bookmark(찜기능)

·2024년 11월 19일

개인프로젝트

목록 보기
3/11

마이페이지에서 사용자가 찜한 게시물을 보여주는 기능을 구현하려면, 찜(좋아요/즐겨찾기) 관련 데이터를 저장하는 별도의 테이블을 설계하는 것이 좋다.

왜 별도의 테이블이 필요할까?

찜 기능은 다음과 같은 이유로 독립된 테이블에 저장하는 것이 효율적이다:

1. 다대다 관계

한 사용자가 여러 게시물을 찜할 수 있고, 하나의 게시물이 여러 사용자에게 찜될 수 있다.
이를 효율적으로 처리하려면 사용자와 게시물 간의 매핑을 관리할 별도 테이블이 필요.

2. 유지보수 용이성

찜한 정보를 board 또는 member 테이블에 포함시키면 데이터 중복과 성능 문제가 발생할 수 있다. 별도의 테이블로 분리하면 데이터 관리와 확장이 쉬워진다.


테이블 설계

테이블 이름은 bookmark로 할 예정

CREATE TABLE bookmark (
    bookmark_id INT AUTO_INCREMENT PRIMARY KEY,    -- 찜 고유 ID
    midx INT NOT NULL,-- 사용자 ID (사용자 테이블 참조)
    review_id INT NOT NULL,-- 찜한 리뷰 ID (bakery_review 테이블 참조)
    bookmark_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (midx) REFERENCES member(midx) ON DELETE CASCADE,  -- 사용자 ID 외래키
    FOREIGN KEY (review_id) REFERENCES bakery_review(review_id) ON DELETE CASCADE  -- 리뷰 ID 외래키
);

동작 흐름

1. 찜하기 버튼 클릭 시

사용자가 게시물을 찜하면, bookmark 테이블에 새로운 레코드가 추가.

INSERT INTO bookmark (midx, review_id) VALUES (?, ?);

2. 마이페이지에서 찜한 게시물 보기

로그인한 사용자의 midx를 기준으로 찜한 게시물을 조회.

SELECT b.bidx, b.subject, b.writer, b.writeday 
FROM board b
JOIN favorite f ON b.bidx = f.bidx
WHERE f.midx = ?;

3. 찜한 게시물 취소

사용자가 찜을 취소하면 해당 데이터를 삭제

DELETE FROM favorite WHERE midx = ? AND bidx = ?;


추가 고려 사항

중복 방지

한 사용자가 동일한 게시물을 여러 번 찜하지 못하도록 midx와 bidx에 UNIQUE 제약을 추가.

ALTER TABLE favorite ADD UNIQUE (midx, bidx);

UI/UX 구현

게시물 상세 페이지에서 "찜하기" 버튼을 동적으로 표시.

  • 찜한 상태: "찜 취소" 버튼
  • 찜하지 않은 상태: "찜하기" 버튼

AJAX를 활용해서 비동기로 동작하도록 구현 가능.


왜 찜 기능을 별도로 구현해야 할까?

데이터 정규화

만약 빵집 리뷰 테이블에 찜과 관련된 데이터를 추가하면 중복 데이터와 테이블 비대화가 발생할 수 있다.

예: 찜한 사용자별로 데이터를 저장하려면 빵집 리뷰 테이블에 새로운 컬럼을 계속 추가해야 함.

다대다 관계 처리

하나의 빵집 리뷰는 여러 사용자가 찜할 수 있고, 한 사용자가 여러 리뷰를 찜할 수도 있다.
이런 다대다 관계를 효율적으로 저장하려면 매핑 테이블이 필요하다.
(예: favorite 테이블처럼 user_id와 review_id를 매핑하는 구조)

확장성과 유지보수성

찜 기능은 빵집 리뷰뿐 아니라 다른 카테고리(예: 자유게시판, 공지사항)에서도 사용할 가능성이 있다.
이때 찜 기능을 별도 테이블로 관리하면 여러 카테고리에서 재사용할 수 있어 유지보수가 쉬워진다.


정리안함

빵집 리뷰 테이블(bakery_review)과 찜 기능 연동 설계
1. 빵집 리뷰 테이블 (bakery_review)
이미 설계한 대로 작성:

sql
코드 복사
CREATE TABLE bakery_review (
review_id INT AUTO_INCREMENT PRIMARY KEY,
midx INT NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
writeday DATETIME DEFAULT CURRENT_TIMESTAMP,
modifyday DATETIME DEFAULT NULL,
view_count INT DEFAULT 0,
filename VARCHAR(255),
ip VARCHAR(15),
FOREIGN KEY (midx) REFERENCES member(midx)
);
2. 찜 테이블 (favorite)
찜 정보를 관리하는 별도 테이블:

sql
코드 복사
CREATE TABLE favorite (
fav_id INT AUTO_INCREMENT PRIMARY KEY,
midx INT NOT NULL,
review_id INT NOT NULL,
fav_date DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (midx) REFERENCES member(midx),
FOREIGN KEY (review_id) REFERENCES bakery_review(review_id),
UNIQUE (midx, review_id)
);
주요 기능 흐름
1. 찜하기
사용자가 특정 리뷰를 찜하면 favorite 테이블에 데이터를 추가:

sql
코드 복사
INSERT INTO favorite (midx, review_id) VALUES (?, ?);
2. 찜 취소
찜한 리뷰를 취소하면 데이터를 삭제:

sql
코드 복사
DELETE FROM favorite WHERE midx = ? AND review_id = ?;
3. 찜한 리뷰 목록 보기
사용자가 마이페이지에서 자신의 찜한 리뷰를 확인:

sql
코드 복사
SELECT r.review_id, r.title, r.writeday
FROM bakery_review r
JOIN favorite f ON r.review_id = f.review_id
WHERE f.midx = ?;
4. 리뷰 상세 페이지에서 찜 상태 표시
리뷰 페이지에 "찜하기" 또는 "찜 취소" 버튼 표시:

sql
코드 복사
SELECT COUNT(*) AS is_favorite
FROM favorite
WHERE midx = ? AND review_id = ?;
결과가 1이면 "찜 취소" 버튼 표시.
결과가 0이면 "찜하기" 버튼 표시.

0개의 댓글