在编程里面有一些复选框的功能,比如要记录用户的爱好,爱好有几个选项,比如:篮球、乒乓球、足球、羽毛球这四个,用户可以选择一个或多个,那这个时候如果是你来做的话,应该怎么设计这个字段呢?
方案一:
hobby 字段,1:篮球、2:乒乓球、3:足球、4:羽毛球
用户如果只选择篮球呢,库里就存1,选择篮球和乒乓球,库里就存 1,2,用逗号分隔。
那增,删,改的时候都很简单,改的时候就直接覆盖就好了;但是当查询的时候,比如web页面有个爱好的查询下拉框,选择篮球的话,需要展示出喜欢篮球的用户都有哪些,那这里该怎么查呢?选择篮球,那就把1传到后台,查询所有的用户,循环遍历这些用户,取到爱好字段,按逗号分隔成list,再遍历list,与传过来的篮球1进行比较,相等的话,则取出该用户,再循环,最后把取出来的用户list返回到前端。看,这个是不是很麻烦呢?
如果做一件事情很麻烦,那一定有一个好方法。
方法二:
hobby 字段,1:篮球、2:乒乓球、4:足球、8羽毛球
用户如果只选择篮球呢,库里就存1,选择篮球和足球,库里就存 5,选择足球和羽毛球呢,库里就存12,全都喜欢存15。
那我们来做查询,前端页面爱好下拉框里有 1:篮球、2:乒乓球、4:足球、8羽毛球四个,当选择足球时,传到后台是4,后台应该要返回喜欢足球的所有用户。下面我们造几条数据,
CREATE TABLE `user_hobby` ( `id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT, `user_id` BIGINT ( 20 ) DEFAULT NULL, `user_name` VARCHAR ( 16 ) DEFAULT NULL, `hobby` INT ( 4 ) DEFAULT NULL COMMENT '1:篮球、2:乒乓球、4:足球、8羽毛球', PRIMARY KEY ( `id` ) ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '用户爱好表';
INSERT INTO `maple`.`user_hobby`(`id`, `user_id`, `user_name`, `hobby`) VALUES (1, 1, '张三', 1); INSERT INTO `maple`.`user_hobby`(`id`, `user_id`, `user_name`, `hobby`) VALUES (2, 2, '李四', 5); INSERT INTO `maple`.`user_hobby`(`id`, `user_id`, `user_name`, `hobby`) VALUES (3, 3, '王五', 12); INSERT INTO `maple`.`user_hobby`(`id`, `user_id`, `user_name`, `hobby`) VALUES (4, 4, '赵一', 15);
可以看到张三只爱好篮球,李四爱好 篮球和足球,王五爱好足球和乒乓球,赵一全都喜欢
那当我们查询喜欢足球的用户,期望结果应该是 李四、王五、赵一。我们执行下面这条sql:
select * from user_hobby where hobby & 4;
是不是就可以查到了呢,和方法一比较是不是简单太多啦。这个sql的意思是说查询和4位与,结果为真的数据,我们发现5&4,和12&4 结果都是4,8&4,结果为0;为什么呢?
所以我们要去看位与运算符:只有对应的两个二进位均为1时,结果位才为1 ,否则为0。
因为5是1+4,所以5的被4加的那个位置上一定是1,然后再 位与4,那肯定不会为0的。
参考原文链接:https://blog.csdn.net/qq_33101675/article/details/103528669