美文网首页
2. Redis基本操作及数据结构

2. Redis基本操作及数据结构

作者: 都是浮云啊 | 来源:发表于2018-10-04 16:21 被阅读0次

    前言

    在上篇文章中我们对Redis进行了简单的介绍,其中有提到:Redis相较于其他的键值数据库有一个特性是支持丰富的数据类型。本篇文章将分别介绍Redis支持的数据类型。

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

    string

    stringRedis最基本的数据类型,和Memcached(也是一个NOSQL)是一模一样的模型,一个key对应着一个value。同时string是二进制安全的->也就是说它可以包含任意数据,比如图像或者任意一个被序列化了的对象。它是redis最基本的数据类型。它的值最大能够存储512M。例如下面的简单的2个命令,set一个键为name,值为xiaoxiao

    127.0.0.1:6379> set name "xiaoxiao"
    OK
    127.0.0.1:6379> get name
    "xiaoxiao"
    
    hash

    redis的哈希是一个string类型的fieldvalue的映射表,比较适合存储对象(因为一个对象有多个键,每个键都对应一个值,而hash的结构和这个对象是类似的)。如下,使用hmset设置一个hash,这个hash的名字叫person,它有2个field一个叫age一个叫name。其中age对应的value为字符串18,name对应的valuexiaoxiao。当然,它可以设置多个field,只要往后继续加就行了。hash一般使用于存储读取修改用户属性。

    127.0.0.1:6379> hmset person age 18 name "xiaoxiao"
    OK
    127.0.0.1:6379> hmget person age
    1) "18"
    127.0.0.1:6379> hmget person name
    1) "xiaoxiao"
    
    list

    redis的列表是一个简单的字符串列表,按照插入顺序,你可以把元素添加到列表的头部和列表的尾部,类似双向链表。如下脚本,lpush代表从左边放入,rpush代表从右边放入。lrange 0 10代表从左边的第0位开始,数到10list一般适用于消息队列中

    127.0.0.1:6379> lpush listtest node1
    (integer) 1
    127.0.0.1:6379> lpush listtest node2
    (integer) 2
    127.0.0.1:6379> lpush listtest node3
    (integer) 3
    127.0.0.1:6379> lpush listtest node4
    (integer) 4
    127.0.0.1:6379> lrange listtest 0 10
    1) "node4"
    2) "node3"
    3) "node2"
    4) "node1"
    
    set集合

    redis的set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1),非常类似于Java中的Set集合。sadd命令为set一个元素到集合中,如果元素原来不存在就添加成功返回1,如果存储就添加失败返回0。这是set集合无序不可重复的特性,因为相同的key计算出来的hash值时一样的,所以不允许重复添加。set适用于共同好友等场景

    127.0.0.1:6379> sadd settest 123
    (integer) 1
    127.0.0.1:6379> sadd settest 123
    (integer) 0
    127.0.0.1:6379> smembers settest
    1) "123"
    
    zset命令

    rediszsetset一样不允许有重复元素,也是一个string类型的集合。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。命令为zadd key score member。如下 根据分数排序从小到大。分数是可以重复的。zset适用于排行榜,有优先级的消息队列。

    127.0.0.1:6379> zadd person 0 redis
    (integer) 1
    127.0.0.1:6379> zadd person 1 rocketmq
    (integer) 1
    127.0.0.1:6379> zadd person 1 java
    (integer) 1
    127.0.0.1:6379> zadd person 0 xiaoxiao
    (integer) 1
    127.0.0.1:6379> zadd person 0 work
    (integer) 1
    127.0.0.1:6379> zrangebyscore person 0 10
    1) "redis"
    2) "work"
    3) "xiaoxiao"
    4) "java"
    5) "rocketmq"
    127.0.0.1:6379>
    

    HyperLogLog

    Redis 在2.8.9 版本添加了 HyperLogLog 结构,HyperLogLog 是用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。在 Redis 里面HyperLogLog键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比.但是,因为 HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
    关于基数举个例子:数据集{3,5,2,1,2,3,5}那么这个数据集的基数集就是{3,5,2,1},基数是4。基数估计就是在误差可接受的范围内,快速计算基数。
    pfadd添加元素到HyperLogLog中,pfcount为基数的估算值

    127.0.0.1:6379> pfadd person "name"
    (integer) 1
    127.0.0.1:6379> pfadd person "age"
    (integer) 1
    127.0.0.1:6379> pfadd person "age"
    (integer) 0
    127.0.0.1:6379> pfadd person "name"
    (integer) 0
    127.0.0.1:6379> pfcount person
    (integer) 2
    

    发布和订阅

    Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis 客户端可以订阅任意数量的频道。如下图所示:客户端c1、c2、c3同时订阅了s1

    Redis订阅.png
    当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端,如下图所示
    Redis发布.png

    在上面我们演示了redis的订阅和发布的流程,下面再来看下如何实现和使用。
    我们在一个客户端订阅一个通道叫channel1,然后再开一个窗口链接redis客户端,

    ## 客户端A订阅一个名字叫channel1的通道
    127.0.0.1:6379> subscribe channel1
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "channel1"
    3) (integer) 1
    1) "message"
    2) "channel1"
    3) "day day up" 
    ## 客户端B往通道channel1发布一个消息,回车之后  客户端A会出现:3) "day day up" 
    127.0.0.1:6379> publish channel1 "day day up"
    (integer) 1
    

    如图所示.


    发布演示.png

    同时 一个客户端可以订阅多个通道,也可以退订这些通道。

    redis对事物的支持

    Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证

    1. 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
    2. 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行

    事物分为三个阶段
    a: 开始事物
    b: 命令入队
    c: 执行事物

    关于事物的命令

    命令 描述
    MULTI 标记事物开始
    DISCARD 取消事务,放弃执行事务块内的所有命令
    EXEC 执行所有事务块内的命令
    UNWATCH 取消 WATCH 命令对所有 key 的监视。
    WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

    附上一个小Demo

    ## 开启事物
    127.0.0.1:6379> multi
    OK
    ## 第1个
    127.0.0.1:6379> set name "xiaoming"
    QUEUED
    ## 第2个
    127.0.0.1:6379> set age "18"
    QUEUED
    ## 第3个
    127.0.0.1:6379> sadd person "1" "2" "3"
    QUEUED
    ## 执行里面的语句
    127.0.0.1:6379> exec
    1) OK
    2) OK
    3) (integer) 3
    127.0.0.1:6379>
    
    附录

    Redis常用的string的命令

    命令 返回值 描述
    set key value OK 设置一个键值对
    get key string 返回key对应的value
    del key 0/1 删除key,成功1,失败0
    getrange key start end string 返回key的第start开始到end的字符
    setnx key value 0/1 key存在设置,不存在不设置
    incr key value 对key原子+1,返回加完的值
    setex key seconds value OK 设置一个值为value的key,过期时间seconds
    decr key value 返回减1之后的值
    总结

    这篇文章简单介绍了Redsi的基本数据类型和常见的一些命令,实际上redis本身就是从简单的设计来考虑的。然后我们学习了基于Redis的订阅和发布特性和redis对事物的支持,并各举出了一个小例子。当然,本篇的内容还是比较浅显的,实际上redsi还有一些高级一点的特性,我们在下篇文章中介绍。现在是国庆节即将一半,前面陪家人和同事在杭州玩了几天,后面几天静心学习,保持更新自己的知识。

    相关文章

      网友评论

          本文标题:2. Redis基本操作及数据结构

          本文链接:https://www.haomeiwen.com/subject/fvvxaftx.html