2009年05月6日

unsiged 数值运算 记录

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究。

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)

分析原因:

18446744073709551615
这个值是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

Mysql 4 和5的int unsigned 区别

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究。

所有整数类型可以有一个可选(非标准)属性UNSIGNED。当你想要在列内只允许非负数和该列需要较大的上限数值范围时可以使用无符号值。
mysql4:
mysql> create table wubx(a TINYINT unsigned not null default ’0′);
Query OK, 0 rows affected (0.04 sec)
mysql> select * from wubx;
Empty set (0.00 sec)
mysql> insert wubx values(0);
Query OK, 1 row affected (0.00 sec)
mysql> select * from wubx;
+——+
| a |
+——+
| 0 |
+——+
1 row in set (0.00 sec)
mysql> update wubx set a=a-1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 1
mysql> select * from wubx;
+——+
| a |
+——+
| 0 |
+——+
1 row in set (0.00 sec)

mysql5:

(root@localhost) [test]> create table wubx(a int(11) unsigned not null default ’0′);
Query OK, 0 rows affected (18.44 sec)
(root@localhost) [test]> select * from wubx;
Empty set (0.00 sec)
(root@localhost) [test]> insert into wubx values(0);
Query OK, 1 row affected (0.00 sec)
(root@localhost) [test]> update wubx set a=a-1;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
(root@localhost) [test]> select * from wubx;
+————+
| a |
+————+
| 4294967295 |
+————+
1 row in set (0.00 sec)
mysql> show warnings;
+———+——+—————————————————–+
| Level | Code | Message |
+———+——+—————————————————–+
| Warning | 1264 | Out of range value adjusted for column ‘a’ at row 1 |
+———+——+—————————————————–+

查了一下:
在对于数值处理时:

MySQL4 会在不合规定的值插入表前自动修改为 0
Mysql5 为了速度,只存放数二进制数据,而且在加减运算中,也是二进制的运算.

所以在使用unsigned 是小心0-1 的操作.尽量在这类操作前先做一个判断.

MySQL Innodb 引擎优化(二)

机器篇

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究。
背景:
Innodb 是什么的介绍请参考 MySQL Innodb 引擎优化(一)我有时在讲选择机器上时,好多朋友会觉的MySQL嘛,随便弄一个机器就行了。又不象Oracle之类的安装要求内存必须超过512M什么之类的。但要想让机器跑出一秒中上千Query的效果,机器选择方面还是要待认真对待一下。另一方面做为数据库,到真正的生产中大家绝对要求是稳定高性能了,怎么达到这些要求呢?当然基本建设上一定要跟上,弄一个稳定的高性能的机器是首要条件。当然这里有一个并发力度和数据量总大小和单表大小有很大的关系。例如:并发不大,数量小或是总量比较大,但最大的表没超过1G,一般的类CMS网站,那对于机器的选择要求真的是不大了;另一方面,如果能预见自已的数据量增长较快,并发强度大,数据增长也快的情况下,选择Innodb引擎是一个明智的选择;或是现在的业务已经出现了性能瓶颈进行优化时,也可以比较一下各个引擎的特点。
机器选择包括:
1、硬盘选择
2、内存选择
3、cpu选择
4、系统选择
5、整架构的规划和调整 
 
1、硬盘选择:
空间的大小:这个根据自已数据量,增长情况,项目预算到那个阶段来决定。Raid级别:根据业务情况选择Raid10,Raid5推荐用Raid10对数据库系统Raid10绝对有优势,Raid5适合读比较多的业务系统。不过在在充许的情况,还是Raid10是最佳的选择以空间换时间,从而加快速度。在Raid的选择上,一定要选择好的Raid卡,大牌子还是可信的。免的出现很多莫名其妙的问题。Raid卡没电,加电过程机器性能下降严重,数据文件损坏等现象。让项目受到损失。推荐Raid卡缓存在256K-1M的。一定要用烂牌了Raid卡。成本可能的情况:选择市场上最快的磁盘,根据业务考虑自已的业务的读写比例有所取舍,必竟现在出来了一个SSD硬盘,在硬盘的选择上又多了一个选择。最其码建义也是单块的SAS硬盘。
2、内存选择:
根据数据量来决定。现在数据库机器内存最少也4个G了,其码要不要低于这个吧。便于你的机器能在项目中抗一段吧。建义用8G内存以上。
3、CPU选择:
选择64位的CPU,缓存要大的。Innodb对CPU的利用比较高。不用担心CPU浪费。
4、系统选择:
这个也是比较重要的。一定要选择64位的系统,64位的MySQL。另一方面确认系统的IO模式,DIRECT模式是一个不错的IO模式。线程库支持情况。MySQL是一个多线程的DB,所以对线程库要求比较高,基于这点Linux,Solaris都是一个不错的选择。Linux要选择kernel 2.6.X的内核。再可能的情况下可以禁用DB服务器的Swap分区,从而必免系统瞬时不稳定的现象。MySQL大量的查询都是短查询,所以可以禁掉Swap。如果是线下数据分悉,还是起用Swap吧。不同系统的分区性能也是不一样的。对于Linux来说推荐用XFS,在数据量大的情况下可以提高性能1.5倍以上。
5、整架构的规划和调整 
另外在选择机器上时,还要考虑到我一次能用多少机器呢?如只有一台,那就尽配置的最强,如果可以上多台,那就可以根据是主库或是从库,读写多少这类来配置不同的机器。如果机器的并发严重,写入量也大的情况下,可以适高的考虑用强的机器做Slave,从而从使Slave能追上Master。
总结:
在机器上的选择上,特别是对DB应用,一定要选择可靠的机器。在上线使用前一定要深入测试,上线测试,多观查,根据自已的业务情况来选择合适的机器。同样也要本着最低成本投入,最大收益的原则来做。