Maison > base de données > Redis > Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

青灯夜游
Libérer: 2021-12-16 10:02:50
avant
4237 Les gens l'ont consulté

Si vous utilisez un ensemble pour enregistrer les utilisateurs actifs de la journée, cela gaspillera beaucoup d'espace lorsque le nombre d'utilisateurs est très important. Par conséquent, Redis fournit un bitmap afin que les utilisateurs puissent utiliser chaque bit individuellement. L'article suivant vous fera comprendre les bitmaps dans Redis. J'espère qu'il vous sera utile !

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Bitmap

Bitmap, c'est-à-dire une structure de données composée d'un grand nombre de bits (chaque bit ne peut être que 0 et 1), est principalement adapté pour économiser de l'espace dans certains scénarios et est significatif. données,

Par exemple, certaines grandes quantités d'accès de type bool, l'enregistrement d'enregistrement de 365 jours d'un utilisateur, connecté est 1, non connecté est 0, si une clé/valeur ordinaire est utilisée pour stocker, lorsque le nombre de les utilisateurs sont nombreux, l'espace de stockage requis est très grand.

Si vous utilisez des bitmaps pour le stockage, 365 bits peuvent être utilisés pour stocker 365 jours par an. 365 bits sont convertis en 46 octets (une chaîne légèrement plus longue), ce qui permet d'économiser beaucoup d'espace de stockage

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

L'essence. d'un bitmap est en fait une chaîne ordinaire, c'est-à-dire un tableau d'octets. Vous pouvez utiliser get/set pour obtenir et définir directement le contenu de l'intégralité du bitmap, ou vous pouvez utiliser getbit/setbit pour traiter le tableau d'octets comme un tableau de bits. . traiter. [Recommandations associées : Tutoriel vidéo Redis]

Utiliser des opérations sur les bits pour définir des chaînes

Normalement, la définition des chaînes utilise la commande set Ci-dessous, nous utilisons setbit pour définir le tableau de bits, et enfin l'obtenons sous la forme d'obtention d'un. chaîne,

Nous obtenons d'abord la représentation binaire des deux codes ASCII h et e comme suit

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Vous pouvez voir que le code binaire de h est 01101000 et le code binaire de e est 01100101. faites attention à la position où le bit est 1. Effectuez ensuite setbit,

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Il est à noter que l'ordre du tableau de bits et l'ordre des bits des caractères sont inversés. Selon ce principe, nous calculons que le. les positions de chaque 1 du caractère h sont 1/2/4 et le caractère e est 9/10/13/15,

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Nous allons donc utiliser setbit pour définir un tableau de bits et définir le tableau de bits correspondant à chaque position (1/2/4/9/10/13/15) 1.

setbit data 1 1
setbit data 2 1
setbit data 4 1
setbit data 9 1
setbit data 10 1
setbit data 13 1
setbit data 15 1
Copier après la connexion

Set bit + get

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Enfin, obtenez la clé de données directement, et vous constaterez que vous obtenez simplement lui, la combinaison de

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

get est appelée zéro dépôt, zéro dépôt. Il s'agit d'un réglage petit à petit qui signifie obtenir toutes les données directement via le nom de la clé

De même, nous pouvons également. effectuer le stockage zéro et la récupération de zéro, et le stockage entier et la récupération de zéro signifie utiliser directement une chaîne pour définir le bit entier. Pour les tableaux, la récupération de zéro consiste à obtenir le bit via la position du bit.

Zéro dépôt et zéro prise

Comme vous pouvez le voir, nous définissons le tableau de bits de la clé appelée w en fonction du setbit, et définissons uniquement les valeurs​​des trois positions 1/2/ 4 à 1, comme indiqué ci-dessous. Il contient getbit w 3 et la valeur de la troisième position est obtenue. La valeur par défaut est 0. S'il est déclenché d'un point de vue commercial, on peut comprendre qu'il y en a un total de 4. jours de connexion, et il n'y a pas de connexion le troisième jour

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Stockez zéro et obtenez

Comme indiqué dans l'après-midi, nous définissons directement un caractère h pour la clé de w. , puis obtenez chaque bit du tableau de bits de w via getbit. Vous pouvez voir le contenu obtenu et le caractère h ci-dessus. Les positions 1/2/4 sont 1, et le reste est 0

. Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

Remarque

  • Le tableau de bits de redis est automatiquement étendu si une position de décalage définie dépasse La plage de contenu existante agrandira automatiquement le tableau de bits de zéro, c'est-à-dire que les bits développés auront une valeur. de 0 par défaut.

  • Si l'octet du bit correspondant est un caractère non imprimable, redis-cli affichera la forme hexadécimale du caractère.

  • Un octet fait 8 bits (bits), il faut distinguer les octets et les bits.

Statistiques et recherche (bitcount/bitpos)

redis fournit l'instruction statistique bitcount et l'instruction de recherche bitmap bitpos

bitcount est utilisé pour compter le nombre de 1 dans la plage de positions spécifiée, et bitpos est utilisé. pour trouver la plage spécifiée. Le premier 0 ou 1 qui apparaît à l'intérieur.

我们可以通过bitcount统计用户一共签到了多少天,通过bitpos指令查找用户从哪一天开始第一次签到,

如果指定了范围参数[start, end],就可以统计在某个时间范围内用户签到了多少天以及用户自某天以后的哪天开始签到,

但是需要注意的是,start和end参数是字节索引,也就是说,指定的位范围必须是8的倍数,

而不能任意指定,所以我们无法直接计算某个月内用户签到了多少天,如果需要计算的话,

可以使用getrange命令取出该月覆盖的字节内容,然后在内存中进行统计,例如2月覆盖了10-12个字节,就使用 getrange w 8 12 。

127.0.0.1:6379> set w hello    

OK

127.0.0.1:6379> bitcount w      # 所有字符中有多少个1

(integer) 21

127.0.0.1:6379> bitcount w 0 0   # 第一个字符中 1 的位数

(integer) 3

127.0.0.1:6379> bitcount w 0 1   # 前两个字符中 1 的位数

(integer) 7

127.0.0.1:6379> bitpos w 0       # 第一个 0 位

(integer) 0

127.0.0.1:6379> bitpos w 1       # 第一个 1 位

(integer) 1

127.0.0.1:6379> bitpos w 1 1 1       # 从第二个字符算起,第一个1位

(integer) 9

127.0.0.1:6379> bitpos w 1 2 2       # 从第三个字符算起,第一个1位

(integer) 17
Copier après la connexion

bitfield

之前介绍的 setbit / getbit 指定位的值都是单个位,如果要一次操作多个位,就必须使用管道来处理,

在redis3.2以后,提供了bitfield指令,可以一次对多个位进行操作,bitfield有三个子指令,分别是get/set/incrby, 都可以对指定位片段进行读写,

但是最多只能处理64个连续的位,如果超过64位,就需要使用多个子指令,bitfield可以一次执行多个子指令。

示例

下面对下图的位数组使用 bitfield 做一些操作

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

127.0.0.1:6379> bitfield w get u4 0   # 从第1个位开始取4个位,结果是无符号数(u)

1) (integer) 6

127.0.0.1:6379> bitfield w get u3 2   # 从第3个位开始取3个位,结果是无符号数(u)

1) (integer) 5

127.0.0.1:6379> bitfield w get i4 0   # 从第1个位开始取4个位,结果是有符号数(i)

1) (integer) 6

127.0.0.1:6379> bitfield w get i3 2   # 从第3个位开始取3个位,结果是有符号数(i)

1) (integer) -3
Copier après la connexion

有符号数是指获取的位数组中的第一个位是符号位,剩下的才是值,如果第一位是1,就是负数,

无符号数表示非负数,没有符号位,获取的位数组全部都是值,有符号数最多可以获取64位,

无符号数只能获取63位,因为redis协议中的integer是有符号数,最大64位,不能传递64位的无符号值,

如果超出位数限制,redis就会告诉你参数错误。

上面的指令可以合并成一条指令,可以看到得到的结果是一样的,

bitfield w get u4 0 get u3 2 get i4 0 get i3 2
Copier après la connexion

Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

set修改

我们从第9个位开始,用8个无符号数替换已经存在的8个位,其实就是把第二个字符替换了,由e变成a(它的ASCII码是97),可以看到结果也变成了 hallo

127.0.0.1:6379> bitfield w set u8 8 97

1) (integer) 101

127.0.0.1:6379> get w

"hallo"
Copier après la connexion

incrby

incrby对指定范围的位进行自增操作,即++,这可能会发生溢出,如果增加了正数,会出现上溢出,如果增加的是负数,会出现下溢出,

redis默认的处理是折返,即如果出现了溢出,就将溢出的符号位丢掉,例如,如果是8位无符号数255,加1后就全部变成0,如果是8位有符号数127,加1后就溢出变成-128。

1Cet article vous amènera à comprendre le bitmap dans Redis (bitmap)

依然根据hello字符,来演示一下 incrby

127.0.0.1:6379> set w hello

OK

127.0.0.1:6379> bitfield w get u4 2     # 从第3位开始取4个无符号整数,第一次是10

1) (integer) 10

127.0.0.1:6379> bitfield w incrby u4 2 1

1) (integer) 11

127.0.0.1:6379> bitfield w incrby u4 2 1

1) (integer) 12

127.0.0.1:6379> bitfield w incrby u4 2 1

1) (integer) 13

127.0.0.1:6379> bitfield w incrby u4 2 1

1) (integer) 14

127.0.0.1:6379> bitfield w incrby u4 2 1

1) (integer) 15
127.0.0.1:6379> bitfield w incrby u4 2 1   #到这里的时候,已经溢出折返成0了

1) (integer) 0
Copier après la connexion

bitfield指令提供溢出策略子指令 overflow,用户可以选择溢出行为,默认是折返(wrap),还可以选择失败(fail) 即报错不执行,还有饱和截断(sat) 即超过范围就停留在最大或最小值,

overflow指令只影响接下来的第一条指令,这条指令执行完以后,溢出策略就会变成默认值 折返(wrap)。

饱和截断

127.0.0.1:6379> set w hello

OK

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 11

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 12

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 13

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 14

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 15

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1 # 接下来的都将是保持最大值

1) (integer) 15

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 15

127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1

1) (integer) 15
Copier après la connexion

失败不执行

127.0.0.1:6379> set w hello

OK

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (integer) 11

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (integer) 12

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (integer) 13

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (integer) 14

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (integer) 15

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1 # 接下来的都是失败

1) (nil)

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (nil)

127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1

1) (nil)
Copier après la connexion

get/set/incrby一起执行

127.0.0.1:6379> bitfield w set u4 1 0 get u4 1 incrby u4 2 1

1) (integer) 0

2) (integer) 0

3) (integer) 1

127.0.0.1:6379> get w

"\x04ello"
Copier après la connexion

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal