【資料庫】如何用一個數字來表示多選值
本人菜鳥一隻,如果有什麼說錯的地方還請大家批評指出!!
把需求轉換成一個簡單的例子解釋下:
前端有5個選項供使用者選擇,分別是足球,籃球,橄欖球,乒乓球,羽毛球這五個選項,並且可以是多選!
但是資料庫中只能通過一個欄位來記錄使用者的選項(為什麼不用5個欄位呢,廢話,用5個欄位,以後可選項多了變成10個,變成20個,那這張表字段不就炸了嗎?)
因此如何通過一個欄位(什麼型別都可以)來解決這個問題呢?
這裡提出兩種方案:
方法一:很簡單,字串拼接下使用者的選項就可以了。
例如:足球,籃球,橄欖球,乒乓球,羽毛球分別是1,2,3,4,5,如果使用者選擇了籃球和橄欖球,就直接在對應的欄位上放入(2,3)中間用逗號隔開,如果選擇足球,乒乓球,羽毛球,就使用(1,4,5),如下圖所示,查詢的時候就根據逗號分隔欄位然後匹配數字就好了(或者簡單粗暴使用like查詢),這種方式插入簡單,大家都看得懂,但是使用起來效率肯定是沒有數字匹配的快,是一種能完成任務的中規中矩的方案
方法二:通過位運算來解決問題
這種方案肯定比方法一快
例如:足球,籃球,橄欖球,乒乓球,羽毛球分別是2的1次方,2的平方,2的3次方,2的4次方,2的5次方,也就是2,4,8,16,32這5個數字。
--greenplum(postgresql)中2的4次方,如下:
select POWER(2,4)
儲存:當用戶喜好足球,橄欖球,羽毛球的時候,資料庫中存的值為2+4+32=38
查詢:有這麼一個符號&(按位與,在我另一篇文章中有做說明:https://blog.csdn.net/lsr40/article/details/78020039),查詢的時候38&2如果值等於2,那麼就說明2這個值對應足球是使用者所喜歡的,38&32等於32,證明32也是使用者所喜歡的(就是與後面那個值如果和計算出來的結果是一樣的,那證明後面這個值就是使用者所喜歡的)
使用:使用者表中資料
字典表:維護數值和中文球類的關係
查詢語句:
單種愛好
--喜歡所有喜歡籃球的人
SELECT
*
FROM
( SELECT *, ( SELECT hobby_type FROM zidianbiao WHERE hobby_str = '籃球' ) AS h FROM test ) tb
WHERE
hobby & h = h
組合愛好
--喜歡羽毛球又喜歡乒乓球的人 SELECT * FROM ( SELECT *, ( SELECT hobby_type FROM zidianbiao WHERE hobby_str = '乒乓球' ) AS h1, ( SELECT hobby_type FROM zidianbiao WHERE hobby_str = '羽毛球' ) AS h2 FROM test ) tb WHERE hobby & h1 = h1 and hobby & h2 = h2
又或者可以分兩條sql來執行,在程式碼中儲存喜好對應的數字,直接迴圈拼接sql(或者等等其他方式都ok),類似這樣
--第一條sql
SELECT hobby_type FROM zidianbiao WHERE hobby_str = '乒乓球' or hobby_str = '羽毛球'
--得到32和16兩列的值
--通過迴圈拼接1=1後面的sql,也可以達到一樣的效果
SELECT * FROM test
WHERE 1=1
and hobby & 32 = 32
and hobby & 16 = 16
到此我應該是把第二種方式解釋明白了,如果還有什麼問題,可以給我留言~