在MySQL数据库中存储多种IP类型的最佳方式是什么,例如:
- 单一IP(123.123.123.123)
- IP范围(123.123.123.1 - 123.123.123.121)
- IP块(123.123.123.1/20)
- IP类(123.123.123。*或123.123。。)
我正在考虑将所有范围/块/类转换为单个IP并使用ip2long存储它们以便更快地搜索到表中,但这将导致我还需要一个100万+数据库来减少/放大类或更改/删除IP块。
每次有人访问我的网站时都会访问此数据库(因此需要快速访问)。 有什么想法吗?
答案 0 :(得分:3)
本教程可以提供帮助:http://daipratt.co.uk/mysql-store-ip-address/
保存IPv4地址的最有效方法是使用INT字段(不是您所期望的VARCHAR)。你可以使用PHP的ip2long转换它们,然后使用MySQL的INET_NTOA函数或PHP的longtoip转换它们。
答案 1 :(得分:2)
类似的东西:
CREATE TABLE ip_ranges (
id INT UNSIGNED AUTO_INCREMENT,
ip_start INT UNSIGNED NOT NULL,
ip_end INT UNSIGNED DEFAULT NULL,
ip_subnet TINYINT UNSIGNED DEFAULT NULL,
ip_class ENUM('A', 'B', 'C') DEFAULT NULL
)
需要ip_start
且所有其他字段可以为NULL [单个IP规则]或其他字段可以设置:
ip_end
是范围[192.168.1.10至192.168.1.15]规范的结尾部分ip_subnet
是子网掩码[192.168.1.0/22] ip_class
是网络类,虽然逻辑上可以存储为/ 8,/ 16或/ 24子网。完全忽略ip_class
...
SELECT *
FROM ip_ranges
WHERE
$ipaddr BETWEEN ip_start AND ip_end
OR
$ipaddr BETWEEN
(ip_start &~ (POW(2,32-ip_subnet)-1)) AND
(ip_start | (POW(2,32-ip_subnet)-1))
应选择适用于$ipaddr
的任何规则。 [但我还没有测试过]
答案 2 :(得分:-1)
您可以将所有类型的地址存储为LineString(Point(-1,first_ip_iplong
),Point(+ 1,last_ip_iplong
)),为此字段添加索引并享受即时搜索(使用MBRIntersects几乎所有数据或记录都很重要。
可以找到更多信息here
请注意,这种做法会将您的代码紧密耦合在mysql中。