MySQL 原生并不支持 bitmap 类型,所以就只能存字符串,然后就根据你的 bitmap 长度以及转换方式来选择是用什么类型来存储,处理的过程在代码层面完成。
我简单说下我们做同样的事情的做法,不一定是好方法,可以一起探讨。
首先,我们 *** 作数据库的语言是 PHP。使用的是 ASCII 表里的 0 ~ 127位的字符,所以每一个字符可以存 8bits,然后用一个 char(125) 来存 bitmap 的一个片段,每个片段可以存 1000bits。
通过 PHP 计算某一位在那一个片段的第几位,例如 2345,就在第三个片段的第345位(从1开始的话),然后通过 PHP 进行更新。当然,也可以直接用 SQL 更新,SQL 语句写起来比较麻烦,我写了半天才写出来:
unhex( conv( bin( conv( hex( STR1 ), 16, 10 ) | conv( hex( STR2 ), 16, 10 ) ), 2, 16 ) )不过我们用 MySQL 存储也就是为了确保数据的安全性,大部分的查询 *** 作都在 redis 里面完成,redis 原生支持 bitmap 用起来又高效又方便。
redis的bitmap能设置最大的长度是多少, 为什么可以设置的最大长度位数是2^32, 怎么计算bitmap会占用多大的空间
前提: 实际上, redis只支持5种数据类型. 并没有bitmap. 也就是bitmap是基于redis的字符串类型的. 而一个字符串类型最多存储512M.
首先: 计算机的单位换算先了解下
8 bit = 1byte
1024 byte = 1kb
1024 kb = 1Mb
其次:
我们使用的bitmap指令SETBIT key offset value, 这个指令就是将第offset设置成0或1. 比如 SETBIT ss 1000 1 //就是将1000位置为1. 1 bit就是1位, 所以我们只要将512M换算成bit, 那么就知道bitmap支持的最大设置长度了. 计算如下
8 * 1024 * 1024 * 512 = 2^32 (所以这个结果就是这么来的)
怎么计算自己的bitmap会大概占用多大的存储空间呢?
举个栗子: 今有一个bitmap最大长度1024, 需要占用多大的空间?
解: 长度1024也就是他需要1024个位(bit), 或者单位为byte就是需要 1024 / 8, 即需要128byte
————————————————
版权声明:本文为CSDN博主「Day____Day____Up」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_37281289/article/details/106834014
a) Bitmap如何做到多维交叉计算的?
Bit即比特,是目前计算机系统里边数据的最小单位,8个bit即为一个Byte。一个bit的值,或者是0,或者是1;也就是说一个bit能存储的最多信息是2。
Bitmap可以理解为通过一个bit数组来存储特定数据的一种数据结构;由于bit是数据的最小单位,所以这种数据结构往往是非常节省存储空间。比如一个公司有8个员工,现在需要记录公司的考勤记录,传统的方案是记录下每天正常考勤的员工的ID列表,比如2012-01-01:[1,2,3,4,5,6,7,8]。假如员工ID采用byte数据类型,则保存每天的考勤记录需要N个byte,其中N是当天考勤的总人数。另一种方案则是构造一个8bit(01110011)的数组,将这8个员工跟员工号分别映射到这8个位置,如果当天正常考勤了,则将对应的这个位置置为1,否则置为0;这样可以每天采用恒定的1个byte即可保存当天的考勤记录。
综上所述,Bitmap节省大量的存储空间,因此可以被一次性加载到内存中。再看其结构的另一个更重要的特点,它也显现出巨大威力:就是很方便通过位的运算(AND/OR/XOR/NOT),高效的对多个Bitmap数据进行处理,这点很重要,它直接的支持了多维交叉计算能力。比如上边的考勤的例子里,如果想知道哪个员工最近两天都没来,只要将昨天的Bitmap和今天的Bitmap做一个按位的“OR”计算,然后检查那些位置是0,就可以得到最近两天都没来的员工的数据了,比如:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)