リレーショナルデータベースにIPv6互換アドレスを保存する方法

StackOverflow https://stackoverflow.com/questions/420680

  •  05-07-2019
  •  | 
  •  

質問

どうすればいいですか?

現在、IPv6は使用されませんが、IPv6に対応するようにアプリケーションを設計する必要があります。 IPアドレスとCIDRブロック(BGP NLRIでもこれは別の話です)をMySQLデータベースに保存する必要があります。私は常にIPv4にINT + masklenにTINYINTを使用しましたが、IPv6は128ビットです。

そのためにはどのアプローチが最適ですか? 2xBIGINT ?バイナリストレージ用の CHAR(16)?テキストストレージ用の CHAR(39)専用テーブルに 8xSMALLINT がありますか?

何をお勧めしますか?

役に立ちましたか?

解決

MySQLがネイティブにIPv6アドレス形式をまだサポートしていないことを考えると、正しい答えがどれなのかわかりません(" WL#798:MySQL IPv6のサポート"は、MySQL v6.0にあることを示唆していますが、現在のドキュメントにはありませんtバックアップします)。

ただし、あなたが提案したもののうち、2 * BIGINTに行くことをお勧めしますが、それらが署名されていないことを確認してください。 IPv6の/ 64アドレス境界には(/ 64が最小のネットブロックサイズであるため)それとうまく調和する、一種の自然な分割があります。

他のヒント

スコープIDを含むIPv6アドレスの最大長は、標準CヘッダーのINET6_ADDRSTRLENで定義されているように46バイトです。インターネットを使用する場合は、ゾーン識別子(%10、# eth0など)、ただし、 getaddrinfo が予想より長い結果を返す場合は注意してください。

char(16)を使用する場合は、代わりにbinary(16)を使用してください。 binary(n)には、照合または文字セットの概念がありません(または、文字セット/照合が 'binary'であるchar(n)です)。 mysqlのcharのデフォルトはlatin1_swedish_ciです。これは、latin1の有効なコードポイントであるバイト値の大文字と小文字を区別しないソートと比較を試行することを意味します。これにより、あらゆる予期しない問題が発生します。

別のオプションは、10進数(39、0)ゼロフィル符号なしを使用することで、2つのbigint(10進数はmysqlの現在のバージョンでは9桁ごとに4バイトを使用します)ほど効率的ではありませんが、すべてを1つに保つことができます列に並べて印刷します。

39文字の「標準」をすべて使用します。印刷フォーマット:-

"2001:0db8:85a3:0000:0000:8a2e:0370:7334"

40、ヌルターミネータ付き。

これは* nixコマンドラインツールで使用される形式であり、IPV6アドレスの形式はnormaly(?)で報告されます。

バイナリが意味をなすプログラムでIPアドレスが使用されますか?それとも、テキスト表現を保存する方が良いでしょうか?また、IPv6では、一般にアドレスを使用する可能性は低く、ホスト名を使用する可能性が高くなります。それが関連するかどうかは、一部アプリケーションによって異なります。 CHAR(16)は悪い選択です。 charは文字データ用であり、IPv6アドレスで一般的なゼロバイトの大きなストリームは好みません。 2 x BIGINTは不快です-2つのフィールドは実際には1つです(プラスの値はビッグエンディアンまたはリトルエンディアンに格納されていますか?)。固定サイズのBINARYタイプを使用したか、それが利用できない場合はBLOBタイプを使用しました。

最長のプレフィックス一致のプロジェクトで作業しているため、IPv4アドレスのアドレスを4つの整数に分離します。うまくいきます。これをIPv6アドレスに拡張します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top