Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何存储和搜索IP地址_C#_Sql Server_Data Structures_Ip Address - Fatal编程技术网

C# 如何存储和搜索IP地址

C# 如何存储和搜索IP地址,c#,sql-server,data-structures,ip-address,C#,Sql Server,Data Structures,Ip Address,我有4个IP地址源,我想将它们存储在SQL Server中,并允许在排除列表中按国家/地区对范围进行分类,这些范围可以按原始国家/地区代码进行分类 为此我有两张桌子 IP地址范围 国家代码 我需要知道的是,如果此数据返回到客户端,然后缓存以进行快速查询,那么存储返回的数据以查询范围内的特定IP地址的最佳方式是什么。我想知道提供的IP地址是否在列表中 该列表位于数据库中的原因是为了便于存储 我想缓存然后在客户机上使用数据的原因是我听说在trie结构中搜索IP地址更快。所以,我想我需要从数据库中获取

我有4个IP地址源,我想将它们存储在SQL Server中,并允许在排除列表中按国家/地区对范围进行分类,这些范围可以按原始国家/地区代码进行分类

为此我有两张桌子

IP地址范围 国家代码

我需要知道的是,如果此数据返回到客户端,然后缓存以进行快速查询,那么存储返回的数据以查询范围内的特定IP地址的最佳方式是什么。我想知道提供的IP地址是否在列表中

该列表位于数据库中的原因是为了便于存储

我想缓存然后在客户机上使用数据的原因是我听说在trie结构中搜索IP地址更快。所以,我想我需要从数据库中获取列表,存储在缓存中,存储在一个可以快速搜索的结构中

A)存储地址的SQL结构和b)搜索IP地址的代码中的任何帮助

我知道有一个代码项目解决方案,它有一个用于搜索的代码算法,但不确定如何将其与存储方面结合起来


理想情况下,无需使用第三方库。代码必须在我们自己的服务器上。

IPv4地址可以存储为四字节无符号整数(C#中的uint)。IPv6地址可以是8字节无符号整数(C#中的ulong)。在SQL中创建适当宽度的列,然后检索它们并将它们存储在变量中。然后使用简单的整数数学检查所需的范围,假设这些范围实际上是连续的


一个更复杂的解决方案是创建一个IPAddress类,让您可以访问更熟悉的虚线四元结构,但在封面下,它会做与您在这里所做的完全相同的事情。

我从未尝试过这一点,所以请对我的答案持保留态度,但我认为trie实际上并不是您想要的,除非您打算存储要阻止的每个IP(与范围或子网/掩码相反)。我认为btree更合适,在这种情况下,只需继续使用常规数据库(许多数据库都是用btree或同样好的数据结构实现的)。我会将IP的4个字节分别存储在一个单独的列中,以帮助按“不在乎”值等于NULL的a/B/C类子网进行搜索,但没有理由不能将其存储为单个32位整数列,并对数字进行运算,以确定它应该属于哪个范围(在这种情况下,存储隐藏的值会稍微复杂一些).

假设您的IP地址是IPV4,您可以将它们存储在一个整数字段中。创建两个字段,一个用于范围的下限,另一个用于上限。然后确保对这些to字段进行索引。搜索值时,只需搜索值大于或等于下限,小于或等于l到上限。在尝试编写更复杂的程序之前,我会先做一些简单的实验,实际上不会给出明显更快的结果。

我已经按国家进行了筛选,与您描述的完全相同

但是,经过一段时间的实验,我发现SQL无法以高性能的方式完成。这就是为什么像(我正在使用的)这样的IP数据库提供了一个二进制数据库,它的速度要快得多,因为它针对这类数据进行了优化

他们甚至明确表示:

请注意,对CSV进行的查询 导入SQL数据库的数据可以 最多需要几秒钟。如果 性能是一个问题,二进制文件 格式更快,并且可以处理 每秒数千次查找

另外,他们甚至让你查询这个数据库

我在一个中等流量的生产网站上使用它,过滤每个请求,没有性能问题

IPv6地址可以是8字节 无符号整数(C#中的ulong)

IPv6地址为128位(16字节),而不是建议的8位。 我现在正在努力解决IP范围的这个问题


我希望尝试填充字符串或十六进制字符串,只需进行<和>比较只要将IPv4起始地址存储在正确的数据类型中,您就可以有效地进行比较。varchar(或其他字符串类型)不正确-您需要使用int

对于IPv4,将IP号码存储在一个足够大的无符号格式中,然后将其存储为INET_ATON格式(这很容易生成;我不确定如何在C#中生成,但这并不困难)

然后,通过安排数据库进行范围扫描,您可以轻松有效地查找IP地址属于哪个范围

通过使用LIMIT(或在MSSQL中选择TOP1),您可以让它在找到记录后停止

SELECT TOP 1 networkidorwhatever, IPNumber, IPNumberUpperBoundOrWhateverYouCallIt 
FROM networks 
WHERE IPNumber <= IPNUMBERTOQUERY ORDER BY IPNumber DESC 
选择前1名网络IDorwhater、IPNumber、IPNumberUpperBounder或您所呼叫的内容
来自网络

IPNumber通常情况下,对于IPv4,DBA会推荐4个tinyint字段,但您使用的是范围,这更适合于前面提供的整数存储解决方案。在这种情况下,您将存储该范围的起始IP地址和结束IP地址。然后进行比较很简单。

IPv需要16个字节6地址,而不是8地址。现在没有A/B/C子网。我们只使用官方原始数据源。查看MaxMind上的内容:“请注意,对导入到SQL数据库中的CSV数据进行查询可能需要几秒钟。如果性能有问题,二进制格式会更快,每秒可以处理数千次查找。”"。有一篇关于使用原始数据的代码项目文章和一种每秒产生大约500K次搜索的算法。这很好,而且我不会依赖第三方公司。但是,我需要存储数据的最佳方式,以便将数据拉入缓存以使用此算法。也许可以将算法更改为使用缓存数据,而不加载ra直接存档。我们只是不想