본문 바로가기
  • 시 쓰는 개발자
1일 1개념정리 (24년 8월~)/Spring

1일1개 (67) - DB에서 삭제한줄 알았지?

by poetDeveloper 2024. 10. 22.
반응형

1일 1개념정리 24.08.09.금 ~ 

 

큰 결정에 큰 동기가 따르지 않을 때도 있다. 하지만 큰 결심이 따라야 이뤄낼 수 있다.

무조건 무조건 1일 1개의 개념 정리하기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!


#67. Soft delete, Hard delete

예전에 Spring 개발시 soft delete, hard delete라는 개념을 썼었는데, 그때는 뭐가 뭔지 잘 모르고 썼다. 오랜만에 생각이 나서 정리해보려 한다.

 

Hard Delete

먼저 Hard Delete에 대해서 알아보자. 우리가 보통 사용하는 방법 그대로다. 데이터베이스에서 데이터를 영구적으로 삭제하는 것을 말하고, 삭제된 데이터는 복구할 수 없다.

  • 데이터가 완전히 제거되므로 저장 공간이 절약
  • 데이터의 영구 삭제가 필요할 때 사용
@Transactional
public void deleteEntity(Long id) {
    repository.deleteById(id);
}

 

Soft Delete

Soft Delete는 데이터를 실제로 삭제하지 않고, 삭제된 것처럼 표시하는 것이다. 예를 들어, deleted라는 컬럼을 추가하여 값이 true면 삭제된 것으로 간주한다.

  • 삭제된 데이터를 복구할 수 있다.
  • 데이터 이력을 보존할 수 있어, 로그 추적 등에 유리
  • 보통 isDeleted 또는 status 필드를 추가해 관리함.
@Entity
public class Entity1 {
    @Id
    private Long id;

    private String name;

    private Boolean deleted = false; // 삭제 여부 표시 필드
}

@Transactional
public void softDeleteEntity(Long id) {
    MyEntity entity = repository.findById(id).orElseThrow();
    entity.setDeleted(true);
    repository.save(entity);
}

 

각각이 언제 사용되는가 ??

1. Hard Delete가 사용되는 경우

  • 데이터 재사용 할 일이 없을 때 : 로그 데이터나 임시 데이터를 삭제할 때 사용함. 즉, 다시 사용할 일이 없을 때.
  • 저장 공간이 필요한 경우 : 삭제된 데이터를 보관할 필요가 없고, 대용량 DB에서 저장 공간 절약이 중요한 경우
  • 보안 및 규정 준수 : 개인정보 보호 규정이나 정책에 따라 완전 삭제가 필요할 때.

2. Soft Delete가 사용되는 경우

  • 데이터 복구가 필요한 경우 : Hard때랑은 반대로, 데이터 복구가 필요한 경우 즉 삭제 후에도 다시 사용할 일이 있을 것 같다면 임시로 삭제시켜놓는 것이다.
  • 논리적 삭제 요구 : DB에서 데이터의 물리적인 삭제보다 논리적으로 삭제된 상태를 표시해야 할 때. 즉, 데이터의 상태 관리 및 추적이 필요한 경우에 유용하다.

 

의문점.

아니 deleted라는 필드가 만능도 아니고, 어차피 findById 해버리면 실제로 삭제된 것이 아니니깐 찾아와지는 거 아닌가 ?? 그래서 이를 방지할 몇몇 방법이 필요하다 ....

 

예를들면.. .JPA의 find 쿼리 자체를 이런식으로 나눠서 짤 수 있다. 그니까, findAllById 이런식의 메소드를 애당초 쓰지 않고 findAllByDeletedFalse같이 삭제되지 않은 엔티티를 가져오는 식으로 짠다는 이야기다. 삭제되지 않는 엔티티를 가져오는 방법은 여러가지가 있다.

// 엔티티가 삭제되지 않은 데이터만 찾는 쿼리 메서드
Optional<MyEntity> findByIdAndDeletedFalse(Long id);

// 삭제되지 않은 모든 엔티티 조회
List<MyEntity> findAllByDeletedFalse();

 

아니면 엔티티에 필터링을 걸어주는 것이다.

@Entity
@FilterDef(name = "deletedFilter", parameters = @ParamDef(name = "isDeleted", type = "boolean"))
@Filter(name = "deletedFilter", condition = "deleted = :isDeleted")
public class MyEntity {
    @Id
    private Long id;

    private String name;

    private Boolean deleted = false; // 삭제 여부 표시 필드
}

// 필터 활성화
entityManager.unwrap(Session.class)
             .enableFilter("deletedFilter")
             .setParameter("isDeleted", false);

 

위와 같은 설정을 통해 조회때마다 자동으로 deleted = false인 데이터만 필터링할 수 있다. 좀 더 간단하게는 이렇게도 가능하긴 함.

@Entity
@Where(clause = "deleted = false")
public class MyEntity {
    @Id
    private Long id;

    private String name;

    private Boolean deleted = false;
}
반응형