欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

读书笔记——《redis入门指南(第2版)》第三章 入门

程序员文章站 2024-02-04 21:56:40
3 、redis的5种数据类型及相应命令 redis不区分命令大小写。 string 512m 一个散列类型键可包含至多232-1个字段 一个列表类型键最多能容纳232-1个元素 一个集合类型键最多能容纳232-1个元素 3.1、一些实用的基础命令 keys pattern exists key 返 ......

3 、redis的5种数据类型及相应命令

redis不区分命令大小写。

 读书笔记——《redis入门指南(第2版)》第三章 入门 

string 512m

一个散列类型键可包含至多232-1个字段

一个列表类型键最多能容纳232-1个元素

一个集合类型键最多能容纳232-1个元素

  

3.1、一些实用的基础命令

keys pattern

 读书笔记——《redis入门指南(第2版)》第三章 入门

读书笔记——《redis入门指南(第2版)》第三章 入门

exists key

返回值:存在返回1,不存在返回0

del      key1 [key2 key3 ...]

返回值:删除的键的个数

type    key

返回值:string、hash、list、set、zset

 

技巧:删除所有复合规则的键(注意del不支持通配符)

方案1

(推荐)

在linux命令行执行下面命令:

[root@tkafka ~]# redis-cli del `redis-cli keys "a*"`

注意用的反单引号,将redis-cli keys "a*"命令的结果作为redis-cli del命令的参数。

方案2

在linux命令行执行下面命令:

[root@tkafka ~]# redis-cli keys "a*" | xargs redis-cli del

利用的是linux管道和xargs命令

 

3.2、字符串类型[string]

         字符串类型是redis中最基本的数据类型,是其它4种数据类型的基础,例如列表类型是以列表的形式组织字符串,集合类型是用集合的形式组织字符串。

string可存储任何形式的字符串,比如数值形式的字符串,二进制形式的字符串,json格式的字符串等,也就是说string能存储数值、图片、json化对象等。

基础命令

set          key value

get          key

 

mset        key value [key2 value2 ...]

mget       key [key2 ...]

 

append   key value

描述:向键值的末尾追加value,如果键不存在则相当于set key value。

返回值:追加后的字符串长度。

strlen      key

你好(6)  ab(2)

-- 当字符串类型存储的是【整数形式的字符串】时,才可以用的命令,否则报错:      

incr          key

incrby      key increment

         注意:若key不存在,incr命令会默认key的值为0,再进行递增;若key的值不是整数形式的字符串,redis会报错。

         返回值:返回递增后的值。

decr         key

decrby     key decrement

这两个指令功能都可以用 incrby key increment 实现

incrbyfloat key increment

 

--位操作命令:

getbit      key offset

 

setbit      key offset value

 

bitcount key [startbyteindex] [endbyteindex]

统计字符串类型键中值是1的二进制位的个数。

可以加两个参数来限制统计的字节范围[0开始]。

bitop        operation destkey key1 key2 … keyn

对多个字符串类型键进行位运算,并将结果存储destkey参数指定的键中,operation可选and、or、xor、not。

bitpos      key bitvalue [startbyteindex] [endbyteindex]

获得指定键中第一个位值为0或1的二进制位的偏移量[0开始]。bitvalue可选0、1。

可以加两个参数来限制查询的字节范围[0开始]。

     

 

注意:包括incr在内的所有redis命令都是原子操作,无论多少客户端同时连接,都不会出现并发性的安全问题。但是如果你希望在程序自己写一个方法来实现incr命令的效果,就得自己在代码层面保证该方法是线程安全的。

实践

1、键命名实践:【对象类型名:对象id:对象属性名】;如user:1:age

多个单词用“.”分隔,如user:2:first.name

2、  文章访问量

对每篇文章都用一个键article:articleid:visit.count来记录该篇文章的访问量,访问一次就incr一次。

3、自增id

为一类对象如article定义一个键如articles:count,用于保存该类对象的数量。

每要增加一个该类对象时都先做一次incr,incr的返回值即可作为该新增对象的id。

4、存储文章数据(下节会讲这种实现方式的缺陷)

键名article:articleid:article.data  键值:articletitle,articleauthor,aticlecontent,articletime序列化后的字符串。

获取文章数据时,获取键值后进行反序列化即可。

5、位操作命令实践

 读书笔记——《redis入门指南(第2版)》第三章 入门

 

 

 

3.3、散列类型[hash]

 读书笔记——《redis入门指南(第2版)》第三章 入门

 redis是采用字典结构<key, value>存储数据的,在此之上,散列类型键的键值也是字典结构的<key, <field, value>>,其中的value只能是基础的字符串类型。redis中的数据类型不支持数据类型嵌套,也就是说hash、list、set、zset中的元素只能是基础的字符串类型。

         散列类型适合存储对象。键命名:对象类名:对象id

         对于关系型数据库中的表,由于其是二维表结构的,表中每条记录拥有的字段是一致的,无法单独为某条记录增减属性而不影响其它记录;散列类型则没有此限制,例如user:1的字段为name、age、phone,但user:2的字段为name、sex、city。

hset         key field value

hsetnx     key field value

hget         key field

         调用hset时不用区分是插入属性还是更新属性,且当key不存在时,hset还会自动创建key。

         返回值:1表示是执行的是插入操作,0表示执行的是更新操作。

         hsetnx只在字段不存在时才进行赋值[not exists]。

hmset     key field value [field2 value2 ...]

hmget     key field [field2 ...]

 

hexist      key field

返回值:1或0

hdel         key field [field2 …]

 

hincrby    key field increment

         返回值为增长后的字段值。        

         当key不存在时,hincrby命令会自动创建key,并默认field在增长前的字段值为0。

hgetall    key

hkeys       key

hvals        key

hlen         key

很多语言的redisclient会将hgetall的返回结果封装成编程语言中的对象

 

实践

1、  存储文章数据(本节开始有讲到用字符串来存储对象的缺点,这里实践下用散列来存储对象)

<article:articleid,<文章各字段名,字段值>>  字段有articletitle,articleauthor,aticlecontent,articletime

2、  存储文章缩略名【slug】

         缩略名用于构成文章网址的一部分,每篇文章的缩略名必须是唯一的,发布文章时需要验证用户输入的缩略名是否已被占用;系统还应提供根据缩略名获取文章id的功能。

         <slug.to.id,<slugname,articleid>>用于存储文章缩略名和文章id之间的映射关系。”hexists slug.to.id slugname”可以验证缩略名是否已被占用;”hget slug.to.id slugname”可以根据缩略名获取文章id;另外修改文章缩略名时要修改<slug.to.id,<slugname,articleid>>中相应字段。

 

3.4、列表类型[list]

列表类型(list)内部使用双向链表结构实现的。向链表两端添加元素的时间复杂度为o(1),获取元素时获取越接近两端的元素就越快;跟索引有关的操作较慢。

 读书笔记——《redis入门指南(第2版)》第三章 入门

基础命令

lpush|rpush   key value [value2 ...]

返回值:增加元素后列表的长度

lpop|rpop       key

返回值:被移除的元素值

llen                  key

实现上,redis会直接读取现成的值,所以时间复杂度为o(1)

lrem                key count value

删除列表中前count个值为value的元素

返回值:实际删除的元素个数

 读书笔记——《redis入门指南(第2版)》第三章 入门

linsert     key before|after pivot value

         描述:先从左到右的从列表中查找值为pivot的元素,然后根据第二个参数是before还是after来决定将value插入到该元素之前还是之后。

         返回值:插入后,列表中元素个数

用作数组【效率较低】

lrange     key start end

         描述:获取列表片段[startindex, endindex],索引从0开始

         注意:lrange支持负索引,表示从最右边开始数,-1表示最右边第一个元素,即”lrange key 0 -1”可以获取列表中所有元素。

ltrim         key start end

删除指定索引范围之外的所有元素

 读书笔记——《redis入门指南(第2版)》第三章 入门

lindex      key index

 

lset          key index value

 

用做栈(lpush + lpop 或 rpush + rpop

用作队列(lpush + rpop 或 rpush + lpop

rpoplpush srcqueue destqueue

         描述:从srcqueue列表类型键的右边弹出一个元素,然后将其加入到destqueue列表类型键的左边,并返回这个元素,当然整个过程是原子的。         rpoplpush可用于在多个队列间传递数据

 读书笔记——《redis入门指南(第2版)》第三章 入门

 

实践

1、存储按时间排序的文章id列表

         用列表类型键articles:list来存储文章id列表,发布新文章时要使用lpush将新文章的id加入此列表中,删除文章时要使用lrem把列表中的相应文章id移除掉,这样就可以用lrange来实现文章分页了。

         “lrange articles:list (pageindex-1)*pagesize pageindex*pagesize-1”

 读书笔记——《redis入门指南(第2版)》第三章 入门

2、存储评论列表

         用列表类型键article:articleid:comments来存储某篇文章的所有评论。

 读书笔记——《redis入门指南(第2版)》第三章 入门

 

 

 

3.5、集合类型[set]

         集合类型(set)内部是使用值为空的hashtable<e,~>实现的,常用的操作如add(e)、remove(e)、contains(e)时间复杂度都是o(1)。

 读书笔记——《redis入门指南(第2版)》第三章 入门

基础命令

sadd         key member [member2 ...]

         如果key不存在则会自动创建

         返回值:成功插入的元素数量(插入操作前集合中已存在的元素会被忽略插入,不参与计数)

srem       key member [member2 ...]

返回删除成功的元素个数

smembers      key

返回集合中所有元素

sismember     key member

判断元素是否在集合中

scard               key

返回集合中元素个数

随机操作

spop                 key

从集合中随机弹出一个元素

srandmember key [count]

随机从集合中获取一个元素,可以指定count参数来随机获取多个元素。

 读书笔记——《redis入门指南(第2版)》第三章 入门

读书笔记——《redis入门指南(第2版)》第三章 入门

集合间运算命令

sdiff          key [key2 …]

差集(a-b:所有属于a但不属于b的元素)。

“sdiff a b c”表示(a-b)-c

sinter       key [key2 …]

交集

sunion      key [key2 …]

并集

sdiffstore                  destcollection key1 [key2 ...]

这3个命令会将运算结果存储在destcollection键中而不会返回,常用于需要进行多步集合运算的场景中,如需要先进行差集再将结果和其它键计算交集。

sinterstore       destcollection key1 [key2 ...]

sunionstore     destcollection key1 [key2 ...]

 

 

实践

1、存储文章标签

         由于一个文章的所有标签不会重复,且在展示时没要求标签顺序,所以可以用集合类型键article:articleid:tags来存储文章标签。

 读书笔记——《redis入门指南(第2版)》第三章 入门

2、通过标签搜索文章

         为每个标签定义一个集合类型键tag:tagname:articles来存储该标签下的文章id列表。用smember可得到一个标签下所有文章;用sinter可得到同属于某几个标签的文章。

 

 

 

3.6、有序集合类型[zset]

         在集合类型的基础上,有序集合类型为集合中的每个元素都关联了一个分数,所以比集合类型多了一些与分数有关的操作。有序集合中的元素不能重复,但是不同元素的分数可以相同。

有序集合类型与列表类型

相似点

区别

1)有序

2)可以获取某一范围的元素

1)实现方式不同

 读书笔记——《redis入门指南(第2版)》第三章 入门

2)列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)

3)有序集合比列表更耗内存

 

基础命令

zadd        key score member [score2 member2 ..]

         描述:加入一个指定分数的元素,若元素已存在则更新该元素的分数。分数可以是整数、double、+inf(正无穷)、-inf(负无穷)。

         返回值:新加入到集合中的元素个数

zscore     key member

返回元素的分数

zincrby   key increment member

描述:增加某个元素的分数,分数可为负数。

返回值:更改后的分数

zcard        key

返回元素数量,类比scard

zrem       key member [member2 ...]

返回成功删除的元素数量(不包含本来就不存在的元素)

跟顺序相关的命令

zrange              key start end [withscores]

         zrange命令会按照元素分数从小到大的顺序返回索引从start到end之间的所有元素[start, end],zrerange则是从大到小。加上”withscores”参数表示需要同时获取元素的分数。

         zrange可类比列表的lrange,索引都是从0开始,负数索引表示从最右边开始往前数(-1表示最右边的元素)

         zrange命令时间复杂度为o(log(n+m)),n为有序集合的基数,m为要返回的元素个数。

         对于分数相同的元素,redis会按照字典序(0<9<a<z<a<z)来进行排列。

 读书笔记——《redis入门指南(第2版)》第三章 入门

zrevrange      key start end [withscores]

zrangebyscore        key min max

         [withscores] [limit offset count]

         zrangebyscore命令按元素分数从小到大的顺序返回分数在min和max之间的所有元素[min, max]。

         如果希望分数范围不包含端点值,可以在分数前加上”(”,例如”80 (100”表示[80, 100)。min和max支持无穷大+inf和-inf,例如”(80 +inf”表示80分以上。

         limit offset count和在sql中的语义一样,表示在获得元素列表的基础上向后偏移offset个元素,然后获取前count个元素。

zrevrangebyscore key max min

         [withscores] [limit offset count]

zremrangebyrank         key start end

按排名范围删除,返回删除的元素数量

zremrangebyscore        key min max

按分数范围删除,返回删除的元素数量

zcount                               key min max

获取指定分数范围的元素个数

zrank                                 key member

获得指定元素的排名(0开始)

zrevrank                          key member

集合间运算命令(用到再查)

zinterstore …

计算有序集合的交集

zunionstore …

计算有序集合的并集

 

实践

1按文章点击量顺序获取文章列表

集合类型键articles:article.visit.count,以文章id作为集合元素,以文章访问量作为元素分数。没当一篇文章被访问时,就用”zincrby articles:article.visit.count 1 aticleid”来更新文章访问量。

这样,通过”zrerange articles:article.visit.count (pageindex-1)*pagesize pageindex*pagesize-1”命令即可实现按照文章点击量顺序获取文章列表。通过”zscore articles:article.visit.count articleid”可获取某篇文章的访问量。有了这个键,就不再用3.2节定义的字符串类型键article:articleid:visit.count来记录单个文章的访问量了。

2改进按时间顺序排列文章

         3.4节的列表类型键实现,在更改元素顺序上比较麻烦;为了能够*更改文章发布时间,这里采用有序集合类型代替列表类型,以文章id作为集合元素,文章发布的unix时间(一个秒数)作为元素分数;通过修改元素的分数来实现更改文章发布时间,通过zrevrangebyscore来实现获取指定时间范围的文章列表。