bitMap
bitMap 其实个字符串数组,只是这种数组里面存储的是0和1
思考:计算机底层是将信息转成二进制存储的,合理的使用01位图,可以帮助我们提升效率,节省空间
redis中的操作:
bitmap 适合的用途:记录大批用户的某种动作的两个状态
比如记录:某种商品一天被多少个用户浏览过
或者一个用户一个月浏览过多少商品之类的
比起正常的使用map存储,使用bitmap存储不仅速度更快,占用的空间更少
思考,相比正常map的全id存储,bitmap将下标作为映射id,一个id只对应数组中的一位,通过这种方式大大提高了存储效率
布隆过滤器
hash算法与位图法的互相应用
上面有说bitmap映射ID,那么常见的映射方式就是采用hash算法的方式,将字符串通过hash算法的方式映射到bitmap上
hash冲突:和hashMap不一样,hashmap采用链表+红黑树的方式处理hash冲突,但是显然在bitmap中没法这样用,那么bitmap怎样处理hash冲突呢?
多次hash计算,通过不同hash落在bitmap不同的位上,同过多个hash定位一个值是否存在
无法避免的冲突
多个hash定位,意味着其他的字符串也有可能hash定位在相同的bit位上,干扰了我们的判断,因此 如果某字符串的多个hash都存在,并不代表着这个字符串一定存在,
相反如果有的hash位不存在,那么这个字符串一定不存在
合适的bitmap长度合理避免hash冲突
假设bitmap长度位 m 大概的插入个数位 n 允许出现的概率 位p
那么公式是
适合的hash个数为k 公式如下
(图片来源享学课堂)
HyperLogLog极大似然法
当某组数据量高达一个数量级后,想要计算这个这组数数据的个数则成为了个很消耗成本的动作,时间复杂度O(n)
所以如果我们只需要知道大概的多少W的数据量,不用精确到个位的话可以使用HyperLogLog来计算。
那么什么是HyperLogLog呢?
通过将key字符串转成二进制后,通过从右到左数第一个出现1的位置来表示一共有多少数据量,比如:
0000100 --》表示这组数据有4组
听起来是不是很离谱,第一此出现1的是很有随机性的,通过这种方式确认数据量,正确的概率简直就和抛硬币会立起来的概率一样
等等,概率!如果一组正确概率很离谱,那么我做1000次,1W次呢,多组数据的验证,可以使结果趋向正确
分桶
如上所说HyperLogLog采用了分桶概念,将一个字符串hash出64位,其中前14位作为桶位,后五十位作为计算第一个1出现的位置。
如果计算的桶位冲突吗,则取最大值
这样当我们将所有桶位都赛满后,就可以开始计算了
调和平均数
假设我的月收是3000 马爸爸的收入的3000w
这个时候使用平均数会使得我的月收入高达 1500W
虽然很美好但是偏离事实太多了
所以这时候有了调和平均数
2/(1/3000+ 1/3000W) 结果约等于6K
这样算出来的结果看比较靠谱
所以HyperLog就是采用这种方式计算桶内的值
HyperLogLog 操作符号
pfadd
pfcount
HyperLogLog思考
HyperLogLog 其实是通过 字符转二进制+寻找最小位1的位置+多组计算+调和平均数的方式估算出一个接近真实数据数量。
GEO算法
通过输入经纬度可以计算出 两个坐标之间的距离
原理:将二位的经纬度映射成一维的整数
通过一维的整数可以直观的看到两个坐标之间的距离
加入坐标:geoadd
计算距离:geodist
geo存储位置是zset
因此删除时使用了 zrem