不经过悉心栽培,花儿开不出鲜艳的花朵;不经过时间的历练,幼苗长不成参天大树。

MySQL数据类型:使用unsigned得注意事项

database 建伟 2228℃ 0评论

unsigned说明

unsigned属性就是将数字类型无符号化,例如INT的类型范围是-2 147 483 648 ~ 2 147 483 647, INT UNSIGNED的范围类型就是0 ~ 4 294 967 295。可以增加字段长度。

在MYSQL中整型范围:

类型                      大小        范围(有符号)                               范围(无符号) 用途

TINYINT            1 字节    (-128,127)                                       (0,255) 小整数值

SMALLINT         2 字节    (-32 768,32 767)                             (0,65 535) 大整数值

MEDIUMINT     3 字节    (-8 388 608,8 388 607)                    (0,16 777 215) 大整数值

INT或INTEGER  4 字节    (-2 147 483 648,2 147 483 647)       (0,4 294 967 295) 大整数值

猛得看起来这是一个不错的属性选项,特别是对于主键是自增长的类型,因为一般来说,用户都希望主键是非负数。然而在实际使用中,UNSIGNED可能会带来一些负面的影响,让我们一起来看看:

先建一张测试表:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
 `a` int(255) unsigned NOT NULL,
 `b` int(255) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建了一个表test,存储引擎为InnoDB。表上有两个UNSIGNED的INT类型,接着我们来运行下面一句sql:

select a-b from test

这时结果会是什么呢?会是-1吗?答案是不确定的,可以是-1,也可以是一个很大的正值,还可能会报错.

在windows中会报如下错误:

[Err] 1690 – BIGINT UNSIGNED value is out of range in ‘(`test1`.`test`.`a` – `test1`.`test`.`b`)’

在linux中会得出:

a – b: 4294967295

哎,纳闷了,怎么没有得出我们心中的结果呢?

这个问题的核心是,在MySQL数据库中,对于UNSIGNED数的操作,其返回值都是UNSIGNED的。而正负数这个问题在《MySQL技术内幕:InnoDB存储引擎》中有更深入的分析,有兴趣的可以进一步研究。

那么,怎么获得-1这个值呢?这并不是一件难事,只要对SQL_MODE这个参数进行设置即可,

SET sql_mode='NO_UNSIGNED_SUBTRACTION';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a-b FROM t\G;

个人的看法是不要随便使用UNSIGNED,看情况而定,因为可能会带来一些意想不到的效果。另外,对于INT类型可能存放不了的数据,INT UNSIGNED同样可能存放不了,与其如此,还不如在数据库设计阶段将INT类型提升为BIGINT类型。

转载请注明:Li Jianwei's Blog » MySQL数据类型:使用unsigned得注意事项

喜欢 (4)or分享 (0)
web技术交流群
22765697