배경
- 스터디 참여에 대해서 하나의 스터디 안에서 유저 당 한 번만 신청할 수 있다.
- 애플리케이션 단에서 데이터 존재 유무를 따지려고 했는데, 연속적으로 들어오는 요청에 대해서 스터디 참여 신청 데이터가 여러 개 존재하게 될 수 있다.
해결
- DB 단에서 UNIQUE 제약 조건을 걸어주면 연속적으로 요청해도, DB 제약 조건에 의해 무조건 하나 이상의 데이터가 생기지 않을 것이란 걸 깨달았다.
- 그렇게 (study_id, user_id)와 같이 UNIQUE를 걸어주려 했는데, deleted_at으로 소프트 삭제를 진행했기에, 애플리케이션 단에서 삭제를 진행해도 DB에서는 데이터가 남아있으므로 오류가 발생했다.
- 부분 인덱스를 활용해 deleted_at 이 null인 데이터에 대해서만 UNIQUE 제약 조건을 걸어주기로 했다.
CREATE UNIQUE INDEX study_participation_unique
ON study_participation (study_id, user_id)
WHERE deleted_at is null;
장점
- 공간 효율성: 테이블의 전체 행에 대해 인덱스를 생성하지 않으므로 디스크 공간을 덜 사용한다.
- 성능 향상: 기본적인 인덱스를 사용하는 것과 동일하게 인덱스를 사용하기 때문에 성능 향상에 크게 기여할 수 있다.
- 유지비용 감소: 인덱스가 작으면, 데이터베이스에서 추가, 수정, 삭제할 때 b+tree 형태와 같이 인덱스를 유지하는데 필요한 작업도 줄어든다.