采用bit位实现数据库记录一对多常量值的存储

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013632755/article/details/102570906

问题

假定有个业务需求:总共有3个功能可以被商户开通,分别为功能A、B、C。一个商户可以开通任意功能,也就是1对多的关系。
后面所有内容都围绕此问题展开进行。

通常方案

方式一:
通常的做法是我们需要设计商户与功能的关联表,假定商户编号为1001的商户开通了A、B、C三个功能,结构如下:

商户ID 功能(1-A,2-B,3-C)
1001 1
1001 2
1001 3

方式二:
或者直接将功能集设计为商户表中的一个字段并用分隔符分隔,如下:

商户ID 功能(1-A,2-B,3-C)
1001 1,2,3

方式一的好处是可以方便的查询到功能1对应的商户有哪些。坏处是随着业务拓展,记录会很多。
方式二的好处是可以更加直接的通过商户ID找到开通了哪些功能,并且一个商户只会对应一条记录,但是如果需要查询某个功能对应了哪些商户的话,需要对功能字段进行like。

bit位方案

bit位方案类似linux的目录文件的权限分配方式。
linux改变文件权限命令:chmod 777 file
三个7分别对应文件拥有者、群组、其他。r=4,w=2,x=1。

  • 若要rwx属性则4+2+1=7
  • 若要rw-属性则4+2=6
  • 若要r-x属性则4+1=5

假定如上功能A=1、B=2、C=4,那么商户表格对应设计如下:

商户ID 功能(1-A,2-B,4-C)
1001 1
1002 2
1003 3
1004 7

从数据来看,1001开通了A功能,1002开通了B功能,1003开通了AB功能,1004开通了ABC功能。
在这里插入图片描述
从数据记录维度来看和前面的方式二很像。一个商户一条记录,只是记录的是一个数字,这个数字代表一个功能或者多个功能。
如果我们只有3个功能那么值的范围为1-7,如果4个功能那么范围为1-15。
假定功能数量为n,那么最大范围值公式为2^n-1
那么当需要确定商户是否开通了某个功能如何做呢?当需要查询开通了某个功能的商户有哪些又该如何查询呢?

和bit位的关系

我们将1、2、4分别使用3位比特位二进制表示如下:
在这里插入图片描述
3位从右往左,每一位代表一个功能,分别为功能A、功能B、功能C。只要为1,代表开通了对应功能,0则是未开通。
如下图:
在这里插入图片描述

判断bit位

如果我们需要校验是否开通了某个功能,那么我们只需要校验该功能对于的位置是否为1就可以了。
我们可以采用and(&)逻辑运算对指定位进行校验。
公式:假定“校验功能数值对应的位下标”=y,“商户的功能数值”=z,结果=x。那么公式为1<<y&z=x,x大于0表明开通了该功能,否则未开通。
如假定商户1003对于的功能数值为3,判断是否开通了B功能,B功能对于下标为1,那么我们使用公式1<<1&3=2,2>0则表明1003的商户开通了B功能。
在这里插入图片描述
判断商户1003是否开通了C功能。C功能数值为4对应下标为2,同样使用公式1<<2&3=0,所以商户1003没有开通C功能。
在这里插入图片描述

拆解数值对应常量列表

在这里插入图片描述
可以看到,3对应1+2,5对应1+4,7对应1+2+4。
对应二进制如下图:
在这里插入图片描述
我们只需要从右往左,将每一个为1的位取出*10^下标组成之后就是分解之后的数列了。
举个例子,将数值7分解:
在这里插入图片描述
7按照上面方式分解就能得到4,2,1的数列了。
通过上面的分解方式,我就能得到某个商户的功能数值对应开通了哪些功能了。

如果需要查询开通了A功能又同时开通了B功能的商户列表怎么做呢,sql查询只需要查功能数值=A+B就可以了,也就是查询功能数值=3的商户列表。

找出某数值在特定位中出现的组合数值

当我们需要列出某个数值在特定位数的二进制中出现的组合情况时,怎么做?
在这里插入图片描述
当2比特位时,1有1、3两种情况,2有2、3两种情况。
当3比特位时,1有1、3、5、7四种情况,2有2、3、6、7四种情况,4有4、5、6、7四种情况。
这种问题需要用到排列组合了,推荐看这篇文章了解https://www.jianshu.com/p/9c139c9ea374

假定比特位长度为n,求某数值对应可能情况数量x,公式为x=2^(n-1)

总结

优点:

  • bit位方式可以很好的解决一对多的关系,可以减少关联表,减少数据存储成本。

缺点:

  • 但是如果对应的值数量在很多的情况下,意味着取值范围也非常大。
  • 仅支持常量值不变场景下的应用,比如,开始有A、B、C三个常量,后续业务扩展或者变动,需要把B这个常量删除,那么这种场景就没有办法玩了。
  • 需要找出某个数值对应的所有组合情况,需要用到程序写出递归算法得出,成本稍高。

猜你喜欢

转载自blog.csdn.net/u013632755/article/details/102570906
今日推荐