在SQL Server中存储IPv4地址的最佳推荐数据类型是什么?
或者有人已经为它创建了用户SQL数据类型(.Net程序集)?
我不需要排序。
答案 0 :(得分:61)
将IPv4地址存储为binary
(4)最能代表它所代表的内容,并允许轻松进行子网掩码式查询。但是,如果您实际上是在文本表示之后,则需要进行转换。在这种情况下,您可能更喜欢字符串格式。
顺便说一句,如果以字符串形式存储,可能有用的SQL Server功能很少。PARSENAME
。不是为IP地址而设计的,但非常适合它们。以下调用将返回'14':
SELECT PARSENAME('123.234.23.14', 1)
(编号从右到左)。
答案 1 :(得分:26)
我通常只使用varchar(15)作为IPv4地址 - 但除非你填充零,否则对它们进行排序会很痛苦。
我过去也将它们存储为INT。 System.Net.IPAddress
有一个GetAddressBytes
方法,它将IP地址作为表示IP地址的4个字节的数组返回。您可以使用以下C#代码将IPAddress
转换为int
...
var ipAsInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);
我曾经使用过,因为我不得不做很多寻找欺骗地址,并希望索引尽可能小。尽可能快。然后将地址从int中拉回到.net中的IPAddress
对象中,使用GetBytes
上的BitConverter
方法将int作为字节数组。将该字节数组传递给带有字节数组的constructor的IPAddress
,然后以最初使用的IPAddress
结束。
var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));
答案 2 :(得分:18)
在接受的答案中关于此评论
除非你填充,否则对它们进行排序是一种痛苦 零。
这是SQL Server 2008的一个技巧(来自this book的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
答案 3 :(得分:4)
我最喜欢的articles之一谈到了为什么不应该使用正则表达式来解析IP地址。他们谈论的大部分内容都在解释为什么你应该非常小心IP地址的文本表示。我建议你在决定在你的数据库中使用什么数据类型之前阅读它,也可能是你的应用程序将要处理的任何数据类型(尽管文章是关于Perl编写的,它对任何语言都有用)。
我认为最终32位数据类型(或4种8位数据类型)将是最佳选择。
答案 4 :(得分:3)
IPV4?诠释?还是tinyint x 4?
这实际上取决于它是仅仅是存储和检索还是它将成为一个远程搜索标准。
答案 5 :(得分:3)
不要忘记IPv6 - 如果你需要存储它们,你需要更多的空间 - 与IPv4的32位相比,需要128位。
我会选择bigint,但你需要一些帮助代码才能翻译成人性化版本。
答案 6 :(得分:3)
最好的方法(当不需要对IP进行排序和其他控制时)将其存储为int ,将其存储为varchar等会比仅仅简单的无辜int更具性价比。
有一个属性IPAddress.Address
但它已经过时,我不知道为什么,因为如果你不需要对IP类进行排序或控制,最好的方法是将它存储为无符号整数(即最大值为0xffffffff
,等于十进制表示中的255.255.255.255
。
IPAddress类也有一个接受long参数的构造函数。
根据VS调试器可视化工具,该IPAddress类本身将其内部变量存储为一个数字(不是字节数组)。
详细了解在MS SQL Server中存储单元的变通方法:
答案 7 :(得分:3)
我在这里阅读了很多类似的问题,这个问题中没有一个回复提到其他人的答案:“对于IPv4地址,您可能希望将它们存储为无符号的int并使用INET_ATON ()和INET_NTOA()函数从其数值返回IP地址,反之亦然。“我认为这是我将要在我的数据库中使用的内容,除非我决定使用上面提到的php函数。
答案 8 :(得分:2)
为了节省空间,并且在处理值(匹配或与范围进行比较)时,我使用int
。 IP地址实际上只是一个32位的值。
对于一个只想存储值来查看它的简单解决方案,我使用varchar(15)
来存储IP地址的字符串表示。
答案 9 :(得分:1)
我已经成功制作了四个smallint(或者你喜欢的任何小整数数据类型)列 - 每个八位字节一个。然后,你可以制作一个视图,将它们一起粉碎为一个字符串(用于显示),或者然后你可以编写简单的操作符来确定谁在所有子网中等等。
它非常快(假设你做了正确的索引)并且还允许非常容易的查询(没有字符串操作!)。
答案 10 :(得分:0)
由于IP地址中有32位,您可以使用LONG来存储数值吗? 它不会像使用VARCHAR那样浪费太多空间,但是每次使用它之前都必须将其解码回IP,并且延迟和开销可能不值得。
答案 11 :(得分:0)
用于在MSSQL数据库中存储IPv4地址的最合适的数据类型是int
。唯一令人讨厌的是将它转换回用于显示/排序的点分表示法,因此我建议您创建一个可以自动执行此操作的视图。
答案 12 :(得分:-1)
我可能选择varchar
或char
。
并将大小设置为15。
答案 13 :(得分:-4)
引用this:
将IP地址存储在CHAR(15)列中。根据您存储的数据量,这可能非常浪费(为什么我们需要存储点?)。我
答案 14 :(得分:-4)
我是新手@ 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时才会这样。