개발 낙서장

[TIL] 내일배움캠프 57일차 - 순서 저장 방법 본문

Java/Sparta

[TIL] 내일배움캠프 57일차 - 순서 저장 방법

권승준 2024. 3. 19. 21:26

오늘의 학습 키워드📚

순서 변경을 DB에 저장하는 방법

위 사진은 Trello에서 컬럼끼리 순서를 변경하는 방법이다.
오브젝트를 드래그해 옮기면 순서가 변경된다. 해당 기능을 구현하려면 DB에도 순서에 대한 값이 들어가야 하는데 어떻게 변경해야 할지 고민이 됐다.

1. 변경될 컬럼과 직접 sequence 값을 변경한다.

1번 방법은 굉장히 직관적인 방법이다. To do 컬럼의 sequence가 1, Doing 컬럼의 sequence가 2라고 가정할 때 To do를 Doing의 뒤로 변경시키려면 Doing 컬럼의 sequence를 1, To do 컬럼의 sequence를 2로 변경하면 된다.
해당 방법의 문제점은 하나의 컬럼의 순서를 변경하기 위해 두 개의 컬럼의 값을 변경하는 쿼리를 날려야 한다는 것이지만 방법이 굉장히 쉽고 간단하다.

2. 컬럼 간 sequence 값의 간격을 크게 둔다.

예를 들어 0, 1000, 2000, 3000, ... 이런 식으로 간격을 굉장히 크게 설정한다.
1번 컬럼을 2번 컬럼의 뒤로 이동하고자 하면 1000과 2000의 사이인 1500으로 sequence를 설정하면 된다.
따라서 수정하는 쿼리를 1번만 날려도 되기 때문에 조금 더 효율적이라고 생각한다.
단점은 프론트 단에서 값을 넘겨줘야 하기에 id, sequence에 대한 정보를 전부 알고 있어야 하며 아무리 sequence의 간격이 크다 하더라도 무한히 순서를 변경하게 될 경우 결국 서로 값을 바꿔줘야 하는 경우가 생긴다는 것이다.

sequence 테이블을 따로 만들어 관리한다던가, prevId(혹은 nextId) 필드를 만들어 앞 혹은 뒤에 누가 올지 지정을 해준다던가 등 여러 방법이 있겠지만 위의 두 방법이 가장 활용할만한 방법이라 생각한다.

나는 2번 방법을 사용했다. 간격을 1000, 혹은 10000 등 크게 둔다면 웬만한 횟수로는 정상적으로 동작할 것이다. 물론 혹시나 간격이 좁혀져 서로 바꿔야 하는 경우도 구현했다.

    @Transactional
    public void modifyColumnSequence(Long boardId, Long columnId,
        ModifyColumnSequenceRequest request) {
        Columns columns = validateExistColumn(columnId);

        Long between = (request.getPrevSequence() + request.getNextSequence()) / 2;

        if (between.equals(request.getPrevSequence())) {
            Columns prevColumns = columnRepository.findBySequence(boardId,
                request.getPrevSequence());

            prevColumns.setSequence(columns.getSequence());
        } else if (between.equals(request.getNextSequence())) {
            Columns nextColumns = columnRepository.findBySequence(boardId,
                request.getNextSequence());

            nextColumns.setSequence(columns.getSequence());
        }

        columns.setSequence(between);
    }

사실 뭐 쿼리 한두번 덜 날리는 거라 성능에 큰 영향은 없겠지만 이렇게 최대한 최적화하는 게 하나 둘 쌓이면 나름 DB의 부하를 줄일 수 있다고 생각한다.


오늘의 회고💬

기존에 했던 CRUD라 크게 어렵진 않았고 좀 더 체계적이고 효율적인 쿼리, 로직을 어떻게 작성할까 고민을 많이 했던 것 같다.

 

내일의 계획📜

테스트 코드를 마치고 추가적인 구현이 어떤게 있을까 회의를 진행할 것 같다!

Comments