Jika anda menggunakan set untuk merekodkan pengguna aktif pada hari itu, ia akan membazirkan banyak ruang apabila bilangan pengguna sangat ramai. Oleh itu, redis menyediakan peta bit supaya pengguna boleh mengendalikan setiap bit secara individu. Artikel berikut akan membawa anda memahami bitmap dalam redis. Saya harap ia akan membantu anda!
Bitmap ialah struktur data yang terdiri daripada sejumlah besar bit (setiap bit hanya boleh menjadi 0 dan 1 ) , terutamanya sesuai untuk menjimatkan ruang dan merekod data secara bermakna dalam beberapa senario,
Contohnya, sebilangan besar akses jenis bool, rekod daftar masuk 365 hari pengguna, bilangan daftar masuk ialah 1, Jika tiada log masuk, ia adalah 0. Jika kunci/nilai biasa digunakan untuk storan, apabila bilangan pengguna ramai, jumlah ruang storan yang besar diperlukan.
Jika anda menggunakan peta bit untuk storan, 365 hari dalam setahun boleh disimpan dengan 365 bit ditukar kepada 46 bait (rentetan yang lebih panjang sedikit), yang menjimatkan banyak masa,
Intipati bitmap sebenarnya adalah rentetan biasa, iaitu tatasusunan bait Anda boleh menggunakan get/set untuk mendapatkan dan menetapkan kandungan keseluruhan bitmap. Anda juga boleh menggunakan getbit/setbit untuk merawat tatasusunan bait sebagai tatasusunan bit. [Cadangan berkaitan: Tutorial video Redis]
Biasanya menetapkan rentetan menggunakan perintah set di bawah kami menggunakan setbit menetapkan tatasusunan bit, dan akhirnya mendapatkannya dalam bentuk rentetan,
Mula-mula kita mendapat perwakilan binari bagi dua kod ASCII h dan e seperti berikut,
Anda boleh melihat bahawa kod binari h ialah 01101000 dan kod binari e ialah 01100101. Kita hanya perlu memberi perhatian kepada kedudukan di mana bit ialah 1, dan kemudian melakukan setbit,
diperlukan Ambil perhatian bahawa susunan susunan bit dan susunan bit aksara diterbalikkan Menurut prinsip ini, kami mengira bahawa kedudukan setiap 1 aksara h ialah 1/2/. 4, dan kedudukan setiap 1 aksara e ialah 9/10/13/15 ,
Jadi kita akan menggunakan setbit untuk menetapkan tatasusunan bit dan menetapkannya. sepadan pada setiap kedudukan (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
Deposit integer
Akhir sekali, dapatkan kunci data terus saya dapati saya baru dapat dia,
Gabungan setbit get dipanggil deposit sifar dan. integer. Deposit sifar ialah tetapan penyepaduan sedikit demi sedikit adalah untuk mendapatkan terus melalui nama kunci,
Begitu juga, kami juga boleh melakukan storan sifar dan perolehan sifar. retrieval Seluruh storan adalah untuk menggunakan rentetan secara langsung untuk menetapkan keseluruhan tatasusunan bit, dan pengambilan sifar adalah untuk melakukan kedudukan bit melalui kedudukan bit.
Sifar deposit dan sifar ambilan
Seperti yang anda lihat, kami menetapkan tatasusunan bit kunci w mengikut setbit, dan hanya menetapkan The nilai tiga kedudukan 1/2/4 ialah 1. Dalam rajah di bawah, terdapat getbit w 3 untuk mendapatkan nilai kedudukan ketiga. Lalai adalah 0 pada masa ini difahamkan sebagai jumlah 4 hari daftar masuk , tiada log masuk pada hari ketiga,
Deposit secara keseluruhan dan kecil. jumlah yang perlu dikeluarkan
Seperti yang ditunjukkan pada sebelah petang, kita Untuk kunci w, aksara h ditetapkan secara langsung, dan kemudian setiap bit dalam tatasusunan bit w diperoleh melalui getbit. Anda boleh lihat kandungan yang diperolehi adalah sama dengan kandungan binari bagi aksara h di atas Kedudukan 1/2/4 ialah 1, selebihnya ialah 0
<. . lalai. Jika bait bit yang sepadan ialah aksara tidak boleh dicetak, redis-cli akan memaparkan bentuk perenambelasan aksara itu.
Bait ialah 8 bit (bit) adalah perlu untuk membezakan antara bait dan bit.
redis menyediakan statistik arahan bitcount dan bitmap arahan carian bitpos,
我们可以通过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"
更多编程相关知识,请访问:编程视频!!
Atas ialah kandungan terperinci Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!