1. 程式人生 > >【資料庫】如何用一個數字來表示多選值

【資料庫】如何用一個數字來表示多選值

本人菜鳥一隻,如果有什麼說錯的地方還請大家批評指出!!

把需求轉換成一個簡單的例子解釋下:

前端有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

到此我應該是把第二種方式解釋明白了,如果還有什麼問題,可以給我留言~

好的,本人菜鳥一隻,整理就到這裡,如果有說的不對的地方,請各路大神指出!!