66

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

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

並べ替えは必要ありません。

4

13 に答える 13

62

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

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

SELECT PARSENAME('123.234.23.14', 1)

(番号は右から左)。

于 2009-06-24T15:10:29.590 に答える
27

私は通常、IPv4 アドレスに varchar(15) を使用しますが、ゼロを埋め込まない限り、それらを並べ替えるのは面倒です。

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

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

重複したアドレスを多く検索する必要があり、インデックスをできるだけ小さく高速にしたかったため、これを使用していました。次に、アドレスを int からIPAddress.net のオブジェクトに戻すには、 GetByteson メソッドを使用しBitConverterて int をバイト配列として取得します。そのバイト配列をバイト配列を取るコンストラクターに渡すと、元の に戻ります。IPAddressIPAddress

var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));
于 2009-06-24T15:07:15.837 に答える
19

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

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

これは 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
于 2010-08-09T15:42:37.433 に答える
8

スペース効率の良いストレージと、値を処理する (範囲と照合または比較する) 場合は、int. IP アドレスは実際には 32 ビット値です。

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

于 2009-06-24T15:18:27.170 に答える
3

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

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

于 2009-06-24T15:18:41.163 に答える
3

IPv6 のことを忘れないでください。それらを保存する必要がある場合は、さらに多くの容量が必要です。128 ビットは、IPv4 の 32 ビットに比べて大きいです。

私はbigintを選びますが、人間に優しいバージョンに変換するにはヘルパーコードが必要です.

于 2009-06-24T15:16:40.777 に答える
3

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

于 2010-08-13T03:01:18.930 に答える
2

それはあなたの目的によります。最高のストレージとおそらくパフォーマンスも必要な場合は、ほとんどの場合、 intとして保存し、 varchar などとして保存すると、単純な無実の int よりもパフォーマンスが高くなります。
検索パラメーターを目的の int にすることで、IP で検索することもできます。

プロパティはありますIPAddress.Addressが、廃止されました。理由はわかりません。並べ替えや IP クラスの制御が必要ない場合は、符号なし整数として格納するのが最善の方法です (最大値0xffffffff255.255.255.255EF
Core を使用すると、コンバーターを使用して との間で自動的に変換することができますIPAddress

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

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

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

于 2010-08-09T23:47:44.347 に答える
2

IPV4? 整数?またはtinyint x 4?

それが単なる保管と検索なのか、それとも範囲検索基準になるのかによって大きく異なります。

于 2009-06-24T15:07:30.250 に答える
0

IP アドレスは 32 ビットなので、LONG を使用して数値を格納できますか?
VARCHARを使用するほどスペースを浪費することはありませんが、使用する前に毎回IPにデコードする必要があり、コストがかかる遅延とオーバーヘッドは価値がないかもしれません.

于 2009-06-24T15:11:36.983 に答える
0

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

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

于 2009-06-24T15:15:56.990 に答える
-5

これを引用:

IP アドレスを CHAR(15) 列に格納します。保存するデータの量によっては、これは非常に無駄になる可能性があります (なぜドットを保存する必要があるのでしょうか?)。私

于 2009-06-24T15:06:48.317 に答える
-5

私は初心者 @ php,sql ですが、SQL db に何かを格納する最速の方法は、それを int 値に変換して int として保存することだと思います。

私はphpで関数を使用しました -

function ip_convert() {
    $ip = $_SERVER['REMOTE_ADDR'];
    $intip = str_replace(".","0",$ip);
    return $intip;
}

そして、すべてのドットをゼロに置き換えます。次に、SQLからこのIPを使用する必要がある場合.. if($ip == ip_convert())

ただし、これは PHP を使用している場合に限られます。

于 2014-06-15T17:35:26.833 に答える