最近要做一个圣诞抽奖活动,需要记录每天用户签到的记录,以前一般都是用普通的字符串数据类型,每个用户的签到用一个 key

// 用户10在活动第一天的签到key为record:1:10
$key = "record:$day:$id";
if ($redis->get($key)) {
echo '已签到';
} else {
$redis->set($key, 1)
}

那么一个用户一天的签到记录就要占一个字节,用户一多就产生非常多的 key,浪费宝贵的内存。

位图

为了解决这个问题,redis 另一种数据类型位图就非常适合。位图并不是特殊的数据类型,内容其实就是字符串,每一位只存储0或1,非常适合存储这种布尔类型的数据

位图使用 setbit/getbit 来存取数据

> SETBIT key offset value
> GETBIT key offset

比如一个用户圣诞连续五天的签到记录可以只使用一个 key, 10010 代表用户只有第二天和第五天签过到

$key = "record:$id";
if ($redis->getbit($key, $day)) {
echo '已签到';
} else {
$redis->setbit($key, $day, 1)
}

现在一个用户五天的签到记录只会产生一个 key,占用内存仅为 5bit 不到一个字节

进一步,如果你的用户系统中用户 id 是连续的 int 类型,还能更节省。因为只记录每个用户5天的签到记录,在一串位图中,每个用户占5个坑,这样所有的用户的签到数据只会使用一个 key

// 用户1占前5个坑
$offset = ($id - 1) * 5 + $day -1;
if ($redis->getbit('record', $offset)) {
echo '已签到';
} else {
$redis->setbit('record', $offset, 1)
}

现在只需要一个 key 就可以存下所有用户的签到记录了。

需要注意的是位图一个 key 最多存储 512mb 的内容,如果你的用户数大于 8*1024*1024*1024*512 / 5 ≈ 87 亿 并不适用这个方法。

其他用法

bitcount 用来统计指定位置范围内 1 的个数,bitpos 用来查找指定范围内出现的第一个 0 或 1。

> setbit s 0 1
> setbit s 3 1 #s=1001
> bitcount s [start, end]
(integer) 2
> bitpos s 0 [start, end]
(integer) 1

最新文章

  1. [c++] constexpr and literal class
  2. 記錄一次CRS-0184: Cannot communicate with the CRS daemon的解決
  3. genymotion虚拟机启动失败
  4. Java基础-内部类
  5. 什么是WebService
  6. Windows7中Emacs 24 shell使用Gitbash
  7. POJ 1778 All Discs Considered(拓扑排序)
  8. python 接口自动化测试--代码实现(七)
  9. C#获取当前时间详解
  10. JSP具体篇——response对象
  11. anaconda常用操作汇总
  12. django filter or 多条件查询
  13. 爬楼梯的golang实现
  14. cocos2dx-lua 延迟调用函数和定时器
  15. Python 运维
  16. HDU 1260
  17. win7访问局域网总提示用户名密码错误解决方案
  18. NET设计模式 第三部分 结构型模式(7):适配器模式(Adapter Pattern)
  19. Windows控制程序网站带宽及Qos(TOS或DSCP)
  20. free命令中buffers和caches的区别

热门文章

  1. 从BIO到Netty的演变
  2. m102 SE赛
  3. Python的看门狗实现自动化实时对服务器、Windows或Linux文件夹的实时监控
  4. Redis必备面试题《基础篇》
  5. Python 面向对象之五 基础拾遗
  6. 问题:做EsayUI分页报错 $(...).pagination is not a function之后我把<jsp:include page="top.jsp"/>去掉就好了,有大神知道为什么吗?另外分页按键放在那里好些,我放到form表单下,就开始显示,点一下后就没有了
  7. 分组取topN
  8. 命令序列 ; & && ||
  9. 最省钱的爬虫解决方案,比IP代理更划算
  10. Spring中常见的设计模式——单例模式