📃

offsetとcursorの違い

2024/07/29に公開

2つのページネーションの違いについてメモ

オフセット・ページネーション

「x番目からy個を表示」 という考え
この時の x をオフセット、y をサイズと言う
ページ番号で管理

例)9つのitemデータがあるとき
Item = [item1, item2, item3, item4, item5, item6, item7, item8, item9]

page1:item1, item2, item3(1番目から3つ)
page2:item4, item5, item6(4番目から3つ)
page3:item7, item8, item9(7番目から3つ)

この先頭にnewItemを追加すると
Item = [newItem, item1, item2, item3, item4, item5, item6, item7, item8, item9]

page1:newItem, item1, item2(1番目から3つ)
page2:item3, item4, item5(4番目から3つ)
page3:item6, item7, item8(7番目から3つ)
page4:item9(9番目から3つ)

追加された分だけズレる!各ページのitem内容が変わる!

メリット

任意のページに飛びやすい
シンプル

デメリット

オフセットの分だけ読み込みが必要なため、オフセットが大きくなるとパフォーマンスが低下する。
データの更新が頻繁に起こると、itemの重複(2つのページに存在する)や不足(どのページからもいなくなる)が生じてしまう可能性がある。

カーソル・ページネーション

「x+1番目の次からyまでを表示」 という考え
この時の x をカーソルと言う
ページ番号ではなく、前と次のページ管理をする
データ数が多い場合や無限スクロールの実装に使われる

例)9つのitemデータがあるとき
Item = [item1, item2, item3, item4, item5, item6, item7, item8, item9]

現在のページ :item1, item2, item3(0の次から3まで)
次のページ  :item4, item5, item6(3の次から6まで)
次の次のページ:item7, item8, item9(6の次から9まで)

この先頭にnewItemを追加すると
Item = [newItem, item1, item2, item3, item4, item5, item6, item7, item8, item9]

前のページ  :newItem(0の次からnewまで)
現在のページ :item1, item2, item3(newの次から3まで)
次のページ  :item4, item5, item6(3の次から6まで)
次の次のページ:item7, item8, item9(6の次から9まで)

→ 前にページができる!ページの内容は変わらない!

メリット

パフォーマンスが良い
重複や不足がない
→ 大量なデータや更新頻度が多い場合に向いている

デメリット

sqlのorder byで使用するカラムにindexを張る必要がある
ページ番号がない

まとめ

静的なものの実装や、ページ番号をつけたい時 → オフセット
動的、無限スクロール、データが多い時 → カーソル

カーソル・ページネーションの方がパフォーマンスが良いからよさそうと思ったけど、それぞれ使い分けできるのがよさそう!

参考

https://qiita.com/ma_r_ko/items/410585238c28eb878806
https://note.com/note_fumi/n/nd5ee70a912d2

Discussion