1. 程式人生 > >位運算,處理前臺多選值

位運算,處理前臺多選值

scrip sin 分隔 sel 但是 接下來 條件 記錄 讀書

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

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

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

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

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

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

  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

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

  

  

  

位運算,處理前臺多選值