[TIL] soft-delete 와 unique 제약조건에 대한 고찰

김건우·2024년 9월 12일

[TIL]

목록 보기
20/25

soft-delete 적용 이유?

실제 서비스를 운영하는 프로젝트 개발하면서 사용자가 테러 이후 회원 탈퇴 처리를 해서 아무런 정보를 확인할 수 없다거나, 사용자가 게시글 같은 자료를 잘못 삭제한 경우에 대해 운영자 측에서 복구해 줄 수도 있게 soft-delete를 사용했다.

soft-delete를 사용하면서 unique 필드에 대한 처리를 어떻게 하는지 좋을까 에 대한 고민이 생겼다.

어떤 문제냐면..

주로 Spring에서 soft-delete 처리는 이런 느낌으로 자동화를 시켜놓는다.
2줄의 코드는 delete 처리 대신 is_delete 필드의 값을 true로 바꾸는 처리와, 매 검색마다 is_delete 필드의 값이 false인 값만 검색하는 where 조건을 붙이는 처리이다.

unique 필드는 DB에 유일하게 존재하는데, soft-delete를 사용하면 삭제되지 않고, 남아있게 된다.

이때, 값을 추가하는 로직에서 @SQLRestriction 어노테이션으로 is_delete is false 처리를 하기에 당연하게 soft-delete 된 필드를 인식하지 못해 insert 를 하다가 오류가 나게되는 것이다.

여기에는 3가지 해결 방법이 있다.

  1. unique 설정을 사용하지 않고, @SQLRestriction 어노테이션을 통해 soft-delete 처리되지 않은 값들에 대해 중복 확인 후, 삽입.
  2. unique 설정을 하고, 모든 필드에 대해 검색한 뒤, 중복 확인 처리
  3. 기존 unique 컬럼과 deleted_at 컬럼 두개를 다중 컬럼 unique를 건다.

추가

  • 기존 unique 컬럼의 레코드 값을 삭제할 때 deleted_~ 이런식으로 수정해주는 방법도 사용해볼만 할 것 같다.

1번은 어떠한 이유에서든 중복 값이 삽입된다면 후 처리해주는게 쉽지 않을 것이고, unique 설정을 하지 않아 전체 탐색에 있어서 속도가 느려질 것이기에 포기.

2번은 unique 설정을 하고, 전체 탐색을 진행하려면 @SQLRestriction 을 제거하고, 기존 사용 메서드에 모두 where id=? 를 추가해줘야 하며, 전체 탐색을 위한 jpa 메서드가 하나 더 필요하다. 복잡해짐..

다중 컬럼 unique는 다음처럼

  • abc123이라는 아이디를 생성하고 탈퇴 -> deleted_at에 삭제한 시간 자동 기입
  • abc123이라는 아이디를 다시 생성 -> 아이디는 중복이지만 deleted_at 컬럼이 달라지기 때문에 안됨

참고 블로그 : https://oraange.tistory.com/26

즉, 2개의 필드를 함께 unique 제약조건으로 확인하는 것이다.

ALTER TABLE users
ADD not_archived BOOLEAN
GENERATED ALWAYS AS (IF(deleted_at IS NULL, 1, NULL)) VIRTUAL;

not_archived 라는 virtual 컬럼을 만든다. 이는 deleted_at이 null 이면 1이 들어가고, 존재하면 null이 된다.

ALTER TABLE users
ADD CONSTRAINT UNIQUE (nickname, not_archived);

그리고, 기존 unique 컬럼과 묶어서 관리하며, 기존에 nickname의 CONSTRAINT는 제거해야 한다.


soft-delete 가 마냥 좋은걸까..?

확실히 복잡도가 증가한다.

현 프로젝트에서는 좋아요 같은 기능에 대해서는 soft-delete를 적용하고 있지 않고, 복구가 필요할 것 같거나 완전 삭제보단 데이터를 남기는게 좋다고 생각한 테이블에 대해서는 soft-delete를 적용하고 있다.

또한 추후 백오피스 기능을 개발해야 할 때, 삭제된 사용자에 대해서도 확인할 api가 필요할 텐데.. 관리자용 조회 메서드를 별도로 추가해야 할 것 같다.

EntityManager를 직접 사용하면 @SQLRestriction으로 인해 자동으로 조건절이 추가되는 것을 우회할 수 있다고 한다.

여튼 soft-delete를 사용하면서 편해지는 부분도 존재하고, 오히려 더 복잡해지는 부분도 존재하는 trade-off 의 영역이라 잘 고민하고 꼭 필요한 부분에만 적용해야 할 것 같다.

profile
공부 정리용

0개의 댓글