pagination 이란?
- 쉽게 말해 페이지별로 다른 데이터를 보여주기위해 , 데이터를 일부만 받아오는 방식입니다.
❗ 실수하고 있던점
- 맨처음 페이지네이션을 구현해보자 했을때 ,
기능을 구현하는데만 열중했었다.
"SELECT * from recipe" 쿼리문으로 recipe table의 모든 행을 가져온뒤 ,그 데이터를 바탕으로 페이지를 나누었다.
간단한 예시코드
const [currentPage, setCurrentPage] = useState(1); //현재페이지넘버
const ITEMNUM=9; // 페이지당 보여줄 데이터의 갯수
const indexOfLast = currentPage * ITEMNUM;
const indexOfFirst = indexOfLast - ITEMNUM;
//indexOfLast,indexOfFirst로 전체데이터에서 페이지별로 필요한데이터를 추출합니다.
const CurrentPost = (post:Recipe[])=>{ //post는 recipe 테이블의 전체데이터입니다.
let currentPosts: Recipe[] = [];
if (post != undefined) {
currentPosts = post.slice(indexOfFirst, indexOfLast);
//1페이지라면 post.slice(0,9)
//2페이지라면 post.slice(9,18) 이됩니다.
}
return currentPosts;
}
하지만 이방식으로 페이지를 나누게된다면 데이터가 만개,십만개,백만개 ... 늘어나게 됐을때 ,
매번 데이터를 전부 가져오는 행위는 성능에 큰 부화를 준다는걸 알게 되었다.
❗ 문제해결
- 해당 문제를 해결하기위해 offset 기반의 pagination을 구현했습니다.
- offset이란 , 데이터에서 가져올 특정 페이지의 시작위치를 나타냅니다. 일반적으로 데이터베이스 쿼리에서 사용됩니다.
- " SELECT * FROM recipe LIMIT ITEMNUM OFFSET ((page-1)*ITEMNUM) "
offset에는 시작점을 , limit이는 가져올 데이터의 갯수를 넣어줍니다. - recipe말고도 데이터를 불러와야하는 테이블이 여러개가 존재합니다. 그렇기때문에 불러올 데이터의 테이블, 가져올데이터의 갯수, 현재 페이지가 쿼리문에서 필요합니다.
간단한 예시코드입니다.
export const getListByPage = async ({
page,
size,
setList, //useState 함수를 통해 데이터를 저장하는 과정에서 setList 함수를 사용합니다.
type,
}: GetListByPageProps) => {
try {
const result = await axios.get(
`url/list/${type}?page=${page}&size=${size}` // list/${type} 과 쿼리를통해 원하는 테이블, 페이지, 가져올데이터의 갯수를 보내줍니다.
);
setList(result.data);
} catch (err) {
console.log(err);
}
};
const queryType = ["recipe", "place", "counseling"];
queryType.map((type)=>{
app.get(`/list/${type}`,async(req,res)=>{
if (!req.query) return BAD_REQUEST;
const { page, size } = req.query;
const response = await conn.excute( `SELECT * FROM ${type} LIMIT ${size} OFFSET ${(page - 1) * size}`)
res.status(200).json(response);
})
})
하지만 이러한 offset 기반의 페이지네이션도 단점이 분명히 있었습니다.
Offset 기반의 페이지네이션은 간단하고 직관적이지만, 대량의 데이터를 처리할 때 성능 문제가 발생할 수 있으므로 대규모 데이터베이스에서는 조심해서 사용해야 합니다.
그래서 cursor기반의 페이지네이션이 있습니다.
하지만 이또한 단점이 분명히 있습니다.
Cursor 기반의 페이지네이션에서는 데이터의 순서를 중요하게 고려해야 합니다. 만약 데이터의 순서가 변경된다면 이전 페이지와 다음 페이지의 결과가 일관성 없게 나타날 수 있습니다.
일반적으로 전체 페이지 수를 정확하게 계산하기 어렵습니다. 이전 페이지와 다음 페이지를 나타내는 커서 값만 관리하기 때문에 사용자에게 현재 페이지가 전체 페이지 중 몇 번째인지 알려주기 어렵습니다.
데이터의 검색 및 필터링이 어려울 수 있습니다.
사용자가 특정 페이지로 바로 이동하는 기능을 구현하기 어려울 수 있습니다.
이러한 점을 고려했을때, 개인 소규모 프로젝트이기 때문에 데이터베이스의 규모가 크지 않을꺼라 판단해
offset기반으로 페이지네이션을 구현했습니다.
'Cooka프로젝트 > 게시판' 카테고리의 다른 글
react-quill 라이브러리 이미지처리 (0) | 2023.09.24 |
---|