一、业务需求:
- 业务涉及的一个表里,有多个“非此即彼”型字段
- 整合在一个字段里,用二级制位来表示多个信息
二、直接小demo
2.1 创建测试类,比较性能和实用性
CREATE TABLE `goods_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_tag` bit(8) DEFAULT NULL,
`tag` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '商品标志位',
`tags` int(8) DEFAULT '0' COMMENT '商品标志位',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
// 这里阈值设置为:8位,足够了
经过多方比较,tags用int类型来存储运算性能是最好的,当然,mysql层面而言,信息可读性就差了些
2.2 查询SQL语句如下:
SELECT *,BIN(tags),tags>>1,tags>>2,tags<<2,tags&1 FROM goods_test WHERE tags&1 >0;
// BIN(tags),表示把十进制的tags展示成二进制的样子
// tags&1 “与”运算
三、业务约定
import com.google.common.base.Objects;
/**
* @author huoNan
* @version 1.0
* @description 商品标志位解析
* @time 2018/12/18 11:46
*/
public enum GoodsTagEnum {
/**
* 00000000
* 采用二进制位记录商品变动信息
*/
GOODS_TITLE_CHANGE_YES(1, 1, "标题变动"),
GOODS_TITLE_CHANGE_NO(1, 0, "标题未变"),
GOODS_PRICE_CHANGE_YES(2, 1, "价格变动"),
GOODS_PRICE_CHANGE_NO(2, 0, "价格未变");
/**
* 位置
*/
private Integer position;
/**
* 值
*/
private Integer value;
/**
* 描述
*/
private String desc;
/**
* @param value 值
* @param desc 描述
*/
GoodsTagEnum(Integer position, Integer value, String desc) {
this.position = position;
this.value = value;
this.desc = desc;
}
public Integer position(){
return this.position;
}
/**
* @return 值
*/
public Integer value() {
return this.value;
}
/**
* @return 描述
*/
public String desc() {
return this.desc;
}
/**
* 根据值获取枚举类型
*
* @param position 枚举值
* @return 枚举类型
*/
public static GoodsTagEnum getByPositionAndValue(int position,int value) {
for (GoodsTagEnum c : GoodsTagEnum.values()) {
if (Objects.equal(c.position(), position) && java.util.Objects.equals(c.value(),value)) {
return c;
}
}
throw new IllegalArgumentException("没有对应得标志位");
}
}