Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mariadb 将IPv4转换为IPv6时MySQL bigint存储不一致/已签名与未签名_Mariadb - Fatal编程技术网

Mariadb 将IPv4转换为IPv6时MySQL bigint存储不一致/已签名与未签名

Mariadb 将IPv4转换为IPv6时MySQL bigint存储不一致/已签名与未签名,mariadb,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 i

我有以下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));
这应该很简单吧?不处理1083条记录后,MariaDB返回以下错误:

列“ipv6”不能为空

我觉得很奇怪,所以我决定开始验证数据:

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

  • 总之,
    更新
    查询为什么不解析整个表
  • 这取决于:MySQL和/或HeidiSQL在存储值方面有什么问题
  • MariaDB/MySQL是否允许存储比表结构允许的大的数字
  • 如果
    ip
    列类型为
    BIGINT(11)
    ,那么在
    UPDATE
    查询期间如何处理值40036798809(同样,不带逗号)
  • 为最高有效IPv4 IP地址(255.255.255.255)存储的有效值是多少
  • 我假设当我在HeidiSQL中排序时,它显示的是有效的最高值;这是最准确的猜测吗

您的号码40036798809似乎大于ipv4地址的最大可能值
255.255.255.255
,这会产生
4.294.967.295
(或
0xFFFFFFFF
)或最大的无符号longint。因此,它不可能是ipv4地址,因此为空,因此出现错误

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


至于MySQL整数列的大小,我感觉它的字节大小有些混乱。你可以在上读这个主题。

你的转换是正确的;你的数据是错误的。IPv4包含32位数字;你的
BIGINT
中存储的东西大于32位

这将定位坏行:

SELECT ip FROM example WHERE ip > INET_ATON('255.255.255.255');
您可能会发现196(1279-1083)行错误


(11)
是完全未使用和不相关的(除非您有
ZEROFILL
)。

我一直在努力部署正确的直接IPv6(完全没有IPv4,例如通过隧道)过去几天。我现在很好奇我是否能从这个转换到IPv6?理论上,是的,当然,如果你的所有设备都支持IPv6。我不太确定这会有多实际。如果你运行一个网站,并希望所有互联网都能访问它,当然不会。不,我说IPv6支持在连接上没有IPv4的情况下完全测试过,并不是说我会放弃IPv4支持。无论如何,我都想看看是否可以挽救较大的整数;但这似乎不起作用:
更新示例集ipv6=if(INET6_-ATON(INET_-NTOA(ip))为NULL,INET6_-NTOA(ip),INET6_-ATON(INET_-NTOA(ip)))
INET6\u ATON返回的内容似乎是二进制的,而不是数字。请尝试以下操作:
更新示例集ipv6=INET6\u ATON(coalesce(inet\u ntoa(ip),INET6\u ntoa(ip),0));