如何在mysql中将二进制转换为整数?
Posted
技术标签:
【中文标题】如何在mysql中将二进制转换为整数?【英文标题】:How to convert binary to integer in mysql? 【发布时间】:2013-07-02 02:25:30 【问题描述】:把我的问题放在正确的角度:
我有一个 php 应用程序,它将用户的 IP 存储在 mysql 表中。
列类型为VARBINARY(16)
,应用使用PHP的inet_pton
形成二进制字符串。
这是一个典型 IP4 地址的字符串有 4 个字节。
如何从表格中检索这些 IP,并以人类可读的形式显示它们?
我目前的解决方案是:
select INET_NTOA(CONV(HEX(ip),16,10)) from operation_ip;
有没有更直接的方法?
尤其是CONV(HEX(x),16,10)
将4个字节变成整数的最简单方法(实际上我认为它甚至不是整数,而是看起来像整数的字符串)。
(我使用 VARBINARY(16)
,因为 PHP 的 inet_pton
可以返回 16 字节的 IPv6 地址。AFAIK MySQL 的 INET_NTOA
不支持 IPv6,但目前这不是我最关心的问题)。
【问题讨论】:
如果你想要一个更直接的形式,不要将IP地址转换为二进制以便将其存储在数据库中......或者同时使用地址的字符串和数据库中的二进制值. 【参考方案1】:MySQL 有很好的内置函数来处理这种情况:
INSERT INTO t(ip) VALUE (INET_ATON('1.2.3.4')); -- stores integer 16909060
SELECT INET_NTOA(ip) FROM t; -- returns string '1.2.3.4'
或者PHP方式:
$sql = 'INSERT INTO t(ip) VALUE (' . ip2long('1.2.3.4') . '))';
// ip2long('1.2.3.4') = 16909060
// reverse conversion: long2ip(16909060) returns '1.2.3.4'
【讨论】:
如果我理解正确,您的解决方案是使用 4 字节整数作为列的类型。不幸的是 IPv6 需要 16 字节,而 MySQL 不支持这么长的整数,这就是我使用 VARBINARY(16) 的原因。另一方面,在某些查询中,我 100% 确定结果只包含具有 IPv4 地址的行,在这种情况下,我想快速将 VARBINARY(16) 转换为(4 字节)INT。 我忽略了 IPv6 的问题,因为您写道“IPv6 (...) 不是我最关心的问题”。从 v5.6.3 开始,MySQL 的功能正是您所需要的:INET6_ATON()
和 INET6_NTOA()
。在那之前,你的方法可能是最好的方法。不过,我不会将 IPv4 和 IPv6 存储在同一列中,而是存储在不同的列中。以上是关于如何在mysql中将二进制转换为整数?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 elixir 中将二进制转换为 base10(十进制)整数
如何在JavaScript中将数字的二进制表示从字符串转换为整数?