Rumah  >  Artikel  >  pangkalan data  >  Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

青灯夜游
青灯夜游ke hadapan
2021-12-16 10:02:504224semak imbas

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!

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

Bitmap

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,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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]

Gunakan operasi bit untuk menetapkan rentetan

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,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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 ,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

Akhir sekali, dapatkan kunci data terus saya dapati saya baru dapat dia,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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,

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

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

Artikel ini akan membawa anda memahami bitmap dalam redis (bitmap)

<. . 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.

  • Statistik dan carian (bitcount/bitpos)
  • redis menyediakan statistik arahan bitcount dan bitmap arahan carian bitpos,

  • bitcount digunakan untuk mengira bilangan 1 dalam julat kedudukan yang ditentukan, dan bitpos digunakan untuk mencari 0 atau 1 pertama yang muncul dalam julat yang ditentukan.

我们可以通过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

bitfield

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

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

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

示例

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

Artikel ini akan membawa anda memahami bitmap dalam 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

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

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

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

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

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

bitfield w get u4 0 get u3 2 get i4 0 get i3 2

Artikel ini akan membawa anda memahami bitmap dalam 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"

incrby

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

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

1Artikel ini akan membawa anda memahami bitmap dalam 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

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!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam