상태가 있을 경우의 스키마 설계

dasd412·2024년 8월 31일
0

실무 문제 해결

목록 보기
5/17

배경

사용자가 어떤 컨텐츠에 대해 bookmark 또는 pass를 할 수 있다고 하자.
어떤게 적절한 스키마가 될 수 있을까?

기존에 User 스키마와 Contents 스키마가 있다고 하자. (sql은 작성 편의상 네이밍, 문법 등은 고려하지 않았다.)


방안

1. bookmark와 pass 상태를 통합한 다대다 테이블 만들고, boolean 칼럼 사용하기

CREATE TABLE contentStatus (
    id INT AUTO_INCREMENT, 
    user_id INT, 
    content_id INT,
    bookmark bool,
    pass bool,
    PRIMARY KEY(id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (content_id) REFERENCES contents(id)
);

2. bookmark와 pass 상태를 통합한 다대다 테이블 만들고, Enum 칼럼 사용하기

CREATE TABLE contentStatus (
    id INT AUTO_INCREMENT, 
    user_id INT, 
    content_id INT,
    status ENUM(bookmark,pass,...etc),
    PRIMARY KEY(id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (content_id) REFERENCES contents(id)
);

3. bookmark 테이블과 pass 테이블로 따로 분리하기

CREATE TABLE bookmarks (
    id INT AUTO_INCREMENT, 
    user_id INT, 
    content_id INT,
    PRIMARY KEY(id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (content_id) REFERENCES contents(id)
);
CREATE TABLE passes (
    id INT AUTO_INCREMENT, 
    user_id INT, 
    content_id INT,
    PRIMARY KEY(id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (content_id) REFERENCES contents(id)
);

방안 비교

1안의 경우 bool로 관리되므로, 상태 확인 및 업데이트가 명확하고 직관적인 편이다. 쿼리 역시 단순하게 작성할 수 있다. 반면, 상태가 추가될 때마다 새로운 칼럼이 필요해져 테이블이 커질 수 있다.

2안의 경우, Enum 하나로 모든 상태를 관리할 수 있어 테이블 구조가 단순해진다. 또한 새로운 상태가 추가되더라도, Enum에 새로운 값을 추가하면 되므로 확장성이 좋다. 하지만, 엔티티 는 동시에 여러 개의 상태를 가질 수 없게 된다. 운영체제 프로세스 상태 천이나 로그인 상태 등 동시에 여러 개의 상태가 존재해서는 안될 경우에 적합한 설계다.

3안의 경우, 기획 변경에 대한 확장성이 좋으며 하나의 엔티티가 여러 개의 상태를 가질 수 있는 설계다. 하지만 테이블이 하나 더 생기므로 join 연산이 하나 더 추가된다. 뿐만 아니라 여러 개의 상태를 가질 때 공존할 수 없는 상태의 경우에는 어플리케이션 레벨에서 잘 관리해야 한다. 추후 사양 변경이나 기획 요구 사항 변경으로 확장성을 충족시켜야 할 때, 특히 추후 동시에 여러 개의 상태가 존재하게 될 수도 있다고 판단되는 경우 적합한 설계다.


profile
시스템 아키텍쳐 설계에 관심이 많은 백엔드 개발자입니다. (Go/Python/MSA/graphql/Spring)

0개의 댓글