位運算,處理前臺多選值

前言: 本週,公司有個需求,須要對前臺一個多選值進行存儲,實現過程當中,想過三種方案,在這裏記錄下。數據庫

 

方案一(使用多個布爾值): 

  在最開始,多選值只有兩個,就打算用兩個布爾值分開存儲的,實現和使用都很方便。可是接下來,給到的多選值多了不少,發現這樣的設計有很大的問題。spa

  不符合數據庫範式、數據冗餘性大、不利於業務調整。設計

 

方案二(使用逗號分割存儲,經過模糊查詢來匹配):

  接下來,對設計進行了調整code

  1. 將多選值設計成一個枚舉類, 帶有code值blog

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進行模糊查詢,將逗號用%號代替ip

  總結: 此方法適用於表的數據量不是很大的狀況, 由於查詢效率不高io

 

方案三(利用位運算):class

  今天想到了一種更好的方案, 利用的是數據庫的「位」運算來實現效率

  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

  總結: 此方案較爲簡單,存儲更加方便,查詢效率也高於方案二

相關文章
相關標籤/搜索