MySQLで並び順をランダムにする方法
以前、何かの案件で記事の並び順をランダムにしたい、という要望がありました。並び順をランダムにするのは、下記のようなクエリーで実現できます。
SQL
SELECT * FROM posts ORDER BY RAND();
ページネーションをする場合は、LIMIT句を付けて部分的に取得すれば良いわけです。
しかし、これだと1ページめに取得した記事を、2ページめ以降にも取得してしまう可能性があります。毎回ランダムな並び順になるので、当然といえば当然ですね・・・。
改善策
RAND()には引数を与えることができ、同じ引数を与えれば同じ乱数が発生します。つまり、例えば
SQL
SELECT * FROM posts ORDER BY RAND(1);
とすれば、並び自体はランダムですが、常に並び順自体は変わらずに取得できます。
したがって、実装としては1ページめを取得する際、適当な乱数nを生成し、クエリー中のRAND()のパラメータにnを指定する、となります(nはセッションやクッキーに保存しても良いでしょう)。2ページめ以降を取得する時も同じnを指定してください。
ただ、インデックスが効かないので、大きなテーブルでのRAND() の使用は注意が必要です。