Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.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
Mysql 检查ipv6是否在范围内_Mysql_Mariadb_Ipv6 - Fatal编程技术网

Mysql 检查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 | +------------------+----------

我有maxmind的ipv6数据。这是我当前的表(带有示例数据):

使用,我可以创建
网络\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
  • 然后,为了检查IPv6地址是否在范围内,我只需要运行以下查询:
    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)