VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
BETWEEN を使います。VillageSQL の INET 型はスキーマをより表現豊かにし、IPv4 と IPv6 を同じテーブルで扱います。
IP 位置情報の仕組み
IP を国に対応付ける MySQL の関数はありません。位置情報は検索の問題です。IP 範囲のテーブルがあり、各行が「X から Y までのアドレスは国 Z にある」と示していて、受信した IP を含む範囲を見つけます。 MaxMind GeoLite2 のような無料のデータベースは、これらの範囲を MySQL にインポートできる CSV ファイルとして提供しています。標準的な手法: 整数の範囲
MaxMind GeoLite2(および同様のデータベース)は、network を CIDR 文字列として、各範囲の開始/終了を整数として提供しています。整数の手法はコンパクトで、インデックスに適しています。
start_ip のインデックスが効率的な範囲スキャンを可能にします。制限は、IPv4 でしか動作しないことです。IPv6 には別のテーブル(VARBINARY(16) の範囲を持つ)が必要です。
VillageSQL の場合: INET による IPv4/IPv6 の統合
VillageSQL のINET 型は、IPv4 と IPv6 の両方のアドレスを自然な順序で保存するため、両方のファミリーに 1 つのテーブルを使えます。範囲チェックでは inet_compare() が BETWEEN の役割を果たします。
CIDR ネットワークで保存する(代替スキーマ)
GeoIP データが開始/終了のペアではなく CIDR ブロックを提供している場合は、ネットワーク列にCIDR を使い、サブネットのクエリで包含を解決します。
手法の選択
IPv4 のみで最大のクエリ速度が必要なら、
INT UNSIGNED + BETWEEN の手法に勝つのは困難です。IPv4 と IPv6 の両方を 1 つのテーブルで扱う必要があるスキーマでは、INET と inet_compare のほうが簡潔で、2 つの並行するテーブルを維持せずに済みます。
位置情報データソースの比較
クエリのスキーマは決定の半分に過ぎません。データソースが精度、鮮度、およびコストを決めます。一般的な選択肢の比較は次のとおりです。
国レベルの精度の数値はプロバイダーの自己申告であり、地域によって異なります。アジア太平洋とラテンアメリカのカバレッジは、すべてのソースで北米とヨーロッパより低い傾向があります。
どれを選ぶか: MaxMind GeoLite2 が標準的な出発点です。無料で、一度インポートするフラットファイルとして提供され、検索は外部依存なしに完全に MySQL の中で実行されます。本番環境で都市レベルの精度が必要なら、GeoIP2 Precision がアップグレードの道です。API ベースのソース(ip-api.com、ipinfo.io)は少量の利用には便利ですが、すべての検索に HTTP のレイテンシとレート制限への依存を加えます。
各手法を使う場面
GeoLite2 データのインポート
MaxMind GeoLite2(無料、登録が必要)は CSV ファイルを提供しています。範囲ベースのスキーマの場合は次のとおりです。.mmdb 形式と、Python、Node.js、Go などの言語向けの公式クライアントライブラリも提供しており、大量の検索を行うシナリオでは SQL の検索より高速です。
よくある質問
位置情報は MySQL とアプリケーションコードのどちらで行うべきですか?
大量の検索(すべての HTTP リクエスト)では、MaxMind の.mmdb リーダーライブラリを使ったアプリケーション層の位置情報のほうが高速です。メモリ内の二分探索で、SQL の往復がありません。SQL ベースの位置情報は、バッチ分析、レポートのクエリ、およびすでに MySQL で実行されているデータパイプラインに向いています。
GeoIP データベースを最新に保つにはどうすればよいですか?
MaxMind は GeoLite2 を毎週更新します。定期的なダウンロードと、位置情報テーブルのTRUNCATE + 再読み込みをスクリプト化してください。あるいは、MaxMind の mmdbinspect か更新スクリプトを使って差分更新を適用します。
MySQL での IP 位置情報はどのくらい正確ですか?
精度は MySQL のスキーマではなく、データソースだけで決まります。国レベルでは、MaxMind GeoLite2(無料)は IPv4 アドレスのおよそ 98% で正確です。都市レベルでは約 80% に下がります。より高い精度には、MaxMind の有料製品 GeoIP2 Precision が国で約 99.8%、都市で約 85〜90% に達します。完璧なデータベースはありません。精度は通常、モバイルネットワーク、VPN、および一部のアジア太平洋の範囲で低くなります。MySQL のクエリ手法は精度に影響しません。インポートしたデータが示すとおりの結果が得られます。MySQL はプラグインや外部 API なしで IP 位置情報を検索できますか?
はい。標準的な手法、つまりこのガイドが扱う手法は、GeoIP データベース(MaxMind GeoLite2 など)を整数の範囲として通常の MySQL テーブルにインポートします。検索はただの SQL のBETWEEN クエリです。プラグインも、外部 API も、クエリ時のネットワーク呼び出しもありません。唯一の依存は、MaxMind のフラットな CSV ファイルをインポートし、定期的に更新することです。VillageSQL の vsql_network_address 拡張機能は、より簡潔な IPv4/IPv6 の扱いのために INET 型を追加しますが、基本的な手法には必須ではありません。
位置情報とアクセスログを 1 つのクエリで結合できますか?
はい。それが GeoIP データを MySQL に置く主な理由の 1 つです。トラブルシューティング
関連項目
- MySQL での IP アドレスの保存 — 位置情報のクエリの前の効率的な IP の保存
- MySQL でのサブネットによる問い合わせ — 位置情報の基礎となる範囲ベースの IP 検索