正如“ipv6-capable inet_aton and inet_ntoa functions needed”中所要求的那样,目前没有用于存储IPv6地址的MySQL函数。什么是用于存储/插入的推荐数据类型/功能? (我不打算将它们存储为字符串)。我也不想将IPv6地址分成2个INT。
答案 0 :(得分:79)
怎么样:
BINARY(16)
这应该足够有效。
目前没有在MySQL服务器中将文本IPv6地址从/转换为二进制文件的功能,如错误报告中所述。您需要在应用程序中执行此操作,或者可能在MySQL服务器中创建UDF(用户定义函数)来执行此操作。
<强>更新强>
MySQL 5.6.3支持IPv6地址,请参阅以下内容:“INET6_ATON(expr)”。
我之前建议的数据类型为VARBINARY(16)
而不是BINARY(16)
。唯一的原因是MySQL功能适用于IPv6和IPv4地址。 BINARY(16)
适用于仅存储IPv6地址并保存一个字节。处理IPv6和IPv4地址时应使用VARBINARY(16)
。
旧版MySQL和MariaDB的实现,请参阅以下内容:“EXTENDING MYSQL 5 WITH IPV6 FUNCTIONS”。
答案 1 :(得分:6)
没有人发布完整的工作答案(许多示例使用Windows ::1
,这些 可能会误导实时(或#34;生产&#34;)环境)任何地方(至少我能找到)所以这里是:
INSERT
。SELECT
查询您将能够echo
将IPv6 IP地址返回给客户端。我将所有列名更改为ipv6
,以反映他们正确支持IPv6(这样可以保持旧列ip
完好无损)。可以在ip
列中存储ipv6
列,然后在您确定转换有效后再点击ip
列;当我真的有时间时,我会将其添加到这篇文章中。
IPv6数据类型
正如已经提到的那样VARBINARY 16
是一种理想的方式,直到AMD用128位CPU祝福我们并更新数据库以支持128位整数(我说得对吗?)。 IPv6是128位,而不是64位。
CREATE TABLE `example`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ipv6` VARBINARY(16) NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_unicode_520_ci'
ENGINE=InnoDB;
IPv6 INSERT查询
我们显然需要在SELECT
之前存储IPv6 IP地址;这是 PHP / SQL 代码:
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query1 = "INSERT INTO example (ipv6) VALUES (INET6_ATON('$ipv6'));";
IPv6 SELECT查询
PHP / SQL 代码:
$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329');
$query2 = "SELECT INET6_NTOA(ipv6) AS ipv6 FROM example WHERE ipv6=INET6_ATON('$ipv6');";
这将返回fe80::202:b3ff:fe1e:8329
;不,不是完整的IPv6(FE80:0000:0000:0000:0202:B3FF:FE1E:8329
),它是一个浓缩/速记版本。有代码使它成为正式的完整版本,但这是为了节省自己和其他人的时间,因为这个 Q / A是一个不断出现的。
重要提示,只是因为某些 IPv6地址看起来就像他们适合bigint
一样不是意味着两分钟之后,拥有更大IPv6地址的人不会停下来并造成严重破坏。
希望这可以使一些人免于打开另外两打标签的疯狂。当我将来有时间时,我会添加额外的PHP代码,将浓缩的IPv6扩展为完整的正式格式。
<强>疑难解答强>
如果出于某种原因存储和/或检索IPv6地址对您不起作用,那么请自己获取Advanced Find and Replace的副本(在Wine中比在本地grep
中更快地运行;);使用此主要来查找,而不是替换。确保您的软件中的代码一致。
$ip
变量必须转换为$ipv6
,以便您知道自己已经覆盖了这一点。)
:inet_pton(
函数的所有实例并将其删除。inet_ntop(
函数的所有实例并将其删除。INET_ATON(
函数的所有实例并将其删除。INET_NTOA(
函数的所有实例并将其删除。$ipv6
的所有实例,并确保所有IP-IN-TO-SQL实例都使用INET6_ATON('$ipv6')
,并确保IP-FROM-SQL使用INET6_NTOA(ipv6) AS ipv6
的所有实例。$row1['ip']
的所有实例,并将其替换为$row1['ipv6']
。$ipv6 =
的所有实例都使用以下代码(更改了数据库对象引用):$ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_string($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_string($db,getenv('REMOTE_ADDR'));
。答案 2 :(得分:0)
一个很好的例子,但是我注意到了以下几点。
仅当某人的mysql
版本具有INET6_ATON
的功能时才有效。
否则,错误消息可能类似于:FUNCTION
DOES
NOT
EXIST
。