zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Gridview常用操作
    在DataGridView列中嵌入ComboBox(vb.net版)【原创】
    使用net创建Access存储过程
    C博客作业00我的第一篇博客 1911
    C博客作业01分支、顺序结构 1911
    Lazy load image for listview and beging separate thread
    Android Send Email
    MySQL修复表数据
    Insertion and Deletion of Calendar Events
    TechCrunch:移动社交应用开创社交网络新格局
  • 原文地址:https://www.cnblogs.com/ywrj/p/9514908.html
Copyright © 2011-2022 走看看