[Node.js][TIL] DB 논리적 삭제, 물리적 삭제에 대한 이해

Trippy·2023년 11월 23일
0

Node.js

목록 보기
14/28

팀프로젝트를 진행하는 과정 중 회원 탈퇴 기능을 구현하고 있었다.
한 줄 한 줄 코드를 야무지게 짜고 회원 탈퇴를 했을때 DB에 잘 적용이 되나 확인을 했지만 삭제는 되어서 해당 아이디로 로그인은 안되는 상황이지만 DB에는 데이터가 그대로 남아있는 것이다. 처음 이건 내가 또 코드를 잘 못 짰구나 라고 생각하며 오류라고 인식 했는데 그것이 아니었다.

기존 코드

// 회원 탈퇴 API
userRouter.delete("", token_middleware, UserDelete, async (req, res, next) => {
    const me = res.locals.user;
    const { id, email } = res.locals.user;
    const { password } = req.body;
    
  .
  .
  .

        await Users.destroy({ where: { id }});
        return res.status(200).json({
            sucess: true,
            email: email,
            message: "회원 탈퇴 성공",
        });
    } catch (err) {
        next(err);
    }
});

변경 된 코드

// 회원 탈퇴 API
userRouter.delete("", token_middleware, UserDelete, async (req, res, next) => {
    const me = res.locals.user;
    const { id, email } = res.locals.user;
    const { password } = req.body;
   
  .
  .
  .

        await Users.destroy({ where: { id }, force: true }); // 이부분
        return res.status(200).json({
            sucess: true,
            email: email,
            message: "회원 탈퇴 성공",
        });
    } catch (err) {
        next(err);
    }
});

destroy 뒤 조건절에서 force: true를 넣어주면 된다.

여기서 force의 역할은 sequelize에서 force 옵션은 destroy 메서드를 호출할 때 물리적인 삭제를 강제로 수행하는 역할을 한다.

이 옵션을 사용하면 해당 레코드가 DB에서 완전히 제거되며, 삭제된 레코드에 대한 롤백이 불가능하게 된다.

일반적으로 sequelize 모델에서 레코드를 삭제할 떄, 해당 레코드는 물리적으로 삭제되는 것이 아니라 논리적으로 삭제되어 deletedAt 과 같은 속성이 설정되고, 더 이상 조회되지 않는다. 이는 복구 가능한 삭제를 의미하며, 삭제된 레코드를 다시 복원할 수 있게된다.

force : false 일 때


그렇다면 논리적 삭제와 물리적 삭제를 적절히 사용하는 방법은?

논리적 삭제의 장점도 있고, 물리적 삭제의 장점도 각각 있는 것 같다.

그렇다면 두 개의 특징을 모두 이용하는 방법이 있을까? 생각 해 본다.

실제로 리그오브레전드나 인스타그램과 같은 서비스에서는 계정 삭제를 할 시 곧바로 삭제 되는 것이 아니라 일정 기간의 유예 기간을 두고, 그 기간 동안 사용자가 아무런 액션이 없을 때 비로소 계정을 완전 삭제하는 시스템을 가지고 있다.

=> 이것은 일반적으로 "소프트 삭제" 또는 "논리적 삭제"로 알려진 패턴 중 하나 이다.

일정 기간 후 물리적 삭제 설정

이를 위해 백그라운드 작업이나 스케줄러를 사용하여 주기적으로 삭제 작업을 수행하는 것이 일반적이다.
예를 들어, Node.js에서는 node-cron 또는 node-schedule과 같은 라이브러리를 사용하여 주기적으로 특정 작업을 수행할 수 있다.


const cron = require('node-cron');

cron.schedule('0 0 * * *', async () => {
  // 매일 자정마다 실행되는 작업
  await Users.destroy({ where: { deletedAt: { [Op.lt]: new Date(new Date() - 30 * 24 * 60 * 60 * 1000) } }, force: true });
});

위의 코드는 매일 자정마다 실행되며, 30일 이전에 삭제된 레코드를 완전히 삭제하는 작업을 수행한다. 간단한 예시이니 자신의 상황에 맞춰 주기와 조건을 정해서 하도록 해 보자.

profile
감금 당하고 개발만 하고 싶어요

0개의 댓글