位運算,處理前臺多選值
阿新 • • 發佈:2018-07-21
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。
總結: 此方案較為簡單,存儲更加方便,查詢效率也高於方案二
位運算,處理前臺多選值