【问题标题】:Mysql compare ip addressmysql比较ip地址
【发布时间】:2021-01-10 07:34:18
【问题描述】:

我有一个存储 IP 地址及其位置的数据库。我只在表中存储了IP地址的前3个网络ID。

+-------------------+-----------------+
|ip_address(varchar)|location(varchar)|
+-------------------+-----------------+
| 1.2.3             |       A         |
| 1.2.4             |       A         |
| 1.22.33           |       B         |
| 1.100.99          |       C         |
+-------------------+-----------------+

假设我的 IP 是 1.2.3.4 或其他 1.100.99.20,我如何将 IP 与表格进行比较以获取位置?

【问题讨论】:

    标签: mysql ip-address


    【解决方案1】:

    这是一个应该可以工作并且也可以索引的解决方案:

    SELECT location
    FROM WhateverTable
    WHERE ip_address = SUBSTRING_INDEX(?, '.', 3)
    

    ? 参数提供值“1.100.99.20”。


    您应该知道您存储的 IP 地址具有误导性。官方 IP 地址格式允许缩短字符串,但不是您可能想的那样。例如:

    mysql> select inet_ntoa(inet_aton('1.100.99'));
    +----------------------------------+
    | inet_ntoa(inet_aton('1.100.99')) |
    +----------------------------------+
    | 1.100.0.99                       |
    +----------------------------------+
    

    我打赌你会期望它返回 1.100.99.0。

    【讨论】:

    • 谢谢你的回答..上面的IP我只是随机输入..不要介意。
    【解决方案2】:
    SELECT location
    FROM address_table
    WHERE AND INET_ATON(@my_address) BETWEEN INET_ATON(CONCAT(ip_address, '.0'))
                                         AND INET_ATON(CONCAT(ip_address, '.255'))
    

    当然这个查询即使存在也不能使用索引……


    我建议您不要修剪 ip_address 列值。最好的方法是以数字形式将未修剪的子网地址而是 IP 地址范围(从 - 到)存储在两列中 - 这可以防止拼写错误(并减少行数)。如果需要,您可以使用带有字符串表示的 IP 地址范围的生成列。

    【讨论】:

      【解决方案3】:

      这不是最实用的方法,但确实有效。

      我们可以使用LOCATE() 函数,它接受两个参数,分别代表您要查找的子字符串和要在其中查找它的字符串。 (定位函数参考:https://www.oreilly.com/library/view/mysql-cookbook/0596001452/ch04s06.html

      要传递的第一个参数是 ip_address 列,第二个参数是您的 IP(例如:1.2.3.4)。

      SELECT location
      FROM that_table
      WHERE LOCATE(ip_address, 'the_ip') >= 1;
      

      如果我们得到大于或等于 1 的数字,则意味着它找到了匹配项,因此该 ip 将有一个位置。

      【讨论】:

      • 您遗漏了一个重要的细节。如果他与IP地址进行比较,则不会匹配。 OP 声明该表仅包含第一个 3 个八位字节。您的答案应该反映了一种从 IP 地址中剥离最后一个八位字节的方法。
      • 更改了答案,没有注意到那个细节。它现在应该可以工作了。
      • 谢谢你..它的作品。我以前从未尝试过 locate() 函数。
      猜你喜欢
      • 2010-11-04
      • 2012-08-26
      • 2014-04-29
      • 1970-01-01
      • 2014-08-04
      • 2014-03-06
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多