Redis学习笔记(3) Redis基础类型及命令之二

1. 集合类型

  集合类型与列表类型有很多相似之处,但二者的区别在于:前者具有唯一性,但不具有有序性;后者具有有序性,但不具有唯一性。集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,以及多个集合类型之间进行并集、交集和差集运算。

  (1) 命令

  1) 增加/删除元素

  格式为:SADD key member [member ...]    SREM key member [member ...]

  SADD向集合中增加一个或多个元素,加入的元素若已存在语集合中,则会忽略该元素。命令返回成功加入的元素数量(忽略不计算在内)。SREM命令用于从集合中删除一个或多个元素,并返回删除成功的个数。

127.0.0.1:6379[2]> SADD letters a
(integer) 1
127.0.0.1:6379[2]> SADD letters a b c
(integer) 2

127.0.0.1:6379[2]> TYPE letters
set
# 由于"d"在集合中不存在,所以只删除了一个元素,返回值为1
127.0.0.1:6379[2]> SREM letters c d
(integer) 1

  2) 获得集合中所有元素

  格式为:SMEMBERS key

127.0.0.1:6379[2]> SMEMBERS letters
1) "b"
2) "a" 

  3) 判断元素是否在集合中

  格式为:SISMEMBER key member,该命令的时间复杂度为O(1),值存在时返回1,否则返回0。

127.0.0.1:6379[2]> SISMEMBER letters a
(integer) 1
127.0.0.1:6379[2]> SISMEMBER letters d
(integer) 0

  4) 集合间运算

  格式为:SDIFF key (key ...)    SINTER key (key ...)    SUNION key (key ...)

  SDIFF是对多个集合执行差集运算,如{1,2,3} - {2,3,4} = {1},{2,3,4} - {1,2,3} = {4}

127.0.0.1:6379[2]> SADD set1 1 2 3
(integer) 3
127.0.0.1:6379[2]> SADD set2 2 3 4
(integer) 3
127.0.0.1:6379[2]> SDIFF set1 set2
1) "1"
127.0.0.1:6379[2]> SDIFF set2 set1
1) "4"

# SDIFF支持同时传入多个键,顺序为先计算set1-set2,再计算结果与set3的差集
127.0.0.1:6379[2]> sadd set3 2 3 4 5
(integer) 4
127.0.0.1:6379[2]> sdiff set1 set2 set3
1) "1"

  SINTER命令用来对多个集合执行交集运算,如{1,2,3} & {2,3,4} = {2,3}

127.0.0.1:6379[2]> SDIFF set1 set2 set3
1) "1"
127.0.0.1:6379[2]> SINTER set1 set2 set3
1) "2"
2) "3"

  SUNION用来对多个集合执行并集运算,如{1,2,3} or {2,3,4} = {1,2,3,4}.

127.0.0.1:6379[2]> SUNION set1 set2 set3
1) "1"
2) "2"
3) "3"
4) "4"

  5) 获取集合中元素的个数

  格式为:SCARD key

127.0.0.1:6379[2]> SMEMBERS set2
1) "2"
2) "3"
3) "4"
127.0.0.1:6379[2]> SCARD set2
(integer) 3

  6) 进行集合运算并将结果存储

   格式为:SDIFFSTORE destionation key [key...]  SINTERSTORE destination key [key ...]   SUNIONSTORE destination key [key ...]

127.0.0.1:6379[2]> SDIFFSTORE result set1 set2
(integer) 1
127.0.0.1:6379[2]> get reult
(nil)
127.0.0.1:6379[2]> SMEMBERS result
1) "1"
127.0.0.1:6379[2]> TYPE result
set

  7) 随机获得集合中的元素

  格式为:SRANDMEMBER key [count],count表示一次获取多个元素,当count为正数,SRANDMEMBER会随机从集合中获得count个不重复的元素,如果count的值大于集合中的元素个数,SRANDMEMBER会返回集合中的全部元素;如果count为负数,SRANDMEMBER会随机从集合中获得|count|个元素,且这些元素有可能相同。

127.0.0.1:6379[2]> SRANDMEMBER set1
"2"
127.0.0.1:6379[2]> SRANDMEMBER set1
"1"
127.0.0.1:6379[2]>
127.0.0.1:6379[2]> SADD letters a b c d
(integer) 4
127.0.0.1:6379[2]> SRANDMEMBER letters 2
1) "d"
2) "a"
127.0.0.1:6379[2]> SRANDMEMBER letters 100
1) "d"
2) "a"
3) "b"
4) "c"
127.0.0.1:6379[2]> SRANDMEMBER letters -2
1) "d"
2) "d"
127.0.0.1:6379[2]> SRANDMEMBER letters -10
 1) "a"
 2) "a"
 3) "a"
 4) "d"
 5) "d"
 6) "d"
 7) "c"
 8) "b"
 9) "d"
10) "d"

  8) 从集合中弹出一个元素

  格式为:SPOP key,LPOP是从列表左边弹出一个元素,但集合类型的元素是无序的,SPOP会从集合中随机选择一个元素弹出。

127.0.0.1:6379[2]> SPOP letters
"d"
127.0.0.1:6379[2]> SMEMBERS letters
1) "c"
2) "b"
3) "a"

  (2) 示例

  1) 存储文章标签:一个文章的所有标签互补相同,且对标签排序不要求,对每篇文章使用键为"post:文章ID:tags"的键存储文章标签,伪代码:

# ID为42的文章添加标签
SADD post:42:tags 闲言碎语,技术文章, Java

# 删除标签
SREM post:42:tags, 闲言碎语

# 显示所有标签
$tags = SMEMBERS post:42:tags
print $tags

  注意:使用集合类型键存储标签适合需要单独增加或删除标签的场合。其次,有些地方需要用户直接设置所有标签后一起上传。

  2) 通过标签搜索文章

  列出某个标签下的所有文章,甚至获得同时属于几个标签的文章列表,为每个标签使用一个"tags:标签名称:posts"的集合类型存储标有该标签的文章ID列表。当需要获取"MySQL"标签的文章时只需要使用命令SMEMBERS tags:MYSQL:posts;当同时找出属于Java、MYSQL、Redis三个标签的文章,只需要将tag:java:posts、tags:MYSQL:posts和tags:Redis:posts这3个键取交集,借助SINTER命令。

2. 有序集合类型

  有序集合类型为集合中的每一个元素都关联了一个分数,不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作,并且元素的分数可以相同。

  有序集合与列表的区别:

  1) 列表通过链表实现,获取靠近两端的数据速度极快,二访问中间数据的速度会较慢,适合实现"新鲜事"或"日志"这样很少访问中间元素的应用。

  2) 有序集合是使用散列表和跳跃表(skip list)实现的,所以即使读取位于中间部分的数据速度也很快。  

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

  4) 有序集合要比列表类型更耗费内存。

  (1) 命令

  1)  增加元素

  格式为:ZADD key score member [score member ...]

  ZADD用于向有序集合加入一个元素和该元素的分数,若已存在,则会使用新的分数替换原有的分数,返回新加入集合中的元素个数。

# j记录三个人的分数
127.0.0.1:6379> ZADD scoreboard 89 Tom 67 Peter 100 David
(integer) 3
# 修改Peter的分数
127.0.0.1:6379> ZADD scoreboard 76 Peter
(integer) 0

# 分数不仅可以是整数,还支持double类型
127.0.0.1:6379> ZADD testboard 17E+307 a
(integer) 1
127.0.0.1:6379> ZADD testboard 1.5 b
(integer) 1
127.0.0.1:6379> ZADD testboard +inf c    #正无穷
(integer) 1
127.0.0.1:6379> ZADD testboard -inf d    #负无穷
(integer) 1

  2) 获得元素的分数

  格式为: ZSCORE key member

127.0.0.1:6379> ZSCORE scoreboard Peter
"76"

  3) 获得排名在某个范围的元素列表

  格式为:ZRANGE key start stop [WITHSCORES]    ZREVRANGE key start stop [WITHSCORE]

  ZRANGE会按元素分数从小到大顺序返回索引从start到stop之间的所有元素(包含两端的元素),同时获得元素的分数可以加上WITHSCORES参数。ZRANGE索引从0开始,负数代表从后向前查找(-1表示最后一个元素);ZREVRANG会按照元素分数从大到小的顺序给出结果。

127.0.0.1:6379> ZRANGE scoreboard 0 2
1) "Peter"
2) "Tom"
3) "David"
127.0.0.1:6379> ZRANGE scoreboard 1 -1
1) "Tom"
2) "David"

127.0.0.1:6379> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"

  如果两个元素的分数相同,Redis会按照字典顺序(0<9<A<Z<a<z)来进行排序,再进一步,如果元素的值是中文,则取决于中文的编码方式。

# 分数相同情况
127.0.0.1:6379> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"
7) "Oliver"
8) "100"

# 中文情况
127.0.0.1:6379> ZADD chineseName 0 马华 0 黎明 0 姚明 0 李娜
(integer) 4
127.0.0.1:6379> ZRANGE chineseName 0 -1 WITHSCORES
1) "\xe5\xa7\x9a\xe6\x98\x8e"
2) "0"
3) "\xe6\x9d\x8e\xe5\xa8\x9c"
4) "0"
5) "\xe9\xa9\xac\xe5\x8d\x8e"
6) "0"
7) "\xe9\xbb\x8e\xe6\x98\x8e"
8) "0"

  4) 获得指定分数范围的元素

  格式为:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

  该命令按照元素大从小到大返回分数在min和max之间的元素。如果希望分数不包含端点值,可以在分数前加上"("符号,如获取80到100分的数据,包含80,不包含100。

  LIMIT offset count时在获得的元素列表的基础上向后偏移offset个元素,并且之获取前count个元素。

# 获取分数在[80,100]间的元素
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 100
1) "Tom"
2) "David"
3) "Oliver"

# 获取分数在[80,100)之间的元素,包含80,不包含100的元素
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 (100
1) "Tom"

# 获取分数在[80,+inf]之间的元素,即大于80的元素
127.0.0.1:6379> ZRANGEBYSCORE scoreboard (80 +inf
1) "Tom"
2) "David"
3) "Oliver"

# scoreboard的元素以及分数
127.0.0.1:6379> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"
7) "Oliver"
8) "100"

# 获取分数高于90分的从第二个人开始的2个人
127.0.0.1:6379> ZRANGEBYSCORE scoreboard 80 +inf WITHSCORES LIMIT 1 2
1) "David"
2) "100"
3) "Oliver"
4) "100"

# 获取分数低于100的前2个人
127.0.0.1:6379> ZREVRANGEBYSCORE scoreboard (100 0 WITHSCORES LIMIT 0 2
1) "Tom"
2) "89"
3) "Peter"
4) "76"

  5) 增加某个元素的分数

  格式为:ZINCRBY key increment member

  ZINCRBY可以增加一个元素的分数(正数和负数均可),返回值是更改后的分数。如果指定元素不存在,Redis会先建立它并将它的分数赋为0再执行操作。

127.0.0.1:6379> ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"
7) "Oliver"
8) "100"
# 将Tom的分数减少5分
127.0.0.1:6379> ZINCRBY scoreboard -5 Tom
"84"

  6) 获得集合中的元素数量

  格式为:ZCRAD key

127.0.0.1:6379> ZCARD scoreboard
(integer) 4

  7) 获得指定分数范围的元素个数

  格式为:ZCOUNT key min max

127.0.0.1:6379> ZCOUNT scoreboard (80 +inf
(integer) 3

  8) 删除一个或多个元素

  ZREM key member [member ...]

127.0.0.1:6379> ZREM scoreboard Oliver
(integer) 1
127.0.0.1:6379> ZCARD scoreboard
(integer) 3

  9) 按照排名范围删除元素

  ZREMRANGEBYRANK key start stop

  该命令按照元素分数从大到小的顺序删除指定排名范围内的所有元素,并返回删除的元素数量。

127.0.0.1:6379> ZADD testRem 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:6379> ZREMRANGEBYRANK testRem 0 2
(integer) 3
127.0.0.1:6379> ZRANGE testRem 0 -1 WITHSCORES
1) "d"
2) "4"
3) "e"
4) "5"
5) "f"
6) "6"

  10) 按照分数范围删除元素

  格式为:ZREMRANGEBYSCORE key min max

  该命令会删除指定分数范围内的所有元素,返回值是删除的元素数量。

127.0.0.1:6379> ZREMRANGEBYSCORE testRem (4 5
(integer) 1
127.0.0.1:6379> ZRANGE testRem 0 -1 WITHSCORES
1) "d"
2) "4"
3) "f"
4) "6"

  11) 获得元素的排名

  格式为:ZRANK key member    ZREVRANK key member

  ZRANK会按照分数从小到大的顺序获得指定的元素排名。ZREVRANK命令则相反。

# 从小到大的顺序获取Peter的排名
127.0.0.1:6379> ZADD scoreboard 70 Peter 80 Tom 90 Green 100 William
(integer) 4
127.0.0.1:6379> ZRANK scoreboard Peter
(integer) 0

# 从大到小的顺序获取其排序
127.0.0.1:6379> ZREVRANK scoreboard Peter
(integer) 3

  12) 计算有序集合的交集

  格式为:ZINTERSTORE destination numkeys key [key ...] [WEIGHT weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

  该命令用来计算多个有序集合的交集并将结果存储在destination中,返回值为destination的个数,destination键中元素的分数是由AGGREGATE参数决定的。

  a. 当AGGREGATE是SUM时(默认),destination键中元素的分数是每个参与计算的集合中该元素的分数的和。

127.0.0.1:6379> ZADD sortedSets1 1 a 2 b
(integer) 2
127.0.0.1:6379> ZADD sortedSets2 10 a 20 b
(integer) 2
127.0.0.1:6379> ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2
(integer) 2
127.0.0.1:6379> ZRANGE sortedSetsResult 0 -1 WITHSCORES
1) "a"
2) "11"
3) "b"
4) "22"

  b. 当AGGREGATE是MIN时。destination键中元素的分数是每个参与计算的集合中该元素分数的最小值。

127.0.0.1:6379> ZINTERSTORE sortedSetResult 2 sortedSets1 sortedSets2 AGGREGATE MIN
(integer) 2
127.0.0.1:6379> ZRANGE sortedSetResult 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"

  c. 当AGGREGATE是MAX时,destination键中元素的分数是每个参与计算的集合中该元素的最大值。

127.0.0.1:6379> ZINTERSTORE sortedSetResult 2 sortedSets1 sortedSets2 AGGREGATE MAX
(integer) 2
127.0.0.1:6379> ZRANGE sortedSetResult 0 -1 WITHSCORES
1) "a"
2) "10"
3) "b"
4) "20"

  ZINTERSTORE命令还能够通过WEIGHTS参数设置每个集合的权重,每个集合在参与计算时元素的分数会被乘上该集合的权重。

127.0.0.1:6379> ZINTERSTORE sortedSetResult 2 sortedSets1 sortedSets2 WEIGHTS 1 0.1
(integer) 2
127.0.0.1:6379> ZRANGE sortedSetResult 0 -1 WITHSCORES
1) "a"
2) "2"
3) "b"
4) "4"

  13) 计算集合间的并集

  与ZINTERSTORE命令用法一样

  (2) 示例

  1) 实现按点击量排序

  有序集合的键以文章ID作为元素,以该文章的点击量作为该元素的分数。该键命名为posts:page.view,每次用户访问一篇文章,则通过"ZINCRBY posts:page.view 1 文章ID"。  

  按点击量的顺序显示文章列表:

$postsPerPage=10
$start = ($currentPage - 1) * $postsPerPage
$end = $currentPage * $postsPerPage - 1
$postsId = ZREVRANGE posts:page.view, $start, $end

for each $id in $postsID
    $postData = HGETALL post:$id
    print 文章标题: $postData.title

  获得某篇文章的访问量可通过:ZSCORE posts:page.view 文章ID来实现。

  2) 改进按时间排序

  为了能自由地更改文章发布时间,可采用有序集合类型替代列表类型,元素仍为文章ID,此时元素的分数是文章发布的LInux时间,可以修改元素对应的分数就可以达到更改时间的目的。

  借助ZREVRANGEBYSCORE命令还可以轻松获得指定时间范围的文章列表,借助这个功能可以实现类似WordPress的按月份查看文章的功能。

时间: 2024-10-05 04:27:49

Redis学习笔记(3) Redis基础类型及命令之二的相关文章

Redis学习笔记(三) Redis API与常用数据类型简介

一.Redis中常用数据类型 由上一篇博客可知,Redis目前提供五种数据类型:string(字符串).list(链表).Hash(哈希).set(集合)及zset(sorted set)  (有序集合).现在,我们一一来看看这五种数据类型的基本使用方法.在开始介绍之前,我们先使用刚刚引入的Redis API建立一个Redis客户端对象,有了这个客户端对象,我们才能和Redis服务端进行通信,且看下面的一行代码.我们需要事先指定好Redis服务端的IP地址和端口号,然后根据这两个信息建立一个Re

Redis学习笔记(4) Redis事务、生存时间及排序

1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命令. 127.0.0.1:6379> multi OK 127.0.0.1:6379> sadd user:1:following 2 QUEUED 127.0.0.1:6379> sadd user:2:followers 1 QUEUED 127.0.0.1:6379>

Redis学习笔记(2) Redis基础类型及命令之一

1. 基础命令 (1) 获取符合规则的键名列表 格式为:KEYS pattern 其中pattern表示支持通配符 # 建立一个名为bar的键 127.0.0.1:6379> SET bar 1 OK # 获取Redis所有键 127.0.0.1:6379> KEYS * 1) "bar" 注意:KEYS命令需要遍历Redis中所有键,因此当键的数量较多时会影响性能. (2) 判断一个键是否存在 格式为:EXISTS key 如果存在则返回1,否则返回0. 127.0.0.

Redis学习笔记之入门基础知识——其他特性

1.订阅(subscribe)与发布(publish) 用户订阅某一个频道,频道发布新的信息时,会将信息告知用户 2.数据安全 1)     快照持久化(时间点转储,实质是数据副本) 操作:SAVA.BGSAVE(后台子进程SAVE) 功能:服务器会保存最近一次完成创建的快照的数据,注意,在创建快照的过程中的操作不会保存在快照中 SAVE seconds times:从上一次快照创建完成到seconds秒的时间内,如果有times次写入,那么会在seconds秒后执行一次BGSAVE,将数据写入

Redis学习笔记3-Redis5个可运行程序命令的使用

在redis安装文章中,说到安装好redis后,在/usr/local/bin下有5个关于redis的可运行程序.以下关于这5个可运行程序命令的具体说明. redis-server Redisserver的daemon启动程序 #启动并加装指定配置文件 redis-server redis.conf #查redis服务版本 redis-server –version # 以标准输入作为配置启动redis,当中key为配置參数,value为配置參数值 redis-server --port 600

Redis学习笔记~StackExchange.Redis实现分布式Session

回到目录 对于多WEB的环境现在已经是必须的了,很难想像一台WEB服务器面对百万并发的响应,所以,我们需要多台WEB服务器集群合作,来缓解这种高并发,高吞吐的场景,而对于多WEB的场景又会有个问题出现,即session存储的问题,如一个用户登陆后,把一个状态信息存储到当前WEB服务器的session里,而你请求其它页面时,很可能就被路由到另一台服务器了,这时,session也就丢了,而对于这种情况,有人把redis这个存储中间件想了起来,对它进行了封装,就有了今天基于redis的session共

Redis学习笔记4-Redis配置具体解释

在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redis学习笔记中Redis的依照方式依照后,Redis的配置文件是/etc/redis/6379.conf.以下是Redis2.8.9的配置文件各项的中文解释. #daemonize no 默认情况下, redis 不是在后台运行的.假设须要在后台运行,把该项的值更改为 yes daemonize ye

Redis学习笔记~目录

redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hashs(哈希类型).这些数据类型都 支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排 序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更

Redis学习笔记4-Redis配置详解

原文:  http://blog.csdn.net/mashangyou/article/details/24555191 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redis学习笔记中Redis的按照方式按照后,Redis的配置文件是/etc/redis/6379.conf.下面是Redis2.8.9的配置文件各项的中文解释. 1 #daemon