简体   繁体   English

Mysql比较ip地址

[英]Mysql compare ip address

I have a database which stores IP address with its location.我有一个存储 IP 地址及其位置的数据库。 I only store the first 3 network ID of IP address in the table.我只在表中存储 IP 地址的前 3 个网络 ID。

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

Let say my IP is 1.2.3.4 or others 1.100.99.20, how do I compare the IP with the table to get the location?假设我的 IP 是 1.2.3.4 或其他 1.100.99.20,我如何将 IP 与表进行比较以获取位置?

Here's a solution that should work and be indexable too:这是一个应该有效并且也可以索引的解决方案:

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

Where you supply the value '1.100.99.20' for the ?您在哪里为? parameter.范围。


You should be aware that the IP addresses you store are misleading.您应该知道您存储的 IP 地址具有误导性。 The official IP address format permits shortened strings, but not the way you probably think.官方 IP 地址格式允许缩短字符串,但不是您想的那样。 For example:例如:

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

I bet you would expect it to return 1.100.99.0.我打赌你会期望它返回 1.100.99.0。

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'))

Of course this query cannot use the index even if it exists...当然这个查询不能使用索引,即使它存在......


I recommend you do NOT trim the ip_address column value.我建议您不要修剪 ip_address 列值。 And the best way is to store not trimmed subnet address but IP addresses range (from - till) in two columns in numeric form - this protects against typos (and decreases rows amount).最好的方法是以数字形式将未修剪的子网地址而是 IP 地址范围(从 - 到)存储在两列中 - 这可以防止拼写错误(并减少行数)。 You may use generated columns with string representation of IP addresses ranges if needed.如果需要,您可以使用带有 IP 地址范围字符串表示的生成列。

This is not the most pragmatic approach, but it does the work.这不是最实用的方法,但它确实有效。

We could use the LOCATE() function, which takes two arguments representing the substring that you're looking for and the string in which to look for it.我们可以使用LOCATE()函数,它接受两个参数,分别代表您要查找的子字符串和要在其中查找的字符串。 (locate function reference: https://www.oreilly.com/library/view/mysql-cookbook/0596001452/ch04s06.html ) (定位函数参考: https : //www.oreilly.com/library/view/mysql-cookbook/0596001452/ch04s06.html

The first argument that is going to be passed is the column ip_address and the second argument will be your IP (eg: 1.2.3.4).要传递的第一个参数是列ip_address ,第二个参数将是您的 IP(例如:1.2.3.4)。

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

If we get the number greater or equal than one, it means that it found a match, therefore that ip is going to have a location.如果我们得到的数字大于或等于 1,则意味着它找到了匹配项,因此该 ip 将有一个位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM