2016-08-07 12 views
-2

私はIPの3000行を持っているが、この形式で範囲:多くのIP範囲を格納するPHPの最良の方法は?

5.9.0.0  5.9.255.255  Hetzner  http://www.hetzner.de/ 
5.10.64.0 5.10.127.255 SoftLayer http://www.softlayer.com/ 
5.34.182.0 5.34.183.255 UA Servers https://itldc.com/ 

ユーザーが、私は彼らのIPは、このIP範囲内にある場合ルックアップし、そのような場合には、それらをブロックしたい、私のサイトを訪れた場合。 PHPでIPを検索する最速の方法は何ですか? IP範囲は静的であり、変更されることはありません。

私はすでにIPを保存する.datファイルを作成すると考えていましたが、これは良いアプローチですか?

+0

(すなわち、あなたは2つの機能をcan'tmixと一致)符号なしのPostgreSQL CIDRとINETデータ型をサポートしています。 mysqlやsqliteに関するDunno – alzee

+1

互換性のないデータベースタグを削除しました。使用しているデータベースに質問にタグを付けるか、またはMySQLとSQLiteの両方で元々タグ付けされた理由を明示的に説明してください。 –

+0

最も速い方法は、この特定の用途に合わせて調整されたロジックを持つ(プロセス間で共有される)いくつかのインメモリです。あなたのために巨大な過度の(そして不必要な仕事)可能性があります。あなたの必要条件について正直に考えてください。 –

答えて

0

は(以前linkはPHPでタスクを実行する方法にありました。この質問は、MySQLについてのようです。)

あなたはIPv4のみを行っている場合は、データ型INT UNSIGNEDに保存し、保存するときINET_ATON()を使用フェッチするときはINET_NTOA()となります。

IPv6の場合、とINET6_ATON()INET6_NTOA()を使用してください。

+0

これはコメントでなければなりません。 –

0

ドット付きクワッドを整数値に変換することは、解決策の開始に過ぎません。

通常のインデックスを使用して配列またはデータベースの値を逆参照することはできません。あなたの範囲内で125.54.123.8のようなレコードを探したい場合を考えてみましょう。範囲に開始アドレスがキー入力されている場合は、開始アドレスが検索値より大きいレコードのみを除外できます。範囲の最後にキーが設定されている場合は、エンドアドレスが検索値より小さい場合にのみ値を除外できます。あなたはまだ一致(または欠如)を見つけるためにあなたのデータのおよそ半分を調べなければなりません。

データバーケットまたはネストされた配列を使用できますが、これはややクールな解決策です。

PHPデータ構造を使用して範囲を管理している場合は、検索を開始する前にデータセットを読み込んで解析するのにかかる時間です。経験から、このオーバーヘッドは、mysqlからレコードを取得する場合と比較して、約100〜200行のデータセットで起動します。

解決策は、1次元空間の範囲をマップするためのmysqlの地理空間機能を使用することです - インターネットの割り当てられた範囲全体(RIPE、APNICなどのデータセットを使用)を検索する適度なハードウェアで1ms未満の検索時間を取得します。

プロセスはhere

注記載されている:ip2longを()()、MySQLのINET_ATONながらPHPで署名された32ビット整数値を返し

関連する問題