mysql 中int类型字段unsigned和signed的探索

转自:http://www.0791quanquan.com/news_keji/topic_816453/

探索一:正负数问题

拿tinyint字段来举例,unsigned后,字段的取值范围是0-255,而signed的范围是-128 - 127。 那么如果我们在明确不需要负值存在的情况下,通常是不要设置signed来支持负数的。 因为只支持正数会让存储空间大一倍呢(当然我这种表达可能不准确)。 假设我们使用tinyint来存储一些状态值。 0表示删除,1表示待付款,2表示已付款,3...。 突然来个需求要加订单取消,一些有代码洁癖的人就想,那就将定义为:-1表示取消吧。 但是就因为有了-1,我们说起来应该可以从0存到255的,结果就变为了0-127。 所以一般情况下,我们不建议这样设置

字段设置为unsigned后有一个问题是:

当select a - b from t时,a为10,b为12,那么这时就会出现异常情况:ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(`test`.`t`.`a` - `test`.`t`.`b`)‘

所以注意这种情况即可

探索二:性能问题

严格讲,在性能上是有细微的差别的。 unsigned的性能更好,当只存储正整数的情况下。 因为,当unsigned时,假设查询值在500以下的数据,那么MySQL会将范围定义为:0-500,而如果是signed,则查询范围为:-2147483648 - 500。 参考文章:http://rakesh.sankar-b.com/2010/08/25/mysql-unsigned-int-to-signed-int-performance-tips-index/

里面讲到:

Let’s say you want to know the list of customers who have purchased an item of quantity 500 or less. Following is the query you might be used to get these results:

SELECT *
FROM customer
WHERE quantity <= 500

Cool, the above query will yield you the list of customers who have purchased an item of quantity 500 or less. Right, what is the big deal, it should return fast, but consider when you have a table with millions of records then this query might be slow in returning you the results.

Yes, that is true, you can always add an “ index ” to the “quantity” field and improve the performance – exactly, this should improve the performance of processing the query much better than without an “index”.

Without “unsigned”:
Process flow, since the quantity field is an “ int ” and you have an  index  of this field, MySQL  will define the range as  -2147483648 to 500  and it will get the result based on this range.

With “unsigned”:
Process flow, since the quantity field is an “ int ” with “ unsigned ” and you have an index of this field,  MySQL  will define the range as  0 to 500  and it will get the result based on this range.

Now compare the difference yourself and tell me, for sure it will improve the performance of the your query. Since we know we never store any negative (signed values) in the quantity field and the default behavior of “ int ” is “ signed “, it’s always better to write a full-syntax while creating a table.

总的说来,设置unsigned最大的差异是字段取值范围的变化。 所以基于这点来对字段的unsigned或者signed是比较明智的决定

以上

参考文献:

http://verysimple.com/2006/10/22/mysql-data-type-optimization-tips/

http://rakesh.sankar-b.com/2010/08/25/mysql-unsigned-int-to-signed-int-performance-tips-index/

http://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html

http://www.cnblogs.com/blankqdb/archive/2012/11/03/blank_qdb.html

时间: 2024-10-09 20:49:38

mysql 中int类型字段unsigned和signed的探索的相关文章

MySQL中int类型的字段使用like查询方法

方法参考自: http://stackoverflow.com/questions/8422455/performing-a-like-comparison-on-an-int-field 也就是使用CAST转换指定字段,然后进行比较.具体样例代码如下: SELECT ProductID, ProductName FROM Products WHERE CAST(ProductID as CHAR) LIKE '%15%' 但是这样做的话,MySQL不能使用对应int字段索引,而且like本身就

关于mysql中int(1)中int后面的数字

详解mysql int类型的长度值问题 作者:追逐_something 我的朋友海滨问我mysql在建表的时候int类型后的长度代表什么? 是该列允许存储值的最大宽度吗? 为什么我设置成int(1), 也一样能存10,100,1000呢. 当时我虽然知道int(1),这个长度1并不代表允许存储的宽度,但却没有一个合理的解释. 或者说对这个长度也没有真正的研究过到底代表什么, 平时都用int(11), 也不知道为什么要11位. 所以我在网上查阅了一些资料, 也仔细的看了mysql手册关于int d

Java学习篇之---Mysql中varchar类型总结

Mysql中varchar类型总结 今天新做一个项目,需要自己进行数据库设计,发现自己对varchar的用法还不是很熟悉,所以查阅资料总结若下: 1.varchar类型的变化 MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定).在 MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字 节,也就是说,在4.1或以

Mysql中自增字段(AUTO_INCREMENT)的一些常识

Mysql中自增字段(AUTO_INCREMENT)的一些常识 在系统开发过程中,我们经常要用到唯一编号.使用过mysql的人都应该知道,mysql有一个定义列为自增的属性:AUTO_INCREMENT. 指定了AUTO_INCREMENT的列必须要建索引,不然会报错,索引可以为主键索引,当然也可以为非主键索引.(不一定要做主键) 1 2 3 mysql> create table t4 (id int auto_increment); ERROR 1075 (42000): Incorrect

MYSQL中TIMESTAMP类型的默认值

MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 表: —————————————————————————————————————— t1      CREATE TABLE `t1` (                                                                             `p_c` int(11) NOT NULL,                                              

MYSQL中TIMESTAMP类型的默认值理解

MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 1.自动UPDATE 和INSERT 到当前的时间:表:——————————— Table   Create Table                                                                         —— ————————————————————————————-t1      CREATE TABLE `t1` (                       

扩展mybatis和通用mapper,支持mysql的geometry类型字段

因项目中需要用到地理位置信息的存储.查询.计算等,经过研究决定使用mysql(5.7版本)数据库的geometry类型字段来保存地理位置坐标,使用虚拟列(Virtual Generated Column)来保存geohash值,便于查询. 需要了解geometry如何使用及优势可参看: mysql中geometry类型的简单使用 MySQL Geometry扩展在地理位置计算中的效率优势 本文主要讲解扩展mybatis和通用mapper,使其支持geometry类型字段的新增.修改.查询 首先创

mysql中int、bigint、smallint和tinyint的区别与长度

对比发现 int bigint smallint 和 tinyint 类型,如果创建新表时没有指定 int(M) 中的M时,默认分别是 : int             -------     int(11) bigint       -------     bigint(20) smallint   -------     smallint(6) tinyint     -------     tinyint(4) 下面是这几种类型的取值范围 参考:http://www.2cto.com/d

mysql中的null字段值的处理及大小写问题

在MySQL中,NULL字段的处理,需要注意,当在处理查询条件中有NULL,很有可能你得到的值不是想要的,因为,在MySQL中,判断NULL值相等(=)或者不等(!=)都会返回false.主要出现在常见的SELECT以及WHERE字句中. 为了处理这种特殊的情况,MySQL提供了如下的关键字进行特殊处理: IS NULL: 当列的值是NULL,此运算符返回true. IS NOT NULL: 当列的值不为NULL, 运算符返回true. <=>: 比较操作符(不同于=运算符),当比较的的两个值