王炸科技头像

减少mysql存储列的方法(以设计网络店铺为例)

来源:
       

  在设计数据库时,我们会经常碰到表示是非的字段,网络渔夫-汪维曾在设计店铺表时就遇到下列情况:

减少mysql存储列的方法(以设计网络店铺为例)-第1张图片

  该店铺有如下属性:首先是否具有如图所示的消费者保障服务:

  其次还有诸如是否属于中关村商圈等等;在这里如果要表示上述的几种属性,按照常规做法我得设计7个字段;如果以后又增加了个如平台保的服务,我又得增加个字段,所以这样做的缺点之一是不便于扩展;第二是占用的列太多,列太多会影响查找数据时的速度;

  第三就是这些字段由于是表示是非的值,所以做索引纯属浪费。

  介于以上缺点,我抛弃了上述方法;在这里我只要一个字段就可以表示上述所有的属性。

  做法如下:

  1.设计一个名为protect_str的字段,类型为binary(12);其值默认为000000000000;这里设计为12位是为了以后扩展需要www.2cto.com

  这里我用从左到右的六位依次来表示6种消保,如000000000011表示如实描述和快速发货;

  为0的位置表示没有这个属性,如000000000001表示这家店没有快速发货这个属性;反之则表示有;第7位表示是否属于中关村商圈子。

  2.查询:

  现在要查询所有拥有如实描述属性的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  protect_str&000000000001

  )=1

  查询既拥有如实描述又拥有快速发货属性的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  `protect_str`&000000000011

  )=11

  但是当执行SELECT100101&100001时结果却变成99841(至于为什么是这个结果,网络渔夫还没想清楚,如果有知道者请留言给我)

  所以用这种方式来记录也行不通。

  所以换成将二进制用十进制来进行存储。比如当二进制的第一位为1(即为0000001)时表示如实描述,转化为十进制则为1

  当二进制的第一位为1,第二位也为1(即为0000011)时表示如实描述,和快速发货,转化为十进制存储在数据库中则为3;至于为什么为3(12的0次方+12的1次方);当二进制的第一位为1,第二位也为1,第三位也为1(即为0000111)时表示如实描述,和快速发货,七天退换,转化为十进制存储在数据库中则为7;

  当一个店铺既有如实描述,和快速发货,七天退换保障又属于中关村商圈时,则可用1000111来表示,转换成十进制存储在数据库中则为71www.2cto.com

  现在要查询所有拥有如实描述属性的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  protect_str&1

  )=1

  现在要查询所有拥有快速发货属性的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  protect_str&2

  )=2

  现在要查询所有属于中关村在线商圈的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  `protect_str`&64

  )=64

  LIMIT0,30

  查询所有既属于中关村在线商圈又有如实描述服务保障的店铺,sql语句如下:

  SELECT

  FROM`shops1`

  WHERE(

  `protect_str`&65

  )=65

  LIMIT0,30

  如若以后有扩展则接着往高位上补数字就行了,比如说现在在对id=5的店铺增加了一个平台保障服务

  则这时可对有此项服务的店铺protect_str字段的第八位值设为1即10000000转化为十进制即为128(12的7次方)

  执行如下语句:

  UPDATE`test`.`shops1`SET`protect_str`=(`protect_str`|128)WHERE`shops1`.`id`=5

  即可将此字段值改为135;

  综上所述,凡是我们要加上某项服务的地方,我们用”|”或运算;凡是要查询具有某项服务的地方我们用”&”与运算。

  掌握了二进制转十进制,还有查询和更新,减少mysql存储列将不再是问题。

  下面给出试验用的数据库,大家可以用上述语句测试一下

  CREATETABLE`shops1`(

  `id`int(10)unsignedNOTNULLauto_increment,

  `shop_name`char(50)collateutf8_unicode_ciNOTNULL,

  `protect_str`int(12)NOTNULLdefault'0',

  `shop_id`int(11)unsignedNOTNULL,

  PRIMARYKEY(`id`)www.2cto.com

  )ENGINE=MyISAMDEFAULTCHARSET=utf8COLLATE=utf8_unicode_ciCOMMENT='店铺表'AUTO_INCREMENT=8;

  --

  --导出表中的数据`shops1`

  --

  INSERTINTO`shops1`VALUES(1,'bestshop',1,13);

  INSERTINTO`shops1`VALUES(3,'firstshop',2,15);

  INSERTINTO`shops1`VALUES(4,'nihao',71,23);

  INSERTINTO`shops1`VALUES(5,'shis',135,34);

  INSERTINTO`shops1`VALUES(6,'ytshop',6,45);

  INSERTINTO`shops1`VALUES(7,'uushop',65,65);

  作者sss0213