### 오프셋 기반 페이징 (Offset-based Paging)
오프셋 기반 페이징은 가장 일반적인 페이징 방법으로, `OFFSET`과 `LIMIT`을 사용하여 특정 위치에서 일정한 수량의 데이터를 가져옵니다. 이 방법은 간단하며, SQL 데이터베이스와 같은 데이터 저장소와 쉽게 통합할 수 있습니다. 하지만 대량의 데이터가 있을 때 성능 이슈가 발생할 수 있습니다.
**예시 코드:**
```sql
SELECT * FROM orders ORDER BY created_date DESC LIMIT 10 OFFSET 30;
```
위의 SQL 쿼리는 `orders` 테이블에서 31번째 데이터부터 10개의 데이터를 정렬된 순서대로 가져옵니다.
### 커서 기반 페이징 (Cursor-based Paging)
커서 기반 페이징은 성능 향상을 위해 일정한 데이터를 가져오는 대신 마지막 항목의 위치를 기억하여 다음 페이징 시 시작을 지정하는 방법입니다. API 응답 속도가 빠르고, 클라이언트가 더 많은 데이터를 요청할 때 일관성을 유지할 수 있습니다.
**예시 코드 (Node.js):**
```javascript
app.get('/messages', async (req, res) => {
const { lastId, limit } = req.query;
const messages = await getMessages(lastId || 0, parseInt(limit) || 10);
res.json(messages);
});
async function getMessages(lastId, limit) {
return await db.query(
`SELECT * FROM messages WHERE id > ? ORDER BY id ASC LIMIT ?`,
[lastId, limit]
);
}
```
이 예제는 `messages` 테이블에서 이전에 받은 데이터의 `id`를 기반으로 다음 데이터 목록을 가져옵니다.
### 키셋 기반 페이징 (Keyset Pagination)
키셋 기반 페이징은 주로 정렬 가능한 고유 키를 기준으로 페이지를 나누는 방식입니다. 이는 대량의 데이터셋에서도 일관된 성능을 제공하며, 특히 실시간 데이터 애플리케이션에서 유용하게 사용됩니다.
**예시 코드 (Java/Spring):**
```java
@GetMapping("/transactions")
public ResponseEntity<List<Transaction>> getTransactions(
@RequestParam Optional<Integer> lastKey,
@RequestParam(defaultValue = "10") int pageSize) {
List<Transaction> transactions = transactionService.findTransactionsAfterKey(lastKey.orElse(0), pageSize);
return ResponseEntity.ok(transactions);
}
public class TransactionService {
public List<Transaction> findTransactionsAfterKey(int lastKey, int pageSize) {
return transactionRepository.findByIdGreaterThanOrderByTimestampAsc(lastKey, PageRequest.of(0, pageSize));
}
}
```
이 코드에서는 `transactions` 테이블에서 주어진 `lastKey` 이후의 데이터를 정렬하여 가져옵니다.
### 결론:
MSA 서비스에서 효율적인 페이징 처리는 사용자의 경험과 시스템의 성능을 직접적으로 좌우합니다. 각 방법은 장단점이 있으며, 애플리케이션의 특성과 요구사항에 맞는 적절한 방법을 선택해야 합니다. 여러분의 시스템에 가장 적합한 페이징 방법을 선택하여 최적의 데이터 전송 환경을 구축하세요.