在签到统计场景中,可以使用 bitmap 数据类型高效的存储签到数据,但 getbit 命令只能获取某一位值,就无法最优的满足部分业务场景了。

比如我们按年去存储一个用户的签到情况,365 天,只需要 365 / 8 ≈ 46 Byte,1KW 用户量一年也只需要 44 MB 就足够了。

setbit sign:uid:year 0 1 #第1天

setbit sign:uid:year 1 1 #第2天

...

setbit sign:uid:year 364 1 #第365天

但如果我想获取某个用户一年的签到统计,使用 bitget 命令的话...要循环读取 365 次,这是没办法接受的。

如果能一次读取到以字符串

"1000100010100100...001"

的形式表示的位状态数据,就很好做后续的处理了。

bitmap 其实也是一种特殊的字符串数据,使用 get 命令是可以读取出来的,但是以 16 进制的流数据返回的,这里就涉及到网络编程中数据传输的打包/解包的知识,redis 使用 get 命令读取 bitmap 数据时,将二进制数据打包成了 16 进制返回给我们,所以我们要对此数据包以 16 进制解包,然后转为二进制字符串。给出转换方法:

<?php

// 第1天的签到

$redis->setBit('sign:uid:year', 0, 1);

// 第234天的签到

$redis->setBit('sign:uid:year', 233, 1);

// 第365天的签到

$redis->setBit('sign:uid:year', 364, 1);

// 使用 get 命令一次性读取用户的 bitmap 签到数据

$bitmap_str = $redis->get("sign:uid:year");

// 对数据流使用网络字节序(大端)解包拿到16进制数据的字符串形式

$hex_str = unpack("H*", $bitmap_str)[1];

// hex str 的长度

$hex_str_len = strlen($hex_str);

// 为了防止 hex to dec 时发生溢出

// 我们需要切分 hex str,使得每一份 hex str to dec 时都能落在 int 类型的范围内

// 因为 2 位 16 进制表示一个字节,所以用系统 int 类型的字节长度去分组是绝对安全的

$chunk_size = PHP_INT_SIZE;

// 对 hex str 做分组对齐,否则 str 的最后几位可能会被当作低位数据处理

// 比如 fffff 以 4 位拆分 'ffff', 'f' 后 最后一组 'f' 就被低位数据处理了

// 对齐后 fffff000 分组 'ffff', 'f000' 就能保证 'f' 的数据位了

$hex_str = str_pad($hex_str, $hex_str_len + ($chunk_size - ($hex_str_len % $chunk_size)), 0, STR_PAD_RIGHT);

// 防止 hexdec 时溢出 使用 PHP_INT_SIZE 个 16 进制字符一组做拆分

// 因 16 进制 2 位标识一个字节 所以 PHP_INT_SIZE 是绝对不会溢出的

$hex_str_arr = str_split($hex_str, $chunk_size);

// 位数据的二进制字符串

$bitmap_bin_str = '';

array_walk($hex_str_arr, function($hex_str_chunk) use (&$bitmap_bin_str, $chunk_size) {

$bitmap_bin_str .= str_pad(decbin(hexdec($hex_str_chunk)), $chunk_size * 4, 0, STR_PAD_LEFT);

});

// 一次读取redis即可拿到 bitmap O(n)次操作的数据

echo $bitmap_bin_str{0} . PHP_EOL; //第1天

echo $bitmap_bin_str{233} . PHP_EOL;//第234天

echo $bitmap_bin_str{364} . PHP_EOL;//第365天

注释较多,业务代码不多,多多理解~

getHandel redis_redis 使用 get 命令读取 bitmap 类型的数据相关推荐

  1. Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据

    Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据 一.资源 什么是Apache POI Apache POI 不同类型的数据的表格(xls) 链接: ...

  2. 通过OracleDataReader来读取BLOB类型的数据 (转载)

     通过OracleDataReader来读取BLOB类型的数据  在实际的应用过程中,需要把大块的二进制数据存储在数据库中.读取这些大块的数据,可以通过强制类型转换成为byte数组,但是当这个二进制数 ...

  3. 通过OracleDataReader来读取BLOB类型的数据

    在实际的应用过程中,需要把大块的二进制数据存储在数据库中.读取这些大块的数据,可以通过强制类型转换成为byte数组,但是当这个二进制数据体够大时(几十兆或者上百兆),一次并不能获取到他的完整长度,所以 ...

  4. 问题:从键盘读取特定类型的数据(使用Scanner读取int类型)

    import java.util.Scanner; public class ScannerIntTest{public static void main(String [] args){int nu ...

  5. java读取mdb类型的数据

    1.总体说明 现在java读取mdb数据(也就是链接access数据库读取数据)对jdk的版本有要求,jdk1.8以前的可以直接链接access数据 库读取数据,而jdk1.8以后的都需要加载一个连接 ...

  6. PostgreSQL命令恢复dmp类型的数据备份

    1.用管理员身份打开cmd黑窗,并进入到PostgreSQL的bin目录下 2.输入 pg_restore.恢复数据库的命令 pg_restore.exe --host "localhost ...

  7. waterdrop(1.5.1版本)增加bitmap类型导数的遇到的问题

    1. 背景 背景是想通过最新的 jbdc 来使waterdrop 可以导入bitmap 类型的数据 2. 实施方法 a. 配置文件 adm_dmp_clickhouse_jdbc.conf spark ...

  8. pandas读取nlp_chinese_corpus里面的json类型的数据,一行一个字典的数据

    最近在用pandas来读取json类型的数据,发现网上资料居然没查到,我这里弥补一下空缺,读取的json数据示例为: {"qid": "qid_1815059893214 ...

  9. Gdiplus byte *数据转换为Bitmap类型图片

    最近在mfc上显示缩略图那样显示采集到的图片,这个用CimageList和CListctrl就可以了,网上有很多这里不细说,但是别忘了初始化Gdiplus: 但是我的相机采集到的就是byte类型的数据 ...

最新文章

  1. 论工程结构设计的重要性
  2. 7-19晚牛客网刷题未知点、错题 集合
  3. PIL应用之生成验证码图片
  4. 将文件内含有的特殊字符还原
  5. 【树莓派】树莓派(Debian)- root用户无法使用SSH登录
  6. jni直接转byte_JNI jbyteArray转char*
  7. 我们来判断一个php函数是否被定义
  8. php连接数据库(一)
  9. AppScan安装教程
  10. 数据结构期末考试试题及答案
  11. 求职软件测试工程师英文简历,软件测试工程师英文简历范文
  12. 2021 ICCV TIMI-Net 抠图网络论文笔记
  13. MySQL数据库实验(六):创建学生信息管理系统
  14. 网站点击流数据分析项目
  15. 2011年11月编程语言排行榜:Objective-C有望成为2011年年度编程语言。
  16. Linux笔记(更新中)
  17. progisp下载时报错Chip Enable Program Error 后续解决
  18. vue集成svg-sprite-loader
  19. 数据结构与算法——左程云09
  20. 换种思路解释自我管理

热门文章

  1. 解决Android 音频Xrun问题
  2. JAVA基础之n+=1与n=n+1的区别
  3. Ubuntu18.04安装BeyondCompare
  4. Android反射set/get系统属性(SystemProperties)
  5. mysql之获取自增长的ID
  6. Ubuntu20.04如何卸载软件
  7. ios 怎么判断字符串的字节数_如何用IOS判断字符串是不是纯数字
  8. c 连接mysql数据库_C++连接mysql数据库的两种方法
  9. vue3.0项目创建
  10. 码云克隆项目到IntelliJ IDEA中