sql >> データベース >  >> RDS >> PostgreSQL

IPから国を決定する-IPv6

    私は解決策を見つけたと信じています。これには、最初にデータを変更してから、入力をマッサージすることが含まれます。うまくいったのは次のとおりです。

    まず、セミコロン区切り文字を削除して、短縮せずにすべてのアドレスがいっぱいになるようにデータを変換する必要があります。私の質問に示されているサンプルデータは次のように変換されます:

     t_start                          | t_end                            | t_country_code
    ----------------------------------+----------------------------------+----------------
     00000000000000000000000000000000 | 00ffffffffffffffffffffffffffffff | ZZ
     01000000000000000000000000000000 | 01ffffffffffffffffffffffffffffff | ZZ
    ...
     20000000000000000000000000000000 | 2000ffffffffffffffffffffffffffff | ZZ
    ...
     20011200000000000000000000000000 | 20011200ffffffffffffffffffffffff | MX
    ...
    

    これがデータベースに保存されているものです。

    次のステップは、コードで受信したIPアドレスを同じ形式に変換することでした。これは、次のコードを使用してPHPで実行されます($ip_addressと仮定します) は着信IPv6アドレスです):

    $addr_bin = inet_pton($ip_address);                                                                                                              
    $bytes = unpack('n*', $addr_bin);
    $ip_address = implode('', array_map(function ($b) {return sprintf("%04x", $b); }, $bytes));
    

    変数$ip_adress たとえば、完全なIPv6アドレスが含まれます

    :: => 00000000000000000000000000000000
    2001:1200::ab => 200112000000000000000000000000ab
    

    など。

    これで、この完全なアドレスをデータベース内の範囲と簡単に比較できます。 IPv6アドレスを処理するために、データベースに2番目の関数を追加しました。これは次のようになります。

    CREATE OR REPLACE FUNCTION get_country_for_ipv6(character varying)
      RETURNS character varying AS
    $BODY$
    declare
        ip  ALIAS for $1;
        ccode   varchar;
    begin
        select into ccode t_country_code from ipv6_to_country where addr between n_from and n_to limit 1;
        if ccode is null then
            ccode := '';
        end if;
        return ccode;
    end;$BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    

    最後に、私のphpコードに、入力ip_addressに基づいていずれかのPostgres関数を呼び出すコードを追加しました。



    1. SQLクエリ-一部の結果を含めない方法

    2. 大したこと:SQL Server 2016 Service Pack 1

    3. EMR上のApacheSparkでPostgresqlJDBCソースを使用する

    4. 単一のMySQLクエリで条件が異なる複数のカウント