redis数据类型及订阅操作

Redis数据类型详解

Redis键/值介绍

Redis key值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如“foo”的简单字符串到一个JPG文件的内容都可以。空字符串也是有效key值。

key规则:

  • 太长的键值不是个好主意,例如1024字节的键值就不是个好主意,不仅因为消耗内存,而且在数据中查找这类键值的计算成本很高。
  • 太短的键值通常也不是好主意,如果你要用“u:1000:pwd”来代替
  • 最好坚持一种模式。例如:"object-type:id:field"就是个不错的注意,像这样“user:1000:password”。或者一个键值对的字段名中加上一个点,就想这样“comment:1234:reply.to”。

数据类型:

String字符串类型

List列表数据类型

 集合(Sets)类型

有序集合(Sorted Sets)类型

Hash类型

1.String字符串类型

这是Redis最简单的数据类型之一。如果只使用这种数据类型,那么redis就是一个持久化的memcached服务器当然redis对string类型的功能比memcached还是多很多的

常规的String字符串类型(key value):

127.0.0.1:6379> set wk >.>haoshuai      #存入数据  key为wk 数据为>.>haoshuai
OK
127.0.0.1:6379> get wk             #查数据,get+key值查看
">.>haoshuai"

value值可以是任何类型的字符串(包括二进制数据),例如你可以在一个键下保存一个jpg图片。但值的长度不能超过1GB

String类型也可以用来存储数字,并支持对数字的加减操作:

set id 1        #设置键为id 值为1
incr id      #自增1 id变为2
incrby id 5   #自增指定数值5    id变为7  
decr id      #自减1 id变为6
decrby id5    #自减指定数值5   id变为1    

为key设置新值并且返回原值

127.0.0.1:6379> set user01 zhangsan   #设置新key-value
OK
127.0.0.1:6379> get user01      
"zhangsan"
127.0.0.1:6379> getset user01 wangwu    #设置新数据并返回旧数据
"zhangsan"
127.0.0.1:6379> getset user01 liliu     #设置新数据并返回旧数据
"wangwu"
127.0.0.1:6379> getset user01 gongli    #设置新数据并返回旧数据
"liliu"
127.0.0.1:6379> get user01      
"gongli"

String类型还支持批量读写操作

127.0.0.1:6379> mset name zhangsan age 44
OK
127.0.0.1:6379> mget name age
1) "zhangsan"
2) "44"

string类型还支持对其部分的修改和获取操作

127.0.0.1:6379> set images flower
127.0.0.1:6379> append images .jpg  #追加字符串
127.0.0.1:6379> get images
"flower.jpg"

2.List列表类型

列表list的用途:

list可被用来实现聊天系统。还可以作为不同进程间传递消息的队列。关键是,你可以每次都以原先添加的顺序访问数据。这不需要任何SQLORDER操作,将会非常快,也会很容易扩展到百万级别的规模。

在评级系统中,比如社会化新闻网站reddit.com,你可以把每个新提交的链接添加到一个list,用LRANGE可简单的对结果分页。

在博客引擎实现中,你可为每篇日志设置一个list,在该list中推入进博客评论,等等

向Redis list压入ID而不是实际的数据

127.0.0.1:6379> lpush students "zhangsan"   #将元素“zhangsan”放在students列表的最左边
127.0.0.1:6379> lpush students "wangwu"   #将元素“wangwu”插入列表的最左边
127.0.0.1:6379> lpush students "liliu"    #将元素“liliu”插入列表的最左边
lrange students 0 2               #查看序列是0到2的元素
1) "liliu"
2) "wangwu"
3) "zhangsan"
rpush students "wangyue"              #将元素wangyue插入列表的最右边
lrange students 0 3                 #查看序列是0到3的元素
1) "liliu"
2) "wangwu"
3) "zhangsan"
4) "wangyue"
llen students   #查看列表元素的个数
lpop students   #移除最左边的元素值
rpop students   #移除最右边的元素值
127.0.0.1:6379> rpush students zhangsan
127.0.0.1:6379> rpush students zhangsan
127.0.0.1:6379> lrange students 0 3
1) "wangwu"
2) "zhangsan"
3) "zhangsan"
4) "zhangsan"
127.0.0.1:6379> lrem students 2 "zhangsan"  #删除列表里是“zhangsan”的元素,删除两次(从左向右删)
127.0.0.1:6379> lrange students 0 3
1) "wangwu"
2) "zhangsan"
127.0.0.1:6379> lrem students 1 "zhangsan"  #删除列表里的元素zhangsan一次
127.0.0.1:6379> lrem students 0 "zhangsan"  #清空列表所有的zhangsan元素
127.0.0.1:6379> lpush students a b c d  #左插入元素abcd
127.0.0.1:6379> lrange students 0 4
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> linsert students before b xxxx  #在元素b的前边插入元素xxxx
127.0.0.1:6379> lrange students 0 9
1) "d"
2) "c"
3) "xxxx"
4) "b"
5) "a"
127.0.0.1:6379> linsert students after b xxxx   #在元素b的后边插入元素xxxx
127.0.0.1:6379> lrange students 0 9
1) "d"
2) "c"
3) "xxxx"
4) "b"
5) "xxxx"
6) "a"

3.集合(Sets)类型

Redis集合是未排序的集合,其元素是二进制安全的字符串。SADD命令可以向集合添加一个新元素。和sets相关的操作也有许多,比如检测某个元素是否存在,以及实现交集,并集,差集等等。

edis能够将一系列不重复的值存储成一个集合

127.0.0.1:6379> sadd users laoda    #向集合users里添加一个元素“laoda”
127.0.0.1:6379> sadd users laoer laosan #向结合users里添加两个元素laoer,laosan
127.0.0.1:6379> smembers users  #查看集合里的所有元素
1) "laosan"         #可以看到集合里的元素是无序的
2) "laoda"
3) "laoer"
#我们向集合中添加了三个元素,并让Redis返回所有元素。现在让我们看一下某个元素是否存在于集合中
127.0.0.1:6379> sismember users laoda   #查看元素laoda是否存在于集合users中
(integer) 1 #存在
127.0.0.1:6379> sismember users laoer   #查看元素laoer是否存在于集合users中
(integer) 1 #存在
127.0.0.1:6379> sismember users laosan  #查看元素laosan是否存在于集合users中
(integer) 1 #存在
127.0.0.1:6379> sismember users laosi   #查看元素laosi是否存在于集合users中
(integer) 0 #不存在

“laoda”是这个集合的成员,而“laosi”不是。集合特别适合表现对象之间的关系。例如用Redis集合可以很容易实现标签功能。

下面是一个简单的方案:对每个想加标签的对象,用一个标签ID集合与之关联,并且对每个已有的标签,一组对象ID与之关联。

例如,假设我们的新闻ID1000被加了三个标签tag1,2,5和77,就可以设置下面两个集合:

sadd news:1000:tags 1
sadd news:1000:tags 2
sadd news:1000:tags 5
sadd news:1000:tags 77
sadd tag:1:objects 1000
sadd tag:2:objects 1000
sadd tag:5:objects 1000
sadd tag:27:objects 1000
#要获取一个对象的所有标签,我们只需要:
#获取ID号为1000的所有新闻的题目
smembers news:1000:tags      #获取集合为news:1000:tags的所有元素
1) "1"      #新闻标题
2) "2"      #新闻标题
3) "5"      #新闻标题
4) "77"     #新闻标题
#查询某个标签的具体内容,我们只需要:
#获取某个新闻标题的具体内容
smembers tag:5:objects       #获取集合为tag:5:objects的所有元素
1) "1000"       #新闻内容

而有些看上去并不简单的操作仍然能使用相应的Redis命令轻松实现。例如我们也许想获得一份同时拥有标签1,2,10和27的对象列表。则可以用SINTER命令来做,他可以在不同集合之间取出交集。因此为达目的我们只需:

sadd tag:1:objects 500       #向集合tag:1:objects里添加元素“500
smembers tag:1:objects   #查看集合tag:1:objects里的所有元素
1) "500"
2) "1000"
smembers tag:2:objects   #查看集合tag:2:objects里的所有元素
1) "1000"
sinter tag:1:objects tag:2:objects tag:5:objects tag:27:objects    #求集合tag:1:objects ...tag:27:objects里的所有元素的交集
1) "1000"

4 有序集合(Sorted Sets)类型

Sorted Sets和Sets结构相似,不同的是存在Sorted Sets中的数据会有一个score属性,并会在写入时就按这个score拍好序。

#向一个有序集合里添加元素
127.0.0.1:6379> ZADD days 0 mon #days是有序集合名,0是序号,mon是值
(integer) 1
127.0.0.1:6379> ZADD days 1 tue
(integer) 1
127.0.0.1:6379> ZADD days 2 web
(integer) 1
127.0.0.1:6379> ZADD days 3 thu
(integer) 1
127.0.0.1:6379> ZADD days 4 fri
(integer) 1
127.0.0.1:6379> ZADD days 5 sat
(integer) 1
127.0.0.1:6379> ZADD days 6 sun
(integer) 1
127.0.0.1:6379> zrange days 0 6 #查看集合索引0到6的元素
1) "mon"
2) "tue"
3) "web"
4) "thu"
5) "fri"
6) "sat"
7) "sun"
#从上面我们可以看出,ZADD创建的集合是有序集合。
#查看有序集合days的具体值的排序
127.0.0.1:6379> zscore days mon
"0"
127.0.0.1:6379> zscore days web 
"2"
127.0.0.1:6379> zscore days fri
"4"
root@redis-master ~]# redis-cli -a yunjisuan
127.0.0.1:6379> zscore days mon
"0"
127.0.0.1:6379> zscore days web
"2"
127.0.0.1:6379> zscore days fri
"4"
127.0.0.1:6379> zcount days 3 6
(integer) 4
127.0.0.1:6379> ZRANGEBYSCORE days 3 6
1) "thu"
2) "fri"
3) "sat"
4) "sun"
  • 集合是使用频率很高的数据类型,但是...对许多问题来说他们也有点太不讲顺序了;因此Redis1.2引入了有序集合。它和集合非常相似,也是二进制安全的字符串集合,但是这次带有关联的score,以及一个类似LRANGE的操作可以返回有序元素,此操作只能作用于有序集合,它就是,ZRANGE命令。
  • 基本上有序集合从某种程度上说是SQL世界的索引在Redis中的等价物。例如在上面提到的reddit.com例子中,并没有提到如何根据用户投票和时间因素将新闻组合生成首页。我们将看到有序集合如何解决这个问题,但最好先从更简单的事情开始,阐明这个高级数据类型是如何工作的。让我们添加几个黑客,并将他们的生日作为“score”。
127.0.0.1:6379> zadd hackers 1940 "1940-Alan Kay"
(integer) 1
127.0.0.1:6379> zadd hackers 1953 "1953-Richard Stallman"
(integer) 1
127.0.0.1:6379> zadd hackers 1965 "1965-Yukihiro Matsumoto"
(integer) 1
127.0.0.1:6379> zadd hackers 1916 "1916-Claude Shannon"
(integer) 1
127.0.0.1:6379> zadd hackers 1969 "1969-Linus Torvalds"
(integer) 1
127.0.0.1:6379> zadd hackers 1912 "1912-Alan Turing"
(integer) 1

对有序集合来说,按生日排序返回这些黑客易如反掌,因为他们已经是有序的。有序集合是通过一个dual-ported数据结构实现的,它包含一个精简的有序列表和一个hash table,因此添加一个元素的时间复杂度是O(log(N))。这还行,但当我们需要访问有序的元素时,Redis不必再做任何事情,它已经是有序的了:

127.0.0.1:6379> zadd hackers 1940 "1940-Alan Kay"
(integer) 1
127.0.0.1:6379> zadd hackers 1953 "1953-Richard Stallman"
(integer) 1
127.0.0.1:6379> zadd hackers 1965 "1965-Yukihiro Matsumoto"
(integer) 1
127.0.0.1:6379> zadd hackers 1916 "1916-Claude Shannon"
(integer) 1
127.0.0.1:6379> zadd hackers 1969 "1969-Linus Torvalds"
(integer) 1
127.0.0.1:6379> zadd hackers 1912 "1912-Alan Turing"
(integer) 1
#利用zrange进行排序查询
127.0.0.1:6379> zrange hackers 0 6
1) "1912-Alan Turing"
2) "1916-Claude Shannon"
3) "1940-Alan Kay"
4) "1953-Richard Stallman"
5) "1965-Yukihiro Matsumoto"
6) "1969-Linus Torvalds"
#利用zrevrange进行反向查询
127.0.0.1:6379> zrevrange hackers 0 -1
1) "1969-Linus Torvalds"
2) "1965-Yukihiro Matsumoto"
3) "1953-Richard Stallman"
4) "1940-Alan Kay"
5) "1916-Claude Shannon"
6) "1912-Alan Turing"

5 Hash类型

Redis能够存储key对多个属性的数据(比如user1,uname user1.passwd)

#存储一个hash类型test,他的属性是name,属性数据是yunjisuan
127.0.0.1:6379> hset test name yunjisuan
(integer) 1
#存储一个hash类型test,他的属性是age,属性数据是35
127.0.0.1:6379> hset test age 35
(integer) 1
#存储一个hash类型test,他的属性是sex,属性数据是non
127.0.0.1:6379> hset test sex nan
(integer) 1
#查看hash类型test的所有属性的值
127.0.0.1:6379> hvals test
1) "yunjisuan"
2) "35"
3) "nan"
#查看hash类型test的所有属性及属性所对应的值
127.0.0.1:6379> hgetall test
1) "name"
2) "yunjisuan"
3) "age"
4) "35"
5) "sex"
6) "nan"

开启redis的订阅功能

#开启redis的订阅功能
redis-cli
127.0.0.1:6379> subscribe yunjisuan #开启频道名:yunjisuan的订阅功能,可开启多个窗口进行订阅

#对频道进行内容推送    只要在推送端推送,订阅端就能看到
redis-cli
127.0.0.1:6379> publish yunjisuan 'welcome' #向频道yunjisuan推送welcome
(integer) 2     #推送成功的人数
127.0.0.1:6379> publish yunjisuan '很高兴'
(integer) 2
127.0.0.1:6379> publish yunjisuan 'welcome'
(integer) 3
原文地址:https://www.cnblogs.com/ywrj/p/9514908.html