【发布时间】:2010-11-05 13:17:33
【问题描述】:
在 SQL Server 中存储 IPv4 地址时最推荐的数据类型应该是什么?
或者也许有人已经为它创建了一个用户 SQL 数据类型(.Net 程序集)?
我不需要排序。
【问题讨论】:
-
不要忘记 IPv6 现在就在这里。今天在解析网络服务器日志时,有时会遇到一个 v6 地址...
标签: sql sql-server types ip-address ipv4
在 SQL Server 中存储 IPv4 地址时最推荐的数据类型应该是什么?
或者也许有人已经为它创建了一个用户 SQL 数据类型(.Net 程序集)?
我不需要排序。
【问题讨论】:
标签: sql sql-server types ip-address ipv4
引用this:
将 IP 地址存储在 CHAR(15) 列中。根据您存储的数据量,这可能会非常浪费(为什么我们需要存储点?)。我
【讨论】:
我通常只对 IPv4 地址使用 varchar(15) - 但是对它们进行排序很麻烦,除非你填充零。
我过去也将它们存储为 INT。 System.Net.IPAddress 有一个 GetAddressBytes 方法,它将 IP 地址作为代表 IP 地址的 4 个字节的数组返回。您可以使用以下 C# 代码将 IPAddress 转换为 int...
var ipAsInt = BitConverter.ToInt32(ip.GetAddressBytes(), 0);
我之所以使用它,是因为我必须做大量的重复地址搜索,并且希望索引尽可能小且快。然后要将地址从 int 中拉回到 .net 中的 IPAddress 对象中,请使用 BitConverter 上的 GetBytes 方法将 int 作为字节数组获取。将该字节数组传递给IPAddress 的constructor,它接受一个字节数组,最后您将返回您开始使用的IPAddress。
var myIp = new IPAddress(BitConverter.GetBytes(ipAsInt));
【讨论】:
hierarchyid 来帮助解决此问题 stackoverflow.com/questions/1038950/…
IPV4?诠释?还是 tinyint x 4?
这真的取决于它是否只是存储和检索,或者它是否将成为一个范围搜索条件。
【讨论】:
【讨论】:
由于IP地址有32位,你可以用LONG来存储数值吗?
它不会像使用 VARCHAR 那样浪费空间,但是每次使用它之前,您都必须将其解码回 IP,而且延迟和开销可能不值得。
【讨论】:
我在制作四个 smallint(或任何您喜欢的小整数数据类型)列方面取得了一些成功——每个八位字节一个。然后,您可以创建一个视图,将它们组合成一个字符字符串(用于显示),或者您可以编写简单的运算符来确定谁在哪个子网中等等。
它非常快(前提是您进行了正确的索引),并且还允许非常简单的查询(没有字符串操作!)。
【讨论】:
不要忘记 IPv6 - 如果需要存储它们,则需要更多空间 - 128 位与 IPv4 的 32 位相比。
我会选择 bigint,不过您需要一些帮助代码来转换为人类友好的版本。
【讨论】:
对于节省空间的存储以及要处理值(匹配或与范围比较)时,我使用int。 IP 地址实际上只是一个 32 位值。
对于您只想存储值以查看它的简单解决方案,我使用varchar(15) 来存储 IP 地址的字符串表示形式。
【讨论】:
我最喜欢的articles 之一谈到了为什么不应该使用正则表达式来解析 IP 地址。他们谈论的大部分内容实际上是在解释为什么您应该非常小心 IP 地址的文本表示。我建议您在决定在数据库中使用什么数据类型之前阅读它,并且可能还考虑您的应用程序将要执行的任何处理(即使这篇文章是关于 Perl 的,它对任何语言都很有用)。
我认为最终一个 32 位数据类型(或四个 8 位数据类型)将是最好的选择。
【讨论】:
关于已接受答案中的此评论
除非你填充,否则对它们进行排序是一件很痛苦的事情 零。
这是 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
【讨论】:
这取决于你的目的。如果您想要最好的存储和可能的性能,并且在大多数情况下,将其存储为 int,将其存储为 varchar 等会比简单的无辜 int 花费更多的性能。
您也可以通过将搜索参数设置为所需的 int 来按 IP 进行搜索。
有一个属性IPAddress.Address 但它已经过时了,我不知道为什么,因为如果您不需要对 IP 类进行排序或控制,最好的方法是将其存储为无符号整数(具有0xffffffff 的最大值等于十进制表示的 255.255.255.255。
使用 EF Core,您可以使用转换器将其自动转换为IPAddress。
IPAddress 类也有一个接受长参数的构造函数。
根据 VS 调试器可视化工具,IPAddress 类本身将其内部变量存储为一个数字(不是字节数组)。
阅读有关在 MS SQL Server 中存储单元的解决方法的更多信息:
【讨论】:
int。
我在这里阅读了很多类似的问题,但没有一个回复提到其他人的第一答案:“对于 IPv4 地址,您可能希望将它们存储为 int unsigned 并使用 INET_ATON () 和 INET_NTOA() 函数从其数值返回 IP 地址,反之亦然。”我想这就是我要在我的数据库中使用的东西,除非我决定使用上面提到的 php 函数。
【讨论】:
我是 @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 的情况下。
【讨论】: