web-dev-qa-db-ja.com

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

それ、どうやったら出来るの?

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

それにはどのアプローチが最適でしょうか? _2xBIGINT_? CHAR(16)バイナリストレージ? CHAR(39) for text storage? _8xSMALLINT_は専用テーブルにありますか?

あなたは何をお勧めします?

34
azerole

MySQLのright答えがまだネイティブではIPv6アドレス形式をサポートしていないため( " WL#798:MySQL IPv6のサポート "は、それがMySQL v6.0に含まれることを示唆しており、現在のドキュメントではサポートされていません)。

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

21
Alnitak

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つの列にすべてを保持して印刷できます。うまく。

6
ʞɔıu

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

6
Steve-o

私は完全な39文字の「標準」印刷フォーマットを使います:-

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

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

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

4
James Anderson

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

1

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

1
hgl