VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
INET_ATON() を使ったビット演算です。VillageSQL の INET 型はネットワーク関数を提供し、同じクエリをより読みやすくし、IPv4 と IPv6 の両方で機能させます。
標準的なアプローチ: ビット単位の範囲チェック
IPv4 の場合、INET_ATON() はアドレスを符号なし 32 ビット整数に変換します。サブネットへの所属チェックはビット単位の AND です。(ip & netmask) == network_address であれば、その IP はサブネット内にあります。
BETWEEN のアプローチは読みやすいです。ビット演算の形式は、サブネットのパラメータが変数である場合に組み合わせやすくなります。
どちらのアプローチも IPv6 では機能しません。INET_ATON() は IPv4 しか扱いません。
VillageSQL の場合: INET 列に対するネットワーク関数
VillageSQL のvsql_network_address 拡張機能は、「このアドレスはあのサブネットの中にあるか」に直接答える包含述語、つまり inet_contained_by()、inet_contains()、および inet_overlaps() を提供します。加えて、チェックを手で組み立てるための inet_network()、inet_set_masklen()、および inet_compare() も提供します。これらはすべて、IPv4 と IPv6 の両方の INET 列で機能します。
サブネットの包含クエリ
保存された IP が特定のサブネットに属するかを確認するには、アドレスをサブネットのプレフィックス長でマスクし、その結果を対象のネットワークと比較します。包含述語
この拡張機能は、PostgreSQL の 5 つの包含述語を関数として提供します。これらは 2 つのINET 値を受け取り、1、0、または NULL を返します。
上のサブネットクエリは、1 回の呼び出しになります。
192.168.1.5/24 と 192.168.1.9/24 は同じネットワークであり、厳密な形式はこれらに対して
0 を返し、_or_equals の形式は 1 を返します。
ファミリーの異なる 2 つのアドレスが一致することはありません。IPv4 の値を IPv6 の値と比較すると、
エラーを発生させるのではなく 0 を返します。これは PostgreSQL と同じです。
両方の引数は INET でなければなりません。CIDR 値は強制変換されません。
inet_from_string() を使ってください。これらの
関数は vsql_network_address 0.0.5 で追加されました。
inet_compare による範囲ベースの包含
行ごとにネットワークを再計算しない代替手段です。ブロードキャストアドレスが分かっている場合に便利です。IPv6 のサブネットクエリ(同じパターン)
同じinet_network() のアプローチが、何も変更せずに IPv6 でも機能します。
ネットワークテーブルのパターン
よくある用途です。許可された CIDR を持つnetworks テーブルがあり、受信した IP がそのいずれかに含まれるかを確認します。
標準と VillageSQL の比較
よくある質問
VillageSQL には PostgreSQL の << 包含演算子がありますか?
その動作は、演算子ではなく関数として存在します。<< には inet_contained_by()、>> には inet_contains()、<<= と >>= には _or_equals の各バリアント、&& には inet_overlaps() です。包含述語を参照してください。
サブネットクエリはインデックスを使いますか?
cidr_to_string(inet_network(inet_set_masklen(...))) のパターンはインデックススキャンを使いません。すべての行に対してネットワークアドレスを再計算します。大きなテーブルでは、inet_compare の範囲アプローチのほうがインデックスを活用しやすくなります。クエリを ip_address 列に対する範囲として表現するためです。
サブネットを保存して、同時に包含をクエリできますか?
はい。ホストアドレスとサブネットの両方をINET 列に保存し、inet_contained_by(host_ip, subnet) で比較します。サブネットが CIDR 列にある場合は、先に変換してください。包含述語は両側に INET を取り、CIDR を強制変換しません。
トラブルシューティング
関連項目
- MySQL での IP アドレスの保存 — サブネットクエリで使う INET 型
- MySQL での IPv6 の保存 — INET を使えばサブネットクエリは IPv6 でも同じように機能する
- MySQL での IP による位置情報の検索 — サブネットを超えて IP データをさらに活用する