web-dev-qa-db-ja.com

IPアドレスの保存

すべての登録ユーザーのIPアドレスをデータベースに保存する必要があります。このような列には何文字を宣言する必要があるのでしょうか。

IPv6もサポートする必要がありますか?その場合、IPアドレスの最大長はいくつですか?

26
Cleankod

文字列として保存しないでください。 _int unsigned_列を使用して、それぞれINET_ATON()およびINET_NTOA()で格納/取得します。 AFAIK mysqlは、ipv6のINET_ *をサポートしていません。

[〜#〜] edit [〜#〜]コメントどおり

組み込み関数を使用してIPを整数に変換したり、整数から変換したりする(そしてこれらの整数をデータベースに格納する)と、これらのIPが自動的に検証されるという副作用があります。 IPをVARCHAR(16)として保存するとします。カスタム検証を使用して、無効なIP(例として999.999.999.999)を保存しないようにする必要があります。 INET_ *関数がそれを処理します。

27
Mr Shunz

PostgreSQLへの移行と INETまたはCIDR データ型の使用をお勧めします。

CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
 test_id | address  
---------+----------
       1 | 1.2.3.4
       2 | a:b::c:d
7
jkj

IPv6の検討を開始する時期です。 MySQLには、IPv6アドレスをバイナリ形式に変換するメソッドがありません。 40文字の文字列は、通常のIPv6アドレスを処理します。 40文字を超える可能性のある形式がありますが、実際には起こりそうにないものと考えます。

そのときのサイズから、最大7つのセパレータ文字を含む4つの文字グループが8つあるという情報を計算できます。異常な形式は、最後の2つのグループをIPv4形式のアドレスに置き換えます。アドレス圧縮を使用しない場合、最後の9文字が最大15文字に置き換えられます。

ブロックを保存する場合、ブロックサイズの表示には、IPv4に必要な3文字ではなく4文字を使用できます。

取得するフォーマットが一貫していることを確認する必要がありますが、私が見たすべてのソフトウェアは、アドレスの一貫したフォーマットを提供します。

6
BillThor

これは、MySQLメーリングリストの1つで行われた最良の回答です。読み取り IPアドレスを保存するのに最適なフィールドタイプ...

簡単に言うと、INT(10)UNSIGNEDを使用することです。

  1. メモリ使用量が少ない(4バイトのみ)
  2. 特に訪問者の出身国を探す場合は、IP範囲の並べ替えと検索に最適です。

したがって、192.168.10.50を使用します。

(192 * 2 ^ 24)+(168 * 2 ^ 16)+(10 * 2 ^ 8)+ 50 = 3232238130(結果は192.168.10.50)

MySQLでは、SELECT INET_ATON('192.168.10.50');を直接使用して_3232238130_を取得できます。

または

192 +(168 * 2 ^ 8)+(10 * 2 ^ 16)+(50 * 2 ^ 24)= 839559360(後方、結果は50.10.168.192)

MySQLでは、SELECT INET_NTOA(3232238130);を直接使用して_192.168.10.50_を取得できます。

4
Eye

MySQL v5.6.3以降、IPv4およびIPv6アドレスを処理する_INET6_ATON_および_INET6_NOTA_のサポートが追加されました。しかし、彼らはもはやそれを整数として保存しません。 IPv6はvarbinary(16)を返し、IPv4はvarbinary(4)を返します。

http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton

2
Vizjerai

最大15文字まで格納できます。 VARCHAR(15)は16バイトなので使用しないでください(最初のバイトは文字列の長さを管理するため、検索と格納に時間がかかります)。 IPアドレスのようなものでは常にCHAR(15)を使用します。

1
RolandoMySQLDBA

回答にコメントできません。 それに関する質問 がstackoverflowにあります。そして、私は選択した答えに完全に同意します。2xBIGINTを使用することは、おそらく現在ipv6に最適な方法です。

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

このbigintにipv4を格納することも可能です-それらの1つをNULLとしてマークするか、V4COMPATフォーマットを使用します

0
rvs