整型(int)数字溢出在程序和数据库设计中的考虑
在数据库设计和程序中需要考虑数字的范围,否则可能导致一些问题。主要是考虑溢出的问题,比如如果数据库中有一个整型的数字字段,里面的数据可能随着业务的增长而膨胀,而这个数字有可能会超出列属性的范围,也就是溢出,与此同时,程序中也需要处理这个日益庞大的数字,如果其中有运算、数字类型的逻辑比较等等,也可能导致某天就出现了异常。而这种错误又是难以发现的。
以下试以整型(int)抛砖引玉:
一:MySQL5
以MySQL5版本为例,大多数管理员可能把自增数字、或者其它应用数字字段的列属性设置为int类型,int占用4个字节,而int又分为无符号型和有符号性。对于无符号型的范围是0 到 4294967295;有符号型的范围是-2147483648 到 2147483647。参考资料可见mysql手册:11.2. 数值类型.
当要在一个数值列内保存一个超出该列允许范围的值时,MySQL的操作取决于此时有效的SQL模式。如果模式未设置,MySQL将值裁剪到范围的相应端点,并保存裁减好的值。但是,如果模式设置为traditional(“严格模式”),超出范围的值将被拒绝并提示错误,并且根据SQL标准插入会失败。请参见mysql手册5.3.2节:“SQL服务器模式”。
如果INT列是UNSIGNED,列范围的大小相同,但其端点会变为到0和4294967295。如果你试图保存-9999999999和9999999999,以非严格模式保存到列中的值是0和4294967296。
如果在浮点或定点列中分配的值超过指定(或默认)精度和标度规定的范围,MySQL以非严格模式保存表示范围相应端点的值。
当MySQL没有工作在严格模式时,对于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT语句,由于裁剪发生的转换将报告为警告。当MySQL工作在严格模式时,这些语句将失败,并且部分或全部值不会插入或更改,取决于是否表为事务表和其它因素。详情参见mysql手册5.3.2节:“SQL服务器模式”。
二:php5:
1:整型数的字长和平台有关,PHP 不支持无符号整数。
2:如果给定的一个数超出了 integer 的范围,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。如果在程序中有对数字类型做比较,可能会产生问题。
3:可以查看PHP_INT_SIZE、PHP_INT_MAX,以确定整数的范围。
以下列子可供参考:
在32位服务器下:
以下是代码片段: [shengting@localhost ~]$ php -r \"echo PHP_INT_SIZE;\" 4 [shengting@localhost ~]$ php -r \"echo PHP_INT_MAX;\" 2147483647 [shengting@localhost ~]$ php -r \"var_dump(2147483647);\" int(2147483647) [shengting@localhost ~]$ php -r \"var_dump(2147483648);\" float(2147483648) [shengting@localhost ~]$ php -r \"var_dump(-2147483647);\" int(-2147483647) [shengting@localhost ~]$ php -r \"var_dump(-2147483648);\" float(-2147483648) [shengting@localhost ~]$ php -r \"var_dump(4294967295);\" float(4294967295) [shengting@localhost ~]$ php -r \"var_dump(4294967296);\" float(4294967296) |
在64位服务器下:
以下是代码片段: [root@login shengting]# php -r \"echo PHP_INT_SIZE;\" 8 [root@login shengting]# php -r \"echo PHP_INT_MAX;\" 9223372036854775807 [root@login shengting]# php -r \"var_dump(2147483647);\" int(2147483647) [root@login shengting]# php -r \"var_dump(2147483648);\" int(2147483648) [root@login shengting]# php -r \"var_dump(-2147483647);\" int(-2147483647) [root@login shengting]# php -r \"var_dump(-2147483648);\" int(-2147483648) [root@login shengting]# php -r \"var_dump(4294967295);\" int(4294967295) [root@login shengting]# php -r \"var_dump(4294967296);\" int(4294967296) |
三:C/C++
对C/C++也存在有符号和无符号类型的问题。
对于32位系统,如果使用有符号int、long来定义变量保存唯一号就可能出现溢出,并出现上述问题。
对于64位系统,如果使用int来定义变量保存唯一号就可能出现溢出,并出现上述问题。
可参考 http://www.ibm.com/developerworks/cn/linux/l-port64.html
建议继续学习:
- java中byte转换int时为何与0xff进行与运算 (阅读:3042)
- Mysql 4.1升级到5.0以后一个很郁闷的地方 (阅读:2460)
- java中byte转换int时为何与0xff进行与运算 (阅读:2232)
- C语言的整型溢出问题 (阅读:1868)
- 小心 int 乘法溢出! (阅读:1354)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:yayu 来源: 芽雨快跑
- 标签: int 整型
- 发布时间:2009-10-10 14:08:06
- [66] Oracle MTS模式下 进程地址与会话信
- [66] Go Reflect 性能
- [65] 如何拿下简短的域名
- [59] android 开发入门
- [59] 图书馆的世界纪录
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [58] 【社会化设计】自我(self)部分――欢迎区
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [46] 读书笔记-壹百度:百度十年千倍的29条法则