クローリングされにくいユニークなIDを発行する方法

ちょっと思いつきメモ。

CakePHP を使っていて思うのだけど、id が大抵 auto inrement になっているのが問題になる場合がある。内部的な id ならば int でガンガン連携すればいいのだけど、

  • レガシーデータベースの場合は、id が文字列だったり
  • レガシーデータベースの場合は、プライマリーキーが複数だったり、
  • 連続する id だと、クローリングされやすい。

という問題がある。

先の2つは、後で CakePHP で確認するとして、連続する id で問題なのは、

  • 商品IDのように、サイトでクローリングされるとちょっと困る

場合なのだ。

例えば http://servername/books/100 という id を振ってあったら、次は容易に http://servername/books/101 と想像できる。で、そうなると、books/10000 なんてあったら、すぐにでも perl なりでクローリングができてしまうという…まあ、ブログなんかはいいんだけど(検索されるのが目的だし)、商品サイトなんかは良し悪しといところがある。

で、文字列なり数値で別なユニークなキーが欲しいときは、

m: ある程度大きい素数
n: m よりも大きく、m で割り切れない数

にしておいて、

id = (m * i) mod n
0 <= i <= n

とすると id が取得できる、ってこれであっているのかな?(他に良い方法がありそうだけど)

証明は、

  1. n > m * i の間は、id は任意になる。
  2. n < m * i+1 となる時、id = m*(i+1)-n = k とすると、k は m を割り切れない(mが素数だから)
  3. 初期値の s0 = k – m は、i が n になるまで一意になるので、id は結果的に一意になる。

…って、きちんとした証明になっていないので、こっちは後程。

カテゴリー: 開発, 雑談 パーマリンク