C# 如何存储和搜索IP地址
我有4个IP地址源,我想将它们存储在SQL Server中,并允许在排除列表中按国家/地区对范围进行分类,这些范围可以按原始国家/地区代码进行分类 为此我有两张桌子 IP地址范围 国家代码 我需要知道的是,如果此数据返回到客户端,然后缓存以进行快速查询,那么存储返回的数据以查询范围内的特定IP地址的最佳方式是什么。我想知道提供的IP地址是否在列表中 该列表位于数据库中的原因是为了便于存储 我想缓存然后在客户机上使用数据的原因是我听说在trie结构中搜索IP地址更快。所以,我想我需要从数据库中获取列表,存储在缓存中,存储在一个可以快速搜索的结构中 A)存储地址的SQL结构和b)搜索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地址更快。所以,我想我需要从数据库中获取
理想情况下,无需使用第三方库。代码必须在我们自己的服务器上。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直接存档。我们只是不想