[DB] Soft Delete vs Hard Delete

HwangDo·2023년 12월 31일
1

JPA

목록 보기
7/7
post-thumbnail
post-custom-banner

이번에 새로 알게된 개념인 Soft Delete에 대해 같이 공부해보자.

먼저 가정해보자. 우리의 User가 하나 존재한다.

유저가 잘 서비스를 사용하다가, 탈퇴를 하려고 한다. 이럴 때 어떻게 처리해야 할까?
당연히 그냥 delete를 통해 user를 지워버리면 된다. 이게 JPA의 기본 수행 방법이자, Hard Delete라고 부르는 방법이다.
그런데, 요구 사항이 추가되었다. 유저가 실수로 탈퇴 했을 수 있으니 복구 기능을 추가하고 싶다.
그렇다면 어떻게 해야할까?

다양한 사용 방법이 존재하지만, 이럴 때 사용 가능한 것이, Soft Delete다.


삭제..한척하기


삭제 여부를 체크하는 칼럼을 추가해서, 만약 탈퇴할 경우 user를 지우는 것이 아닌 delete_flag만 1로 업데이트 해주는 방식이다.
이러면 영구적으로 삭제되지 않고, delete_flag의 값을 where 절에 넣어서 탈퇴한 유저들의 값을 모아 볼 수도 있다.


장점

  1. 복구 가능성
    당연하게도, 실수로 delete한 튜플을 되돌리는 법은 구글에 검색해도 더 확고한 절망을 가지게 된다. 그러나 Soft delete의 경우, 실제 튜플을 삭제하지 않아 복구 할 수 있다.
  2. 성능
    update는 delete보다 빠르다.
    라고 찾았는데, 얼마나 빠를지 궁금해서 직접 테스트를 구성했다.

    먼저 각 테스트 수행 전, 10만개의 엔티티를 삽입했다.

    이후 각 메소드는 업데이트와 삭제를 진행하며 수행 시간을 측정한다.


    단위는 ms다. 약 1.5초가량 Update가 더 빠른 모습을 보였다. 7%가량 빠른 결과다.

단점

그렇지만 위 장점만 있었으면 Soft Delete가 표준이 되었을 것이다..

  1. 공간 낭비
    soft delete는 튜플을 삭제하지 않고, 칼럼값만 바꾼 뒤 DB에 냅둔다. 따라서 삭제연산한 튜플이 DB에 지속적으로 남아있으니 공간을 많이 잡아먹게 된다. 그 말은 즉 조회 쿼리 성능에도 영향을 줄 수 있다.
  2. 복잡성
    이 복잡성은 개발자 입장이다. Soft Delete를 채용 할 경우, 모든 개발자가 Soft Delete를 수행함을 명확히 인지하고 있어야 한다. 만약 실수로라도 update가 아닌 delete 쿼리를 써버린다면.. 결과는 처참하다. 이를 어느정도 막기 위해 JPA는 @SQLDelete라는 어노테이션을 통해, 삭제 쿼리 수행시 대체할 쿼리를 엔티티 레벨에서 제한 할 수 있다.

개인적인 모호함

위 단점 말고도, 나는 칼럼 중 Unique Constraint가 걸린 경우에 대해 의문이 생겼다.
만약 Nickname이라는 테이블이 있고, 닉네임은 중복일 수 없다.
이 테이블에 대해 Soft delete를 적용하면, 삭제로 표기된 튜플이더라도 DB에는 존재하기 떄문에, 한번 쓰인 닉네임은 다시는 쓸 수 없게 되어버린다.
이에 대해 찾아봤다.

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

MySQL 기준, deleted_at이 NULL이면 1이고, 아니면 NULL이 되는 Virtual 칼럼을 선언하고

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

그 두개를 같이 UNIQUE로 묶어버리는 방법을 사용했다.

나도 Virtual Column에 대해 처음 들어봤는데, 이는 실제 칼럼처럼 데이터는 추가되지 않기에 db 용량에는 영향을 주지 않는다. 하지만 select 구문이 실행 될 때 마다 AS 뒤에 있는 트리거가 실행되는 형태로 작동한다고 한다.


개인적인 결론

사실 나는 Soft Delete를 알고 나니까, 잘 써야할 큰 메리트를 모르겠다. 정말 삭제후 일정 기간동안 복구를 해야할 유예 기간을 준다던가 하는 경우정도가 아니면, 보통 Hard Delete가 더 좋을 것 같다. UPDATE로 인한 성능 개선보다는, 잃는 조회 성능이 더 뼈아플 것 같다.
만약 유예기간이 필요한 경우에는, 별도의 테이블에 데이터를 임시로 이관하는 방법도 떠오르기도 한다. 마지막으로 StackOverFlow에 있는

"Soft Delete는 좋은 아이디어인가요?"

라는 질문 게시글에서, 100개의 추천을 받은 답변의 첫 문장을 첨부하며 마무리한다.

profile
제가 배워가는 내용과, 실수한 부분을 정리합니다
post-custom-banner

0개의 댓글