You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 페이지 번호 (0부터 시작)와 페이지 크기 설정intpageNumber = 2;
intpageSize = 10;
Pageablepageable = PageRequest.of(pageNumber, pageSize);
// 페이징된 결과 조회Page<User> userPage = userRepository.findAll(pageable);
// 결과 데이터 가져오기List<User> users = userPage.getContent();
3️⃣ 커서 기반 페이징 (Cursor-Based Paging)
✅동작 원리
Cursor(=데이터를 가리키는 값) , 쉽게 말해, 지금까지 받은 데이터를 표시하는 책갈피
커서 기반 페이징은 마지막으로 조회한 데이터의 고유 식별자(Cursor)를 기준으로 그 다음 데이터를 조회하는 방식입니다.
커서 값: 이전 요청에서 마지막으로 조회된 데이터의 ID나 타임스탬프 같은 고유값을 전달합니다.
LIMIT: 가져올 데이터의 개수를 제한하는 LIMIT을 설정합니다.
데이터의 식별자(예: ID)를 기준으로 다음 데이터만 조회하여, 마지막 데이터 다음부터 일정 개수만큼을 가져옵니다. 예를 들어, "ID가 100 이상인 데이터 10개"를 요청하는 식입니다.
✅ 장점
고속 처리: 이전 커서 값 이후의 데이터를 바로 조회하기 때문에, 오프셋 스캔보다 빠르고 성능이 좋습니다.
일관된 데이터 제공: 실시간 데이터 변동이 발생해도 커서 위치를 기준으로 조회하므로, 누락이나 중복이 없는 일관된 데이터 조회가 가능합니다.
✅ 단점
임의 페이지로 이동이 어려움: 커서를 기준으로 순차적으로 데이터를 불러오므로, 특정 페이지로 이동하는 것이 어렵습니다.
고유 식별자 필요: 커서로 사용할 수 있는 고유 ID 또는 식별자가 필요하며, 복잡한 정렬 기준이 포함될 경우 적용이 까다로울 수 있습니다.
📌 커서 기반 페이징 SQL 예시
커서를 기반으로 데이터를 조회하는 SQL 구문의 예시는 다음과 같습니다. 이 예시에서는 ID를 기준으로 페이징합니다.
첫 페이지 요청
첫 페이지는 커서 없이, 조회할 데이터의 개수만 지정하여 요청합니다.
SELECT*FROM users
ORDER BY id ASCLIMIT10;
users 테이블에서 id 기준으로 정렬된 첫 10개의 데이터를 가져옵니다.
다음 페이지 요청
첫 페이지 조회 결과에서 마지막으로 조회한 데이터의 id를 커서로 사용하여 이후 데이터를 가져옵니다.
예를 들어, 첫 페이지의 마지막 id가 10이라고 가정하면, WHERE 절을 사용해 id가 10보다 큰 데이터만 조회합니다.
SELECT*FROM users
WHERE id >10ORDER BY id ASCLIMIT10;
id가 10보다 큰 데이터를 id 오름차순으로 정렬하여 10개만 가져옵니다.
📌 커서 기반 페이징 구현 예시 (Java + JPA)
Java와 Spring Data JPA를 사용하여 커서 기반 페이징을 구현하는 예시입니다. 여기서는 id를 커서로 사용하는 방식입니다.
커서 기반 메서드 정의
Spring Data JPA에서는 쿼리 메서드를 사용해 커서 기준 조회를 구현할 수 있습니다.
importorg.springframework.data.domain.Pageable;
importorg.springframework.data.jpa.repository.JpaRepository;
importjava.util.List;
publicinterfaceUserRepositoryextendsJpaRepository<User, Long> {
// 커서를 기준으로 이후 데이터 조회 (id가 주어진 커서보다 큰 데이터 조회)List<User> findByIdGreaterThanOrderByIdAsc(LongcursorId, Pageablepageable);
}
페이징 요청하기
이제 커서를 기반으로 UserRepository에서 페이징된 데이터를 조회합니다.
importorg.springframework.data.domain.PageRequest;
importorg.springframework.data.domain.Pageable;
// 페이지 크기와 커서 ID를 설정LongcursorId = 10L; // 이전 요청의 마지막 ID 값intpageSize = 10;
Pageablepageable = PageRequest.of(0, pageSize);
// 커서를 기준으로 다음 데이터 조회List<User> nextPageUsers = userRepository.findByIdGreaterThanOrderByIdAsc(cursorId, pageable);
// 조회된 데이터에서 마지막 항목의 ID를 가져와 다음 커서로 사용if (!nextPageUsers.isEmpty()) {
cursorId = nextPageUsers.get(nextPageUsers.size() - 1).getId();
}
findByIdGreaterThanOrderByIdAsc 메서드는 cursorId보다 큰 id를 가진 데이터 10개를 조회합니다. 다음 요청을 위해 조회된 마지막 항목의 ID를 저장하여, 이를 새로운 커서 값으로 사용합니다.
The text was updated successfully, but these errors were encountered:
ToDo 페이징 처리에 대해 고민해보세요.
keywords : offset based paging / cursor based paging
1️⃣ 페이징이란 ?
페이징은 책 페이지처럼 데이터를 묶음으로 분리하는 과정입니다. 페이징 처리는 데이터를 나누어 보여주는 방식으로, 효율적인 데이터 조회와 전송을 위해 필수적인 개념입니다. 페이징에는 offset 기반 페이징과 커서 기반 페이징 두 가지 주요 방식이 있습니다.
2️⃣ Offset 기반 페이징 (Offset-Based Paging)
✅ 동작 원리
LIMIT
과OFFSET
구문을 사용하여 구현할 수 있습니다. 예를 들어,LIMIT 10 OFFSET 30
은 30번째 데이터부터 10개를 조회하는 식입니다.✅ 장점
✅ 단점
📌 오프셋 기반 페이지네이션의 문제점 예시
오프셋 기반 페이지네이션은 새로운 데이터가 실시간으로 추가되는 상황에서 중복된 데이터를 보거나 데이터를 놓치는 문제가 발생할 수 있습니다. 이를 쉽게 이해할 수 있도록 예시를 들어보겠습니다.
🔎 문제 상황 예시
🔎 시나리오 1 : 중복 데이터
🔎 시나리오 2: 데이터 누락 상황
🔎 요약
오프셋 기반 페이지네이션에서 실시간으로 데이터가 추가되는 환경에서는 다음과 같은 문제가 발생할 수 있습니다:
이 문제를 해결하려면 커서 기반 페이지네이션을 사용하여 마지막으로 본 글을 기준으로 이후 데이터를 조회하는 방식이 더 적합합니다.
📌 Offset 기반 페이징의 SQL 예시
Offset 기반 페이징은
LIMIT
과OFFSET
구문을 사용하여 데이터를 특정 범위로 제한합니다.예를 들어,
LIMIT 10 OFFSET 30
은 30번째 위치부터 10개의 데이터를 조회하라는 의미입니다.1. 기본 페이징 쿼리
users
테이블에서id
기준으로 정렬된 데이터 중 31번째부터 40번째까지 10개의 데이터를 가져옵니다.ORDER BY id
:id
를 기준으로 데이터를 정렬합니다.LIMIT 10
: 최대 10개의 행을 가져옵니다.OFFSET 30
: 30개의 행을 건너뛰고, 31번째 행부터 조회를 시작합니다.2. 페이징 파라미터를 동적으로 설정하는 경우
page
)와 페이지 크기(pageSize
)를 클라이언트에서 받아와LIMIT
과OFFSET
값을 계산하여 쿼리를 작성합니다.:pageSize
와:pageNumber
는 파라미터로 들어오는 값입니다.(:pageNumber - 1) * :pageSize
를 통해 각 페이지의 시작 위치를 계산합니다.OFFSET
값은(3 - 1) * 10 = 20
이 됩니다.LIMIT 10
에 따라 총 10개의 데이터를 조회합니다.📌 Offset 기반 페이징 구현 예시 (Java + JPA)
Pageable 구현체에는 PageRequest라는 객체가 존재합니다.
3️⃣ 커서 기반 페이징 (Cursor-Based Paging)
✅동작 원리
LIMIT
을 설정합니다.ID
)를 기준으로 다음 데이터만 조회하여, 마지막 데이터 다음부터 일정 개수만큼을 가져옵니다. 예를 들어, "ID가 100 이상인 데이터 10개"를 요청하는 식입니다.✅ 장점
✅ 단점
📌 커서 기반 페이징 SQL 예시
커서를 기반으로 데이터를 조회하는 SQL 구문의 예시는 다음과 같습니다. 이 예시에서는
ID
를 기준으로 페이징합니다.첫 페이지는 커서 없이, 조회할 데이터의 개수만 지정하여 요청합니다.
users
테이블에서id
기준으로 정렬된 첫 10개의 데이터를 가져옵니다.첫 페이지 조회 결과에서 마지막으로 조회한 데이터의
id
를 커서로 사용하여 이후 데이터를 가져옵니다.예를 들어, 첫 페이지의 마지막
id
가10
이라고 가정하면,WHERE
절을 사용해id
가10
보다 큰 데이터만 조회합니다.id
가10
보다 큰 데이터를id
오름차순으로 정렬하여 10개만 가져옵니다.📌 커서 기반 페이징 구현 예시 (Java + JPA)
Java와 Spring Data JPA를 사용하여 커서 기반 페이징을 구현하는 예시입니다. 여기서는
id
를 커서로 사용하는 방식입니다.Spring Data JPA에서는 쿼리 메서드를 사용해 커서 기준 조회를 구현할 수 있습니다.
이제 커서를 기반으로
UserRepository
에서 페이징된 데이터를 조회합니다.findByIdGreaterThanOrderByIdAsc
메서드는cursorId
보다 큰id
를 가진 데이터 10개를 조회합니다. 다음 요청을 위해 조회된 마지막 항목의ID
를 저장하여, 이를 새로운 커서 값으로 사용합니다.The text was updated successfully, but these errors were encountered: