位运算,处理前台多选值

前言: 本周,公司有个需求,需要对前台一个多选值进行存储,实现过程中,想过三种方案,在这里记录下。

 

方案一(使用多个布尔值): 

  在最开始,多选值只有两个,就打算用两个布尔值分开存储的,实现和使用都很方便。但是接下来,给到的多选值多了很多,发现这样的设计有很大的问题。

  不符合数据库范式、数据冗余性大、不利于业务调整。

 

方案二(使用逗号分割存储,通过模糊查询来匹配):

  接下来,对设计进行了调整

  1. 将多选值设计成一个枚举类, 带有code值

public enum Hobby {

    READ("01", "读书"),
    
    SING("02", "唱歌"),
    
    GAME("03", "游戏"),
    
    SWIM("04", "游泳"),
    
    CYCLE("05", "骑车");
    
    private String code;
    
    private String description;

    //......  

}

  2.  存储时,将code以逗号分隔进行存储, 如 01,03,04(读书、游戏、游泳)

  3. 查询时, 假设用户想查询爱好有读书、游泳的人。那么用户的条件即: 01,04,此时SQL过滤条件为:SELECT * FROM tb_user hobby WHERE LIKE '%01%04%'。 即利用like进行模糊查询,将逗号用%号代替

  总结: 此方法适用于表的数据量不是很大的情况, 因为查询效率不高

 

方案三(利用位运算):

  今天想到了一种更好的方案, 利用的是数据库的“位”运算来实现

  1. 将多选值设计成一个枚举类,带有权重标识

public enum Hobby {

    READ(1, "读书"),
    
    SING(2, "唱歌"),
    
    GAME(4, "游戏"),
    
    SWIM(8, "游泳"),
    
    CYCLE(16, "骑车");
    
    private int weight;
    
    private String description;

    //......  
s
}

  2. 存储时,将用户选择的多选值,权重进行相加、将得到的整型数值进行存储。 如:读书、游戏、游泳, 权重和为1 + 4 + 8 = 13, 即存储13进入数据库

  3. 查询时, 假设用户想查询爱好有读书、游泳的人。那么用户的条件权重值为1 + 4 = 5,此时SQL过滤条件为:SELECT * FROM tb_user hobby WHERE hobby & 5 > 0

  总结: 此方案较为简单,存储更加方便,查询效率也高于方案二

  

  

  

转载于:https://www.cnblogs.com/ark-blog/p/9347837.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值