整合mysql多个bool值字段,用&查询

需求

商品需要有是否上架,是否可用现金,是否可用提货额度,是否可用积分,是否可用金币等一些bool 值的字段;我们可以考虑转化为位的查询运算;
创建表

CREATE TABLE `products`  (
  `id` int(0) UNSIGNED NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `price` decimal(10, 2) NOT NULL,
  `type` tinyint(4) NOT NULL DEFAULT 0,
  `created_at` datetime(0) NULL DEFAULT NULL,
  `updated_at` datetime(0) NULL DEFAULT NULL,
  `deleted_at` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
定义

我们定义type 字段为,左起第一位 现金,第二位 积分,第三位 提货额度 第四位 上下架,即

二进制定义十进制
1000上架8
0100提货4
0010积分2
0001现金1

位与运算符 &
参与&运算的两个二进制位都为 1 时,结果就为 1,否则为 0。例如1|1结果为 1,0|0结果为 0,1|0结果为 0,这和逻辑运算中的&&非常类似。

位或运算符 |
参与|运算的两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。例如1|1结果为 1,0|0结果为0,1|0结果为1,这和逻辑运算中的||非常类似

添加 模拟数据

-- ----------------------------
-- Records of products
-- ----------------------------
INSERT INTO `products` VALUES (1, '仅提货', 1300.00, 4, NULL, NULL, NULL);
INSERT INTO `products` VALUES (2, '仅积分', 1355555.00, 2, NULL, NULL, NULL);
INSERT INTO `products` VALUES (3, '仅现金', 15.00, 1, NULL, NULL, NULL);
INSERT INTO `products` VALUES (4, '上架提货', 12222.00, 12, NULL, NULL, NULL);
INSERT INTO `products` VALUES (5, '上架积分', 222.00, 10, NULL, NULL, NULL);
INSERT INTO `products` VALUES (6, '上架现金', 566.00, 9, NULL, NULL, NULL);
INSERT INTO `products` VALUES (7, '上架提货积分', 88.00, 14, NULL, NULL, NULL);
INSERT INTO `products` VALUES (8, '上架提货现金', 66.00, 13, NULL, NULL, NULL);

插入数据

需求1: 可以积分提货及现金都可以的产品,即0111,bindec(0111)->7,插入数据

INSERT INTO `products`(`id`, `name`, `price`, `type`, `created_at`, `updated_at`, `deleted_at`) VALUES (9, '提货积分现金', 777.00, 7, NULL, NULL, NULL);

需求2:修改刚插入数据的名称为‘上架提货积分现金’及状态改为上架,
取出数据type=7;
$type = 7|8;//15

UPDATE `test`.`products` SET `name` = '上架提货积分现金', `type` = 15 WHERE `id` = 9
查询

需求1:
查找能用积分购买的上架商品

SELECT * FROM `products` where type&8 AND type &2

或者

SELECT * FROM `products` where (type&10)=10

结果都为
在这里插入图片描述

第一种好理解:表中的type与8(1000)与2(0010)同时满足查找,其实第一条的sql 相当于

SELECT * FROM `products` where (type&8)>0 AND (type &2)>0

第二种,相当于

SELECT * FROM `products` where (type&(2|8))=(2|8)
  • 2 的补码为 0010,8 的补码为 1000,按位或运算之后,结果为 1010,即整数 10;
  • type 字段值与10(1010)进行&运算,结果=1010(存在上架积分的)

总结

  1. 用mysql 的位运算查询,需要比较扎实的基本功。逻辑理解起来也比较绕一点,但是也更方便更简洁了;
  2. 那type这个字段的索引不是失效了?其实type 本身是枚举的类型,不适合创建索引;那也就不存在索引失效的问题;
  3. 以后我们可以深入探讨下整合后的查询效率问题;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值