Hard Delete? Soft Delete?
Delete 처리를 개발하던 도중, Soft Delete와 Hard Delete 두 방법이 존재한다는 것을 알게 되었다.
Hard Delete는 물리 삭제라고도 하며, DB에서 해당 데이터를 실제로 삭제하는 것을 의미한다.
Soft Delete는 논리 삭제라고도 하며, DB에서 해당 데이터가 삭제된 것을 하나의 컬럼을 이용하여 구분하는 것을 의미한다.
즉,
Hard Delete의 경우에는 DB에 Delete Query를 날리게 되고
Soft Delete의 경우에는 DB에 Update Query를 날리게 된다.
Soft Delete를 사용하는 이유?
그렇다면 Soft Delete를 왜 사용하게 되는 것일까?
Hard Delete를 진행하게 되면 해당 글에 어떤 문제가 생겼을 때 사용자가 삭제해버린다면, 운영진 등이 어떤 문제가 생겼는지 확인할 수 있는 방법이 없어진다. DB에서도 삭제가 되었기 때문이다.
하지만 Soft Delete를 해놓는다면, 사용자의 눈 앞에서만 사라졌을 뿐 DB에 존재하기 때문에, 운영진 등이 어떤 문제가 발생했었는지 추적 관리를 할 수 있게 되는 것이다.
논리적으로만 삭제된다면 DB에 계속 데이터가 쌓일텐데 DB에 부담이 되지 않을까요?
라고 생각이 든다면, 일정 시간이 흐른 뒤에 삭제시키는 방법이 존재할 것 같다.
아마 회원가입을 진행할 때 탈퇴후 몇 개월, 몇 년이 지나면 개인정보에 대한 기록을 파기한다는 내용이 있는 것으로 보아
회원 탈퇴를 진행했을 때 사용자 정보가 DB에서 바로 사라지는 Hard Delete가 아닌 Soft Delete를 사용하여 정보가 남아있지 않을까 라는 생각이 들었다.
사용법
@SQLDelete
JPA Delete를 실행시켰을 때, Update 쿼리가 DB로 보내질 수 있도록 해야 한다.
방법은 해당 Entity에 @SQLDelete 어노테이션을 사용하는 것이다.
해당 어노테이션은 Delete 명령어를 사용했을 때, Delete 쿼리를 커스텀할 수 있게 만들어 준다.
@Where
@Where 어노테이션은 해당 엔티티의 쿼리에 일괄적으로 Where 구문을 추가시키는 역할을 한다.
일반적으로 soft delete를 진행한 경우 작성하게 된다
예제
...
@Entity
@SQLDelete(sql = "UPDATE comment SET deleted_at = current_timestamp WHERE id = ?")
@Where(clause = "deleted_at is null")
public class Comment extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String comment;
@JoinColumn(name = "user_id")
@ManyToOne(fetch = LAZY)
private User user;
@JoinColumn(name = "post_id")
@ManyToOne(fetch = LAZY)
private Post post;
}
@SQLDelete에 "UPDATE comment SET deleted_at = current_timestamp WHERE id = ?" 쿼리를 작성했다.
Delete를 진행하게 된다면 Delete쿼리가 아닌 해당 엔티티의 deleted_at을 현재 시간으로 Update 하라는 쿼리를 보내라는 것이다.
그렇다면 Delete를 진행할 때마다 현재 시간으로 delete_at 컬럼에 데이터가 들어가는 것을 확인할 수 있다.
@Where로 "deleted_at is null"이라는 쿼리를 추가하였다.
만약에 다음과 같이 Comment의 모든 데이터를 찾는 쿼리를 날리게 된다면
select *
from comment
아래와 같이 마지막에 where 문이 추가가 될 것이다.
select *
from comment
where deleted_at is null;
결론
@SQLDelete와 @Where를 사용하여 Soft Delete를 구현해 봤다.
본인의 경우에는 deletedAt을 만들어 현재 시간을 담았지만, 많은 사람들은 boolean 형태로 true, false 형태로 구분을 하기도 한다.
선택은 상황에 따라, 요구사항에 따라 달라질 것 같다.
처음에는 여러 어노테이션을 사용해야 하고, 상황에 따라 @where 어노테이션을 넣고 빼고를 판단하다 보니 어렵다고 느껴졌지만
막상 구현하고 보니 난이도가 높아 보이진 않았다.
여러 이점들을 생각했을 때, 개인적으로 soft delete를 애용하게 될 것 같다.
'Server > JPA' 카테고리의 다른 글
[JPA] Delete와 DeleteById 차이 (0) | 2023.01.02 |
---|---|
[JPA] 01. JPA 시작 (0) | 2022.09.15 |
[JPA] 00. JPA 소개 (0) | 2022.09.14 |