注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

红尘若梦

生活的色彩

 
 
 

日志

 
 

Mysql中Tinyint字段的另类用法  

2015-09-08 12:39:24|  分类: 技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在MySQL的数据类型中,Tinyint的取值范围是:带符号的范围是-128到127,无符号的范围是0到255,占用1字节的存储空间,即8位(bit)。这种类型我们常常用它来表示一个状态,如0为无,1为有。
如下列创建表的SQL语句:

CREATE TABLE `593668` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键,自增',
`state` tinyint(1) unsigned DEFAULT '0' COMMENT '状态,0为无,1为有',
PRIMARY KEY (`id`)
)

查询的时候,就根据state来判断记录的状态。但是,往往数据表设计时,可能记录有多个状态需要,那就需要用多个tinyint字段来分别表示,相信大家也常常是这么做的,但是这种情形下对资源是一种很大的浪费。
要知道tinyint本身就可以按字节位来表示八种状态,如255按二进制来表示就是11111111,而Mysql函数库中也有一个BIN函数可以将相关的十进制数变成二进制数。如下列SQL语句:

select LPAD(bin(0),8,"0"); #会显示00000000,这里利用LPAD将不足八位的二进制补0

select LPAD(bin(255),8,"0"); #会显示11111111

看明白了吧,其实就是用二进制的方式将tinyint字段同时表示八种状态【如果tinyint被定义成有符号的话,那么就只能表示七种状态】。这种用法,在十多年前计算机资源还很有限的情况下是经常用到的,这在当时也是因为存储空间有限而不得不用的。比如DOS下的640K内存时,大多数的DOS游戏修改某种道具时,只需要将十六进制的00变为FF,就会全道具都齐全了。现在虽然存储空间已经没有那么紧张了,而且内存也变得越来越大,但其实这种做法也是对加快系统运行,提高执行效率仍有用处。那么下面就具体来谈谈做法。
比如一个记录,有八种状态需要表示,二进制每位都表示一种状态,那么需要查询这种状态位的到底是0还是1可以用下面的SQL语句来查询:

select * from 593668 where MID(LPAD(BIN(state),8,"0"),8,1)=1; #查询第八位是1的记录

select * from 593668 where LPAD(BIN(state),8,"0") like '_______1'; #同样是查询第八位为1的记录

select * from 593668 where state mod 254=1;#这也是查询第八位为1的记录,这里254是2的八次方减1,如果要查其它位,请按此规律调整

select * from 593668 where state=1 or state=3 or state=7 or state=15 or state=31 or state=63 or state=127 or state=255; #这同样是查询第八位是1的记录

当然您还可以把这个做成视图,以上四条语句都可以达成效果,但以第三条性能为最佳。不用担心性能问题,这种整除取余可以说对查询影响微乎其微,当然,你也可以将字段取出后,用配合的程序语言再来转换也成。如要判断第八位为1,那么只有可能性是00000001,00000011,00000111,00001111,00011111,00111111,01111111,11111111几种可能性,查询条件由程序来生成。
查询条件已经完成了,那么更新条件要如何处理呢,其实也不是很复杂。如要将符合条件的记录,第八个状态位置成1,那么可采用的SQL语句如下:

update 593668 set state=CONV(INSERT(LPAD(BIN(state),8,"0"),8,1,"1"),2,10);#将第八位置成1

update 593668 set state=IF(MID(LPAD(BIN(state),8,"0"),8,1)=1,state,state+1) #同样将第八位置成1,后面那个+1需要根据你所置的位置调整为2的多少次方-1

update 593668 set state=IF(state mod 254=1,state,state+1);#同样将第八位置成1

update oftest set state=CONV(CONCAT(SUBSTR(LPAD(BIN(state),8,"0"),1,LENGTH(LPAD(BIN(state),8,"0"))-1),"1"),2,10);#同样将第八位置成1

现在看出来了吧,操作都很简单。当然,如果换成int、bigint、smallint,同样可以利用来代表更多的状态,这样即节省的资源,又高效率利率了字段。
  评论这张
 
阅读(46)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017