mysql> CREATE TABLE IF NOT EXISTS `ab`
`id` int(11) NOT NULL,
`id1` tinyint(3) unsigned DEFAULT NULL,
`id2` tinyint(3) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into ab values(1,1,2);
Query OK, 1 row affected (0.00 sec)
mysql> select id1-id2 from ab;
+———————-+
| id1-id2 |
+———————-+
| 18446744073709551615 |
+———————-+
1 row in set (0.00 sec)
分析原因:
这个值是bigint unsigned 的最大值。
MySQL内部的运算是按地址运算的。
二进制减法运算的原理:减去一个正数相当于加上一个负数A-B=A+(-B),对(-B)求补码,然后进行加法运算。 符号也进用相应的位表示了。
补码:补码或是反码的最高位为符号位,正数为0,负数为1
当二进制数为负数时,将原码的数值位逐位求反,然后在最低位加1得到补码。
当二进制数为正数时,其补码,反码与原码相。
(补了一下二进制)
1-2
过程: 0000 00001 – 0000 0010 = 0000 0001 +(-0000 0010)
#在这个求补码的过程中,按整数最大值来求了。用8个字节表示了。
=0000 00001 + (11111111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 + 1 )
=11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
mysql> select hex(18446744073709551615);
+—————————+
| hex(18446744073709551615) |
+—————————+
| FFFFFFFFFFFFFFFF |
+—————————+
1 row in set (0.00 sec)
参考:
http://zhidao.baidu.com/question/36780022.html
http://www.mysqlsupport.cn/2009/04/mysql-4int-unsigned.html