Mysql 检查ipv6是否在范围内
我有maxmind的ipv6数据。这是我当前的表(带有示例数据): 使用,我可以创建Mysql 检查ipv6是否在范围内,mysql,mariadb,ipv6,Mysql,Mariadb,Ipv6,我有maxmind的ipv6数据。这是我当前的表(带有示例数据): 使用,我可以创建网络\u开始\u ip和网络\u最后一个\u ip列: +------------------+----------------------------------------+------------+ | network_start_ip | network_last_ip | geoname_id | +------------------+----------
网络\u开始\u ip
和网络\u最后一个\u ip
列:
+------------------+----------------------------------------+------------+
| network_start_ip | network_last_ip | geoname_id |
+------------------+----------------------------------------+------------+
| 2001:200:: | 2001:200:ffff:ffff:ffff:ffff:ffff:ffff | 123 |
| 2001:208:: | 2001:208:ffff:ffff:ffff:ffff:ffff:ffff | 4312 |
+------------------+----------------------------------------+------------+
我希望这样的方法会奏效(尽管它可能比其他方法慢):
那么,我错过了什么?另外,存储ipv6地址(范围)的最佳方式是什么
谢谢以下是我如何让它工作的:
network\u start\u ip
和network\u last\u ip
是VARBINARY(16)
INSERT INTO blocks
从块中选择INET6\u-ATON(b2.网络\u-start\u-ip)、INET6\u-ATON(b2.网络\u-last\u-ip)、b2.geoname\u-id\u-copy b2代码>
selectgeoname\u id fromblocks b
其中,b.network\u start\u ip和b.network\u last\u ip之间的INET6\u ATON('2a01:4ff:ffff:ffff::ffff')
HEX(…)
是不必要的,正如您在自我回答中所观察到的那样。也就是说,BINARY(16)
很乐意正确比较IPv6值
如果表中有无数行,您会发现查询是慢行的。这是因为没有索引能够始终帮助优化器。快速查询是可能的,但它需要去掉最后一个_ip列,并在表中填充任何缺少的范围。我用代码来讨论这个问题。@PaulSpiegel它不起作用,而且我更愿意避免字符串样式的比较,因为它们比较慢。
INET6\u ATON('2001:201:ffff:ffff:ffff:ffff:ffff')在INET6\u ATON(b.network\u start\u ip)和INET6\u ATON(b.network\u last\u ip)之间呢
?比较索引字符串比将字符串转换为数字/二进制更快。@PaulSpiegel也不起作用。这也不是:其中HEX(INET6_ATON('2001:201:ffff:ffff:ffff:ffff:ffff:ffff')位于HEX(INET6_ATON(b.network_start_ip))和HEX(INET6_ATON(b.network_last_ip))之间。
您正在检查的ip不在示例数据中的两个范围内。这个解决方案听起来不错,我也在使用这个数据集,这种方法是否也适用于IPv4?最后一个查询(选择geoname\u id…
)是否确保只返回一个结果?我刚刚测试了大约15个IPv6,每个测试只返回1个结果,但如果您能确认,我将不胜感激。谢谢
+------------------+----------------------------------------+------------+
| network_start_ip | network_last_ip | geoname_id |
+------------------+----------------------------------------+------------+
| 2001:200:: | 2001:200:ffff:ffff:ffff:ffff:ffff:ffff | 123 |
| 2001:208:: | 2001:208:ffff:ffff:ffff:ffff:ffff:ffff | 4312 |
+------------------+----------------------------------------+------------+
SELECT b.geoname_id FROM blocks b
WHERE HEX(INET6_ATON('2001:201:ffff:ffff:ffff:ffff:ffff:ffff')) BETWEEN HEX(b.network_start_ip) AND HEX(b.network_last_ip)