LoginSignup
6
3

More than 5 years have passed since last update.

今どきのページング

Posted at

ページングって?

Webサイトの一覧画面って大概ページングする。

ページングとは、まさに、複数行を1画面に表示して、次のページにまた複数行を表示するようインターフェースのこと。

UIとして、画面を移動したり、画面下部に継ぎ足されたりとかいろんなパターンはあるが、そこは重要ではなく、データ構造としてどう取り出すかというのがポイント。

古くから有る例「limit」

SQLにはlimit句がある

select * from users order by id limit 20,10;

この例では、「21番め移行を10件とってきなさいよ」って命令になる。

10件ずつとってくるのは、一気に10万件とかとってきちゃうと画面のデータがいっぱいになっちゃうから。かならず上限は決める。

Webの一覧画面では、レコード数ではなく「1ページあたりの件数を決めて」「何ページ目からのスターとか」ってことで、UIをつくる。ECサイトの大半はそういう作り。

SS 2017-06-27 12.59.01.png

URLのクエリストリングにp=2とかpage=2 とかついてるから、いきなりp=10とかってやれば、いきなり後ろの方のデータを取得できる。

今風のページングは、max_id を取得

limitを使ったページングは、これはこれで、教科書どおりなんだけど、offsetって後ろの方のページになると遅いんですね。じゃぁってことで、イマドキはmax_idをつかう。max_idってのはSQLの用語ではなく、「そのページにある最大のidを覚えておいてそれより小さな件数を取得する」ということ。

Twitterなんかがまさにそうで、そのページのTweetの最大をとっておいて、それより小さなTweetIDを取得するようにしている。

RubyのActiveRecordも、バッチ処理で複数レコードを処理するときには、以下のように、処理したIDの最大を勝手に覚えてくれるので、メモリがあふれることなく、次々と処理をしてくれる。

 SELECT  `users`.* FROM `users` WHERE (`users`.`id` > 1001)  ORDER BY `users`.`id` ASC LIMIT 1000

max_idでページングするデメリット

並び順の種類が2個になっちゃう

「このid以前(以降)何件頂戴」はDBに対してはすごく速いんだけど、並び順が制御できない(idの昇順か降順)。SNSは、新着順が殆どなので、増えていくタイプのIDだと、IDの降順でだいたいこと足りる。だけどSNSのとかだと、必ずしも新着順じゃなくて、オススメ順だとかレビュー数順とかになる。

その場合は、並び順で制御するのではなく、抽出条件として「★3つ以上」とかのUIにするとかで回避。

ランダムなIDは使いづらい

そもそも、IDがオートナンバーで増えつづける方式もそれはそれで古い。オートナンバー方式だとDBが分残しにくいので、UUID的なランダムな文字列を主キーにするというスタイルも出てきている。その場合は時刻で並ばない。そんなわけで、「分散しやすいランダム文字列だけど並び順は時系列」というスタイルの主キーをつかうのがSNSでは多い。

まとめ

SNSなんかは、自由に並び替えたいというニーズよりも、「情報の鮮度」「情報の量」「レスポンスの速さ」が大事なので、絶対max_idの方がいい。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3