sql - 如何使用 php 在任何数据库中将 IP 地址(v4 或 v6)存储为 int?

标签 sql optimization ip-address

我需要以尽可能紧凑的方式存储 IP 地址,搜索不是问题。这还需要在使用任何数据库(MySQL、SQLite、Postgres 等)的 Windows、Linux 和 Mac 上兼容。

感谢 ip2long() PHP 中的 long2ip() 函数我可以将 IP4 地址转换为小的 int 字段而不是 varchar(15) 或其他任何内容。问题是我们正处于向 IP6 的过渡阶段,这意味着大多数现有的最佳实践都失败了——包括那些不适用于 IP6 的功能。此外,像 INET_ATON() 和 INET_NTOA() 这样的数据库特定函数在这里不是选项。

那么,您如何以适用于任何系统的方式将 IP 地址存储为 INT(或任何其他紧凑格式)呢?

编辑:
The thread Wrang-wrang 指出使用 inet_ntop() 和 inet_ptop() 来打包和解包 IP4 或 IP6。问题是它们只能在使用 PHP +5.1(这不是什么大问题)的 Linux/Mac 和使用 +5.3(是)的 Windows 上工作。

如果这不是问题,它们是否会替换每个数据库中推荐的 varbinary(16) 字段?

最佳答案

您只需要选择一种存储 128 位的方式:

::/96 — This is a 96-bit zero-value prefix originally known as IPv4-compatible addresses. This class of addresses were used to represent IPv4 addresses within an IPv6 transition technology. Such an IPv6 address has its first 96 bits set to zero, while its last 32 bits are the IPv4 address that is represented. The Internet Engineering Task Force (IETF) has deprecated the use of IPv4-compatible addresses with publication RFC 4291. The only remaining use of this address format is to represent an IPv4 address in a table or database with fixed size members that must also be able to store an IPv6 address.



(来自 http://en.wikipedia.org/wiki/IPv6)

我认为两个 BIGINT UNSIGNED 是存储它们的合理方式,但我想您可以使用二进制(字节数组)。

这个问题似乎已经在 Working with IPv6 Addresses in PHP 得到了回答。和 How to store IPv6-compatible address in a relational database

关于sql - 如何使用 php 在任何数据库中将 IP 地址(v4 或 v6)存储为 int?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1386930/

相关文章:

c++ - 使用保存的客户端 ip 地址将数据包从服务器发送到特定客户端?

SQL LIKE 特性-所有字符或所有数字

mysql - 使用 mysql COUNT(*)

c# - "Binding"Tcp套接字有什么意义?

c# - 优化 Linq : IN operator with large data

java - 优化 Java 中的递归函数

python - 通过IP和掩码计算广播

sql - 如何通过 group by 和子查询计算来选择数据?

sql - 尝试创建函数时 DECLARE 部分中的“"VARCHAR"处或附近的语法错误”

php - 在一个字段中存储多个值