Alex的博客

本博客的文章均为原创,是本人从事行业多年来所遇见一些小问题的解决心得,希望可以帮助到大家!



mysql 位运算的应用

业务需求环境是这样的;

我们有三张表

分别是index 中间表

           course课程表

            area地区表

首先来说一下area表的area_binary字段

它必须为前一个字段乘以2的值

如下:

area:

area_id,area_name,area_binary

1            徐汇区        1

2            黄浦区        2

3            闵行区        4

4            浦东区        8

5            青浦区        16


然后就是index表的area_id字段了,其实这里存储的是area表或运算后的结果(或运算可以理解为相加 比如index表中的第一条记录里面的课程包含徐汇区,闵行区,浦东区 那么这个值应该就是对应的1+4+8=13)

index:

index_id,school_id,course_id,area_id

1               1            1           13

2               2            2           1

3               3            3           20

然后是课程表,这个不用太在意

course:

coures_id,course_name

1                course1

2                coures2

3                coures3

好了设计就完成了比如现在我们要查询出是否有闵行区的课程

那么sql语句就应该是

select `course_id` from index where area_id&4=4;

解释一下:

与运算的结果是如果这个字段的值里的组成部分包含你写入的这个值 那么他与运算后的值就是你进行与运算的值,如果不是组成部分那么与运算后的值就为0

如果我们要查询多个区的课程的时候同样也是先把要查询的区的area_binary进行或运算后 再对index表进行与运算  结果等于与运算的值就包含 为0就不包含。

这里要特别说明一下 一定要那2的倍数 也就是按照前面规律来进行id赋值的方式值来查询才能得到正确的结果。


这样我们就得到了包含指定区域的课程id集合了,

下面就要进行课程内容查询了

这里遍历数据我就不写了直接写关键部分

然后用php组装一维数组

foreach ($query as $value){

$temp[]=$value->course_id;

}

$temp=implode(',',$temp);

select course_name from  course where coures_id in ($temp);

结果就出来了。


至于mysql位运算的原理你可以简单的理解为:

或(|)运算是加法运算 比如1|2|3 等同于 1+2+3所有等于6

异或(^)运算是减法运算 比如6^3 等同于 6-3 所以等于3


最后是与运算

与运算原理其实也很简单

拿二进制来说吧

101101和000100进行与运算


101101

000100

上下对比

上1 下1 为1  其他情况为0

得出的结果就是与运算的结果

下面我们来把上面的表进行改变一下来进行解释应该就懂了


原理表:

index:

index_id,school_id,course_id,area_id

1               1            1            01

2               2            2           11

3               3            3           10

course:

coures_id,course_name

1                course1

2                coures2

3                coures3

area:

area_id,area_name,area_binary

1            徐汇区        1

2            黄浦区        01

3            闵行区        001

4            浦东区        0001




解释一下:

可以这么理解

徐汇区    黄浦区    闵行区    浦东区

    1            1            1            1

如果四个区都有那么就是 1111表示

如果只有徐汇区那么就是1000表示

如果有徐汇区和浦东区那么就是1001

这样就比较好理解了吧。

然后我们再来看看与运算

area_id&01 比较的时候

其实就是二进制的与运算

比如index表中的第一条

就是 01&01

第一个二进制的第二位为1 而第二位表示的是黄浦区 所以第一条满足条件

第二条

11&01

同理第二位上是1  所以也是成立的 

看第三条

10&01

第二位上是0 表示不存在 所以不成立

好了下班儿了。
浏览470  评论0  Alex于 2017-5-5 16:55
发言