将IPv4转换为IPv6 /签名与未签名

时间:2017-09-16 14:33:19

标签: mariadb

我有以下MySQL数据库表:

CREATE TABLE `example` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ip` BIGINT(11) NOT NULL,
`ipv6` VARBINARY(16) NOT NULL
PRIMARY KEY (`id`)
);

我的目标只是在新的ipv6列中将现有的IPv4 IP地址复制/转换为IPv6格式。所以我运行以下查询,在我的所有测试用例中都运行良好:

UPDATE example SET ipv6 = INET6_ATON(INET_NTOA(ip));

这个应该简单吗?否...处理1,083条记录后,MariaDB返回以下错误:

  

列'ipv6'不能为空。

我在想奇怪所以我决定开始验证数据:

  • 此表中有1279条记录。
  • 所有记录都包含ip列的值,因此看起来不错。所以我向下滚动到转换的第一条记录。它的值为40036798809,这是11个数字,因此应该INT(11)匹配吗?
  • 但是,未处理的第二行(请记住MySQL自然执行UPDATE查询按主键id的升序排列)ip值为该记录为10317637058914,其长度为14个数字,应该可以在INT(11)字段中使用,是吗?
  • 我看到一些显然超过整数长度的其他整数,所以我决定ORDER HeidiSQL 中的ip表,然后突然显示最高值记录ip列为1202623438。这是十个数字。 phpMyAdmin 也显示了更大的数字,但是我已经切换到HeidiSQL,因为我发现它的GUI对于我的本地开发来说是优越的。
  • 经过一些研究后,似乎BIGINT的数据类型的长度与列范围无关。 HeidiSQL 只需更改ip即可更改ORDER列值! Wait, what?!
  • 继续阅读后我的下一步是检查列是签名还是未签名。由于 HeidiSQL 显示未检查ip列的无符号意味着ip 已签名,因此它的最大值为(全部)逗号添加了用于可视化,实际值是纯数字的)2,147,483,647而在UPDATE查询期间不会解析的值是40,036,798,809。
  • 早期的研究表明,如果列中的数字大于允许的数量(不确定为什么甚至 允许?)那么它将被视为允许的最大值(我想象)在这种情况下2,147,483,647);这是真的吗?

问题

  • 总结:为什么UPDATE查询不能解析整个表?
  • 这取决于:MySQL和/或HeidiSQL存储值有什么问题?
  • MariaDB / MySQL是否允许存储大于表格结构允许的数字?
  • 如果UPDATE列类型为ip,则在BIGINT(11)查询期间如何处理值40,036,798,809(同样,没有逗号)?
  • 为最高有效的IPv4 IP地址(255.255.255.255)存储的有效值是多少?
  • 我假设我在HeidiSQL中ORDER时显示有效最高值;这是最准确的猜测吗?

IPv4 to IPv6 Conversion Issue Screenshot

2 个答案:

答案 0 :(得分:1)

您的号码40,036,798,809似乎大于最大可能的ipv4地址255.255.255.255,后者产生4.294.967.295(或0xFFFFFFFF)或最大的无符号longint。因此它不可能是IPV4地址,因此为空,因此是错误。

也许您的某些号码不是IPV4地址?

至于你的MySQL Integer列大小,我觉得它的字节大小有些混乱。您可以在What is the size of column of int(11) in mysql in bytes?上阅读该主题。

答案 1 :(得分:0)

您的转换是正确的;您的数据是错误的。 IPv4涉及32位数字;你有BIGINT大于32位的东西。

这将找到坏行:

SELECT ip FROM example WHERE ip > INET_ATON('255.255.255.255');

你可能会发现196(1279-1083)个坏行。

(11)完全未使用且无关紧要(除非您有ZEROFILL)。