关于redis:redis中bitmap使用场景结束员工统计打卡

2次阅读

共计 3427 个字符,预计需要花费 9 分钟才能阅读完成。

Redis 的 Bitmap 是一种非凡的数据结构,它能够存储一组二进制位,并对这些二进制位进行位运算。Bitmap 在 Redis 中被宽泛用于计数器、统计、排重等场景。

一、命令介绍

1、SETBIT key offset value

将指定偏移量的二进制位设置为给定的值(0 或 1)。例如,SETBIT mybitmap 1001 1 将 mybitmap 中偏移量为 1001 的二进制位设置为 1。

2、GETBIT key offset

获取指定偏移量的二进制位的值(0 或 1)。例如,GETBIT mybitmap 1001 将返回 mybitmap 中偏移量为 1001 的二进制位的值。

3、BITCOUNT key [start end]

计算指定范畴内所有二进制位被设置为 1 的个数。例如,BITCOUNT mybitmap 0 1023 将返回 mybitmap 中偏移量从 0 到 1023 的所有二进制位中被设置为 1 的个数。

4、BITOP operation destkey key [key …]

对多个指定的 bitmap 进行位运算,并将后果存储到 destkey 中。operation 参数能够是 AND、OR、XOR、NOT 四种运算之一。例如,BITOP AND myresult mybitmap1 mybitmap2 将 mybitmap1 和 mybitmap2 中的所有二进制位进行 AND 运算,并将后果存储到 myresult 中。

Bitmap 的次要长处是占用的空间十分小,一个 bitmap 只须要占用 1MB 的内存,就能够存储 8 1024 1024 个二进制位。Bitmap 还反对十分高效的位运算操作,能够疾速实现简单的统计、计算等性能。

不过,因为 Redis Bitmap 只能存储二进制位,因而只实用于对数据量比拟小、构造比较简单的数据进行存储和计算。对于构造比较复杂的数据或者须要高性能的大规模数据处理场景,倡议应用其余类型的数据结构和分布式计算框架。

二、了解 bitmap 中偏移量 offset 的概念

当咱们应用 Redis 的 Bitmap 存储数据时,实际上是将数据转换为一组二进制位,并将这些二进制位存储在一个字符串中。偏移量 offset 指的是这个字符串中的地位,用于标识每个二进制位的地位。

上面举一个具体的例子来阐明。假如咱们有一个员工打卡零碎,须要记录每个员工每天的打卡状况,包含上午打卡和下午打卡两个工夫点。咱们能够应用 Redis Bitmap 存储这些数据,其中每个二进制位示意一个员工在某个工夫点是否打卡。

假如咱们有 1000 个员工,须要记录每个员工在某一天的打卡状况。咱们能够创立一个名为 “checkin:20220306” 的 Bitmap,用于存储这些数据。在这个 Bitmap 中,每个员工的打卡状况占用两个二进制位,一个示意上午打卡,一个示意下午打卡。偏移量 offset 示意每个员工在这个 Bitmap 中占用的地位。

假如咱们规定每个员工在 Bitmap 中占用的地位为 2 个二进制位。那么,员工编号为 1001 的员工在 Bitmap 中的占用地位就是 2 * 1001 = 2002。如果这个员工在上午打卡了,咱们能够应用 SETBIT 命令将这个地位的二进制位设置为

SETBIT checkin:20220306 2002 1

如果这个员工在下午也打卡了,咱们能够应用 SETBIT 命令将这个地位的第二个二进制位设置为 1:

SETBIT checkin:20220306 2003 1

如果咱们须要查问这个员工在某个工夫点是否打卡,能够应用 GETBIT 命令查问对应的二进制位的值:

GETBIT checkin:20220306 2002  # 查问上午打卡状况
GETBIT checkin:20220306 2003  # 查问下午打卡状况

通过 Bitmap,咱们能够十分高效地存储和查问大量的打卡数据,并进行一些高级的计算和统计操作。

三、下面 Demo 中,如何把员工编号 1001 转换成 offset?

在下面的示例中,咱们假如每个员工在 Bitmap 中占用的地位为 2 个二进制位。这意味着每个员工在 Bitmap 中的起始偏移量为 2 员工编号。例如,员工编号为 1001 的员工在 Bitmap 中的起始偏移量为 2 1001 = 2002。

具体来说,如果咱们有 n 个员工,须要应用 Bitmap 存储这些数据,每个员工在 Bitmap 中占用的二进制位数为 m,那么咱们能够应用如下公式将员工编号转换为偏移量 offset:

offset = m * (employee_id - 1)

其中,employee_id 是员工编号,从 1 开始编号。因为 Redis 中字符串的下标也是从 0 开始的,因而咱们须要将员工编号减去 1。例如,如果咱们有 1000 个员工,每个员工在 Bitmap 中占用 2 个二进制位,那么员工编号为 1001 的员工在 Bitmap 中的起始偏移量为 2 * (1001 – 1) = 2000。

四、bitmap 中 key 的设计

1、从员工角度,统计员工每日,每月的打卡状况,如何设计 bitmap 的 key 和 offset

对于每个员工的打卡状况,咱们能够应用 Redis 的 Bitmap 来存储。对于每个员工,咱们能够为其创立一个以日期为后缀的键,例如 “checkin:employee_id:20220306” 示意员工在 2022 年 3 月 6 日的打卡状况。

为了不便统计每个员工在每日、每月的打卡状况,咱们能够为每个员工创立两个非凡的键,别离用于记录该员工在某个月份内的所有打卡数据和该员工在某一天内的所有打卡数据。例如:

“checkin:employee_id:daily:20220306” 示意员工在 2022 年 3 月 6 日的所有打卡数据。
“checkin:employee_id:monthly:202203” 示意员工在 2022 年 3 月的所有打卡数据。
这些键的值都是一个 Bitmap,能够应用 Redis 的 BITOP 命令对多个 Bitmap 进行位运算,从而实现对多个键对应的 Bitmap 进行统计。

对于偏移量 offset,咱们能够将其设为员工的编号,例如员工编号为 1001 的员工在 “checkin:employee_id:daily:20220306” 对应的 Bitmap 中的偏移量为 1001。当员工在某一天内打卡时,咱们能够应用 SETBIT 命令将该员工在对应的 Bitmap 中的位设置为

SETBIT checkin:1001:daily:20220306 1001 1

这样,咱们能够疾速地获取该员工在某一天内的打卡状况,例如:

GETBIT checkin:1001:daily:20220306 1001

将返回该员工在 2022 年 3 月 6 日是否打卡的信息(0 示意未打卡,1 示意已打卡)。

相似地,咱们能够应用 BITOP 命令对多个 “checkin:employee_id:daily:” 和 “checkin:employee_id:monthly:” 键的 Bitmap 进行统计,从而失去每个员工在每日、每月的打卡状况。

2、从工夫角度,统计每月,每日所有员工的打卡,如何设计 bitmap 的 key 和 offset

要统计每月、每日所有员工的打卡状况,咱们能够创立两个键:

1) 一个键用于记录所有员工在某一天的打卡状况,例如 “checkin:daily:20220306” 示意所有员工在 2022 年 3 月 6 日的打卡状况。

2) 另一个键用于记录所有员工在某个月份内的打卡状况,例如 “checkin:monthly:202203” 示意所有员工在 2022 年 3 月的打卡状况。

这些键的值都是一个 Bitmap,能够应用 BITOP 命令对多个 Bitmap 进行位运算,从而实现对多个键对应的 Bitmap 进行统计。

对于偏移量 offset,咱们能够将其设为员工的编号,例如员工编号为 1001 的员工在 “checkin:daily:20220306” 对应的 Bitmap 中的偏移量为 1001。当员工在某一天内打卡时,咱们能够应用 SETBIT 命令将该员工在对应的 Bitmap 中的位设置为 1,例如:

SETBIT checkin:daily:20220306 1001 1

这样,咱们能够疾速地获取某个员工在某一天内的打卡状况,例如:

GETBIT checkin:daily:20220306 1001

将返回该员工在 2022 年 3 月 6 日是否打卡的信息(0 示意未打卡,1 示意已打卡)。

相似地,咱们能够应用 BITOP 命令对多个 “checkin:daily:” 和 “checkin:monthly:” 键的 Bitmap 进行统计,从而失去每日、每月所有员工的打卡状况。

五、在线网址推荐:
https://try.redis.io/

正文完
 0