Wenn Sie ein Set verwenden, um die aktiven Benutzer des Tages aufzuzeichnen, wird dadurch viel Platz verschwendet, wenn die Anzahl der Benutzer sehr groß ist. Daher stellt Redis eine Bitmap bereit, sodass Benutzer jedes Bit einzeln bedienen können. Der folgende Artikel wird Ihnen helfen, die Bitmaps in Redis zu verstehen. Ich hoffe, er wird Ihnen helfen!
Bitmap, also eine Datenstruktur, die aus einer großen Anzahl von Bits besteht (jedes Bit kann nur 0 und 1 sein), eignet sich in einigen Szenarien hauptsächlich zum Platzsparen und ist sinnvoll Daten,
Zum Beispiel einige große Zugriffsmengen vom Typ Bool, der 365-Tage-Check-in-Datensatz eines Benutzers, angemeldet ist 1, nicht angemeldet ist 0, wenn zum Speichern ein gewöhnlicher Schlüssel/Wert verwendet wird, wenn die Anzahl der Die Anzahl der Benutzer ist groß, und der benötigte Speicherplatz ist sehr groß.
Wenn Sie Bitmaps zur Speicherung verwenden, können 365 Bits zum Speichern von 365 Bits in 46 Bytes (eine etwas längere Zeichenfolge) umgewandelt werden, was viel Speicherplatz spart Eine Bitmap ist eigentlich eine gewöhnliche Zeichenfolge, also ein Byte-Array. Sie können get/set verwenden, um den Inhalt der gesamten Bitmap direkt abzurufen und festzulegen, oder Sie können getbit/setbit verwenden, um das Byte-Array als Bit-Array zu behandeln . bewältigen. [Verwandte Empfehlungen:
Redis-Video-Tutorial]
Bit-Operationen zum Festlegen von Zeichenfolgen verwenden
Normalerweise verwenden wir zum Festlegen von Zeichenfolgen den Set-Befehl. Im Folgenden verwenden wir setbit, um das Bit-Array festzulegen, und erhalten es schließlich in Form von a Zeichenfolge,Sie können sehen, dass der Binärcode von h 01101000 und der Binärcode von e 01100101 ist. Wir müssen nur Achten Sie auf die Position, an der das Bit 1 ist. Führen Sie dann setbit aus.
Es ist zu beachten, dass die Reihenfolge des Bit-Arrays und die Bit-Reihenfolge der Zeichen umgekehrt sind Die Positionen jedes einzelnen h-Zeichens sind 1/2/4 und das e-Zeichen ist 9/10/13/15 jede 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
setbit + get heißt Zero Deposit, Zero Deposit. Es handelt sich um eine bitweise Integration, bei der alle Daten direkt über den Schlüsselnamen abgerufen werden können Nullspeicherung und Nullabruf sowie Ganzzahlspeicherung und Ganzzahlspeicherung bedeuten, dass beim Array-Abruf das Bit direkt über die Position des Bits ermittelt wird.
Zero Deposit und Zero TakeWie Sie sehen können, setzen wir das Bit-Array des Schlüssels namens w entsprechend dem Setbit und setzen nur die Werte der drei Positionen 1/2/ 4 zu 1, wie unten gezeigt. Es enthält getbit w 3 und der Wert der dritten Position wird erhalten. Der Standardwert ist 0. Wenn es aus geschäftlicher Sicht ausgelöst wird, kann es verstanden werden, dass es insgesamt 4 gibt Tage der Anmeldung und am dritten Tag erfolgt keine Anmeldung , und erhalten Sie dann jedes Bit im Bit-Array von w über getbit. Sie können den erhaltenen Inhalt und das h-Zeichen oben sehen. Die Positionen 1/2/4 sind gleich 1 und der Rest ist 0
Hinweis
Das Bitarray von Redis wird automatisch erweitert. Wenn eine festgelegte Offset-Position den vorhandenen Inhaltsbereich überschreitet, wird das Bitarray automatisch um Null erweitert, d. h. die erweiterten Bits haben einen Wert von Standardmäßig 0.Wenn das Byte des entsprechenden Bits ein nicht druckbares Zeichen ist, zeigt redis-cli die hexadezimale Form des Zeichens an. Ein Byte besteht aus 8 Bits (Bits), wir müssen zwischen Bytes und Bits unterscheiden.
Statistik und Suche (bitcount/bitpos)
redis stellt die statistische Anweisung bitcount und die Bitmap-Suchanweisung bitpos zur Verfügung. bitcount wird verwendet, um die Anzahl der Einsen im angegebenen Positionsbereich zu zählen, und bitpos wird verwendet um den angegebenen Bereich zu finden. Die erste 0 oder 1, die darin erscheint.
我们可以通过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
之前介绍的 setbit / getbit 指定位的值都是单个位,如果要一次操作多个位,就必须使用管道来处理,
在redis3.2以后,提供了bitfield指令,可以一次对多个位进行操作,bitfield有三个子指令,分别是get/set/incrby, 都可以对指定位片段进行读写,
但是最多只能处理64个连续的位,如果超过64位,就需要使用多个子指令,bitfield可以一次执行多个子指令。
示例
下面对下图的位数组使用 bitfield 做一些操作
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
有符号数是指获取的位数组中的第一个位是符号位,剩下的才是值,如果第一位是1,就是负数,
无符号数表示非负数,没有符号位,获取的位数组全部都是值,有符号数最多可以获取64位,
无符号数只能获取63位,因为redis协议中的integer是有符号数,最大64位,不能传递64位的无符号值,
如果超出位数限制,redis就会告诉你参数错误。
上面的指令可以合并成一条指令,可以看到得到的结果是一样的,
bitfield w get u4 0 get u3 2 get i4 0 get i3 2
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"
incrby
incrby对指定范围的位进行自增操作,即++,这可能会发生溢出,如果增加了正数,会出现上溢出,如果增加的是负数,会出现下溢出,
redis默认的处理是折返,即如果出现了溢出,就将溢出的符号位丢掉,例如,如果是8位无符号数255,加1后就全部变成0,如果是8位有符号数127,加1后就溢出变成-128。
依然根据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
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
失败不执行
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)
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"
更多编程相关知识,请访问:编程视频!!
Das obige ist der detaillierte Inhalt vonIn diesem Artikel erfahren Sie mehr über die Bitmap in Redis (Bitmap).. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!