【数据库】如何用一个数字来表示多选值

本人菜鸟一只,如果有什么说错的地方还请大家批评指出!!

把需求转换成一个简单的例子解释下:

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

到此我应该是把第二种方式解释明白了,如果还有什么问题,可以给我留言~

好的,本人菜鸟一只,整理就到这里,如果有说的不对的地方,请各路大神指出!!

猜你喜欢

转载自blog.csdn.net/lsr40/article/details/82423173