在各个项目中,我们都可能需要用到签到和统计功能。签到后会给用户一些礼品以此来吸引用户持续在该平台进行活跃。
一般情况下签到功能我们可以使用MySQL来完成,比如下表:
CREATE TABLE `tb_sign` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint(20) unsigned NOT NULL COMMENT '用户id',
`year` year(4) NOT NULL COMMENT '签到的年',
`month` tinyint(2) NOT NULL COMMENT '签到的月',
`date` date NOT NULL COMMENT '签到的日期',
`is_backup` tinyint(1) unsigned DEFAULT NULL COMMENT '是否补签',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;
用户一次签到,就是一条记录,假如有1000万用户,平均每人每年签到次数为10次,则这张表一年的数据量为1亿条。每签到一次需要使用(8 + 8 + 1 + 1 + 3 + 1)共22 字节的内存,一个月则最多需要600多字节。
这样的坏处,占用内存太大了,极大的消耗内存空间! 对此签到功能,我们可以通过Redis中的BitMap(位图)功能来实现!!!
一、Redis中BitMap(位图)的介绍
大家都知道redis的五种常用类型string、hash、list、set、zset,那除此之外,redis还有一些特殊类型,bitmap就属于其中一种,接下来就对bitmap做一下详细说明。
BitMap(位图)不是实际的数据类型,而是在字符串类型上定义的一组面向位的操作。
位图(bitmap)同样属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由8个Bit位组成。位图结构正是使用 “位” 来实现存储的,它通过将比特位设置为“0”或“1”来达到数据存取的目的,这大大增加了value的存储数量,它的存储上限为2^32(约有42亿条数据记录)。
位图本质上就是一个普通的字节串,也就是 bytes 数组。我们可以使用 getbit 或者 setbit 命令来处理这个位数组,位图的结构如下所示: