web-dev-qa-db-ja.com

SQLサーバーにIPアドレスを保存するための最も適切なデータ型は何ですか?

SQLサーバーにIPv4アドレスを保存するための最も推奨されるデータ型は何ですか?

または、誰かが既にユーザーSQLデータ型(.Net Assembly)を作成している可能性がありますか?

ソートする必要はありません。

65
Shimmy

IPv4アドレスを binary (4)として保存することは、それが表すものに忠実であり、簡単なサブネットマスクスタイルのクエリを可能にします。ただし、実際にテキスト表現の後にいる場合は、変換の変換が必要です。その場合、文字列形式を好むかもしれません。

ちなみに、文字列として保存する場合に役立つかもしれない、あまり使用されないSQL Server関数は PARSENAME です。 IPアドレス用には設計されていませんが、IPアドレスに最適です。以下の呼び出しは「14」を返します。

SELECT PARSENAME('123.234.23.14', 1)

(番号は右から左です)。

61
David M

私は通常、IPv4アドレスにvarchar(15)を使用しますが、ゼロを埋めない限り、ソートするのは大変です。

また、過去にINTとして保存しました。 System.Net.IPAddress には GetAddressBytes メソッドがあり、IPアドレスを表す4バイトの配列としてIPアドレスを返します。次のC#コードを使用して、 IPAddressint...に変換できます。

var ipAsInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);

私はそれを使用していました。重複アドレスを多く検索する必要があり、インデックスをできる限り小さくて迅速にしたかったからです。次に、アドレスをintからプルして、.netの IPAddress オブジェクトに戻すには、 GetBytes intをバイト配列として取得する BitConverter のメソッド。そのバイト配列を constructor に渡し、 IPAddress がバイト配列を取得すると、 IPAddress 開始時。

var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));
26
Scott Ivey

受け入れられた答えのこのコメントについて

ゼロを埋めない限り、それらをソートするのは大変です。

SQL Server 2008のコツ( この本 のItzik Ben-Ganから)

with ip_addresses as
(
SELECT '131.33.2.201' AS ip_address UNION ALL
SELECT '2.12.4.4' AS ip_address UNION ALL
SELECT '131.33.2.202' AS ip_address UNION ALL
SELECT '2.12.4.169' AS ip_address UNION ALL
SELECT '131.107.2.201' AS ip_address 
)
select ip_address
from ip_addresses
ORDER  BY CAST('/' + ip_address + '/' AS hierarchyid)

返品

ip_address
-------------
2.12.4.4
2.12.4.169
131.33.2.201
131.33.2.202
131.107.2.201
18
Martin Smith

私のお気に入りの1つ articles では、IPアドレスの解析に正規表現を使用しない理由について説明しています。彼らが話していることのほとんどは、IPアドレスのテキスト表現に非常に注意する必要がある理由を本当に説明しています。データベースでどのデータ型を使用するかを決定する前にそれを読むことをお勧めします。おそらく、アプリの処理についても(おそらく記事はPerlについて書かれていますが、あらゆる言語に役立ちます)。

最終的には、32ビットデータ型(または4つの8ビットデータ型)が最良の選択だと思います。

4
rmeador

最善の方法(IPでの並べ替えやその他の制御が不要な場合)は、intとして保存します。varcharなどとして保存すると、パフォーマンスが大幅に低下します単純な無邪気な整数です。

プロパティがあります IPAddress.Address しかし、それは時代遅れです。IPクラスをソートしたり制御したりする必要がない場合、最良の方法は次のように保存することです。符号なし整数(10進表現で0xffffffffと等しい255.255.255.255の最大値を持つ).

また、IPAddressクラスには、長い引数を受け入れるコンストラクタがあります。

VSデバッガビジュアライザーによると、そのIPAddressクラス自体は、内部変数を1つの数値(バイト配列ではなく)として格納します。

MS SQL Serverにユニットを保存する回避策の詳細をご覧ください。

3
Shimmy

IPV4? int?またはtinyint x 4?

それは本当にそれが単なる保管と検索であるかどうか、あるいはそれが広範囲の検索基準になるかどうかに依存します。

3
Cade Roux

IPv6を忘れないでください-それらを格納する必要がある場合、より多くのスペースが必要です-IPv4の32と比較して128ビット。

私はbigintに行きますが、人間に優しいバージョンに変換するにはいくつかのヘルパーコードが必要になります。

3
Lee Atkinson

私はここで多くの同様の質問を読んでいますが、この1件の回答のいずれも、他の1件の回答に言及していません。 INET_NTOA()関数は、数値からIPアドレスを返します。逆も同様です。上記のphp関数を使用することを決定しない限り、これがdbで使用するものだと思います。

3
Bobby

スペース効率の良いストレージと、値が処理される(範囲と一致または比較される)ために、intを使用します。 IPアドレスは実際には32ビットの値です。

値を保存して表示するだけの簡単なソリューションでは、varchar(15)を使用してIPアドレスの文字列表現を保存します。

2
Guffa

4つのsmallint(または任意の小さい整数データ型)列(各オクテットに1つ)を作成することに成功しました。次に、文字列として表示するために文字列としてそれらを破壊するビューを作成するか、単純な演算子を作成して、誰がどのサブネットにいるかなどを判断できます。

これは非常に高速で(適切なインデックス作成を行う場合)、クエリも非常に簡単です(文字列操作は不要です!)。

1
Matt Rogish

IPアドレスには32ビットが含まれているので、LONGを使用して数値を保存できますか?
。それ。

0
SqlRyan

IPv4アドレスをMSSQLデータベースに保存するための最も適切なデータ型は、intです。唯一の厄介な点は、表示/並べ替えのためにドット表記に変換することです。したがって、これを自動化するビューを作成することをお勧めします。

0
Ian Kemp