美文网首页
Redis 常用5大数据类型及应用场景

Redis 常用5大数据类型及应用场景

作者: 猫的树MaoTree | 来源:发表于2018-04-23 11:52 被阅读0次

    Redis最为常用的数据类型:

    • 字符串(String)

    • 哈希(hash)

    • 字符串列表(list)

    • 字符串集合(set)

    • 有序的字符串集合(sorted set)

    String(字符串)

    • redis中最为基础的数据类型,在redis中是以二进制的方式来存储的,所以存入和获取数据相同。

    • value 最多可以容纳的数据长度是 512M。

    • _ 存储String常用的命令:

              1. 赋值:set 、get 、getset(先设置这个键的值再获取这个键的值)


      image.png

              2. 删除:del


      image.png

              3. 数值增减 : incr、decr


      image.png

              4. 扩展命令:
                      incrby、decrby :增加或者减少指定的值
                      append:追加值,返回字符串长度


      image.png
    • 应用场景 : 最常用的一种数据类型, 普通的key - value 存储都可以归为此类。value也可以为数字。

      如:常规计数:微博关注数、粉丝数
      
      如:计数器:使用 INCRBY 完成统计“点击数”,由于单线程,可以避免并发问题。
      

    Hash(哈希)

    • 可以看成一个具有String key 和 String value 的类型,也就是键值对类型。所以适合存储 值对象的信息,如用户名、密码、年龄等等

    • 每一个hash可以存储4294967295个键值对。


      image.png
    • 存储Hash常用的命令:

      1. 赋值:hset:设置一个key - value
                   hmset:设置多个key - value


        image.png
      2. 取值:hget:获取一个属性的值
                   hmget:获取多个属性的值
                   hgetall:获取所有的属性和属性的值


        image.png
      3. 删除:hdel:删除具体值
                    del:删除整个集合


        image.png
      4. 增加数字:hincrby:增加指定定的数字


        image.png
      5. 扩展命令:hexists:判断指定key中的某个属性是否存在,存在返回1
                           hlen:获取属性的数量
                           keys:获得所有的key
                           hvalues:获取所有的value


        image.png
    • 使用场景:

       1. 存储部分变更的数据,如用户数据
      
    image.png
      2. 验证前端请求是否重复,可以通过redis进行过滤:每次请求将requset Ip、参数、接口等 
      hash作为key存储,当用户请求过来的时候现在redis中检索有没有这个key,进而验证是不
      是一定时间内过来的重复提交。
    

    List(列表)

    • 简单的字符串列表,可以从 头部 或 尾部 向redis列表添加元素。

    • 列表最大的长度为 2^32-1 ,即每个列表支持超过40亿个元素。

    • -列表类型的两个特性:
               1. 列表中的元素是有序的,这就意味着可以通过下标获取某个元素或者某个范围内的元素列表。

                2. 列表中的元素是可以重复的。

    • 从插入和删除角度:如果是在链表的两头插入和删除元素,这是非常高效的。如果插入和删除的操作是作用在链表的中间,那么效率就会比较低了。
    • -存储数据的方式:

                1. arraylist(数组的方式):所以根据”索引“去”查询“是比较快的,但是“新增”和“删除”比较慢,因为涉及到“位移”操作。

                2. LinkedList方式(双向链表的方式):对每个元素都记录了前后的“指针”,“插入”和“删除”的时候只是改变元素的“指针”指向即可,所以速度“快”。

                3. 双向链表添加数据

                4. 双向链表删除数据

    • -存储List常用的命令:

              1. 两端添加:lpush、rpush

    image.png

              2. 查看列表:lrange

    image.png

              3. 两端弹出:lpop、rpop

    image.png

              4. 获取列表元素个数:llen

    image.png

              5. 扩展命令

       <1> pushx :当指定的参数中 key “存在”的时候,可以向关联的list头
                部插入一个具体的值,如果”不存在”,就不会进行插入
    
    image.png
       <2> lrem(lremove):
                        正数:从头开始删除
                        负数:从尾部、开始   0 : 删除所有
    
    image.png
       <3> lset : 设置链表中某个index的角标的元素的值   
                   lset mylist 3 mmm : 在第三个角标的时候给他设置值为 mmm
    
    image.png
       <4> insert:插入元素
                   linsert mylist before b 11: 在 b 元素之前插入 11
                   linsert mylist after b 22 : 在 b 元素之后插入 22
    
    image.png
       <5> rpoplpush:完成插入和弹出操作
    
    image.png
        <6> rpoplpush 使用场景:list列表经常用于一些消息队列的一些服务,多个程序间消息
        的交互。
    
    如: 此时假设一个应用程序正在执行 “lpush” 向链表中去添加新的元素,将这样的程序称为'生
    产者' ,另外一个程序正在执行 “rpop” 操作,从链表中取出元素,称为'消费者'与此同时 “消费
    者” 元素在取出元素后立刻“崩溃”,由于该消息已经被取出但是没有被正常处理,此时可以认为该
    消息已经丢失了,可能会导致业务数据丢失或者业务数据的不一致等现象发生,此时我们可以使用
     “rpoplpush” 命令使消费者在主消息队列中取出元素之后再将它插入到一个 “备份”的队列中,
    直到消费者完成正常的逻辑处理之后再将消息从备份中删除,这样可以提供一个守护的线程。当备
    份中的消息过期之后,可以将消息重新放回到主消息队列当中,以便其他的消费者可以继续去使用。
    
    
    • - 应用场景

             1. twitter 的关注列表、粉丝列表等都可以用 Redis 的 list结构来实现

               2. 抢购:使用redis的原子操作来实现这个“单线程”,首先我们把库存存在good_things:1这个列表中,如果有10件库存,就往列表中push10个数。抢购开始后,每来一个用户,就或从good_things:1中pop一个数,表示抢购成功,列表为空时,表示商品已经被抢完。pop操作是原子性的,此时如果有很多用户同时到达,也是依次执行的。

               3. 最新列表:获取前N个最新登录的用户列表

          // 获取当前登录人
          ret = r.lpush("login:last_login_times", uid)
          //限制列表中输在的数据数量
          ret = redis.ltrim("login:last_login_times", 0, N-1)
          // 获取前N个最新登录的用户Id列表
          last_login_list = r.range("login:last_login_times", 0, N-1)
    

    Set(字符集合)

    • - 与list集合的不同:

      • Set集合不允许出现重复的元素,也就是说重复添加多个相同的元素只会保留该元素的一份copy。

      • 功能上: 在服务器端可以完成多个set之间的聚合计算操作,如 unions,difference,这些都是需要在服务器端完成的,因此可以省掉大量的开销。

      • Set包含的最大元素数量是 4294967295

    • - 存储Set常用的命令:

      • 添加/删除元素:sadd 、srem
    image.png
    • 获得指定元素:

        smembers:获取set中的数据
        sismember:判断参数中有没有指定的元素在set里面
      
    image.png
    • 集合中的差集运算:

        sdiff:返回集合当中相差的成员(与key的顺序有关系)
        sinter:返回交集(都有的数据)
        sunion:返回并集
      
    image.png
    • 扩展命令:

        scard :获取具体数量
        srandmember : 随机返回 set中的成员
        sdiffstore:将相差的值存到一个新的集合上
        sinterstore:两个集合的交集将他们存到新的集合
        sunion: 两个并集的交集将他们存到新的集合
      
    image.png
    • - 使用场景:

      • 使用redis的set类型去跟踪一些具有唯一性的数据,

        1. 如:访问某一博客的唯一IP地址的信息,我们只需要在每次访问者访问该博客的时候,将访问者的IP存入到redis当中,然后set类型 会自动的保证IP地址的唯一性

        2. 如:set查询该用户名是否被注册,效率极高

        3. 如:投票系统中,如果在限制用户一天只能只能投票一次,可以将今天日期作为 set 的key,存取用户额投票行为,从而保证投票唯一。

      • 用于维护数据之间的关联关系(利用set类型的服务端聚合)

        1. 如:所有购买某一个电子设备的ID被存储到一个指定的set当中,而购买另外一个电子产品的客户的ID被存储到另外的一个set当中,而如果此时我们想获取由哪些客户同事购买了这两种产品,那么就可以使用它的一个“交集”的操作来完成。
        2. 如:将关注人 和 粉丝 存在不同的集合中。redis为集合提供求交集、并集、差集等操作,可方便实现如共同关注、共同喜好等功能,对上面的所有集合操作,还可使用不同命令结果返回给客户端或者存集到一个新的集合中。

    Sorted-set(有序的set集合):

    • 和set集合共同点:都不允许重复的成员出现在set当中
    • -和set集合的主要区别:

      • Sorted-Set 中的每一个成员都会有一个“分数”进行关联,而redis正是通过了这个分数来为集合中的成员进行从小到大的排序
      • 尽管 Sorted-Set中的成员必须是唯一的,但是分数是可以重复的,那么在 Sorted - Set中“添加、删除、更新”一个成员都是非常快速的操作。
    • 实践复杂度:由成员中的个数到对数。由于Sorted-Set集合中一个位置是有序的,因此访问集合“中部”的这些成员也是非常高效的。redis这一特征在其他很多数据库中都是很难实现的,也就是说在该“点”要想达到和redis一样的高效,在其他数据库中进行“建模”是非常困难的。

    • 添加:

          zadd : 返回添加的元素的个数  ,如果存在了再添加此元素,会执行“覆盖”。
      
    image.png
    • 获得元素:

        zscore:获取某一元素
        zcard:获取具体成员数量
      
    image.png
    • 删除元素:

        zrem :删除某一元素
      
    image.png
    • 范围查询:

        zrange:withsscores 参数:表示将分数也显示出来
        zrevrange (更改排序方式):大 ->小
      
    image.png
    • 排序:

        zremrangebyrank : 根据范围删除
        zremrangebyscore:根据分数范围删除元素
      
    image.png
    • 扩展命令:

        zrangebyscore : 查找某一分数范围内的元素,withscores表示同时也显示分数。
        zincrby:设置指定成员增加多少分数
        zcount:获取分数在某个区间的个数
      
    • - 应用场景

      • 排行榜:以“登录次数”为权重,获取登录次数最多的用户将登录次数和用户统一存储在一个sorted set里

                       zadd login:login_times 5 1
                       zadd login:login_times 1 2
        
                       //当用户登录时,对该用户的登录次数自增1
                       ret = r.zincrby("login:login_times", 1, uid)
                       //那么如何获得登录次数最多的用户呢,逆序排列取得排名前N的用户
                       ret = r.zrevrange("login:login_times", 0, N-1)
        
      • 游戏排行榜:获取前100名高分用户,或者获取用户全球排名等

          // 将分数写入数据库中    
          ZADD leaderboard <score> <username>   
          // 实现分数从高到低排名,然后获取0-99,也就是100名游戏玩家         
          ZREVRANGE leaderboard 0 99  
          // 获取某用户的全球排名
          ZRANK leaderboard <username>  
        

    Keys的通用操作

    • -命令:

      • 获得所有的keys:keys *

      • 以 ”my“ 开头的keys:keys my?

      • 删除某个指定的keys :del key1 key2

      • 判断某key是否存在:exists my1

      • 获取key : get my1

      • 重命名:rename my1 my2

      • 设置过期时间 : expire my2 1000 (秒)

      • 查看某key过期时间:ttl my1

      • 查看key类型: type my1


        image.png

    redis特性

    • -多数据库:

      • 一个redis实例可以包含多个数据库,可以指定连接某个数据库

      • 一个redis实例最多可提供16个数据库,0-15 默认连接:0

      • 命令:切换“1”号数据库:select 1

          将1号数据库中的“myset”key移动到“0”数据库:
                                              move myset 0
        
    image.png
    • -事物:

      • 事物中所有命令都将会被串行化顺序执行,在执行过程中,redis不会再对其他客户端提供任何服务,从而保证事物的“原子性”

        • - 命令:

          1. 开启事物:mutli,此后的命令都会被存放到一个队列当中,直到执行 exec,这些命令都会被原子化执行了
          2. 提交:exec,相当于关系型数据库中的commit
          3. discard:回滚,相当于关系型数据库中的roll-back
    • -注意:

      1. 如果在开启事物之前,如果客户端和服务端出现通讯故障导致服务器断开,那么执行的这些语句都将不会被服务器提交。
      2. 而如果网络中断是发生在exec(执行)之后的,那个这个十五中的所有命令都会被服务器提交。
    • 演示一:开启两个窗口


      image.png
    • 演示二:回滚


      image.png

    redis持久化:

    • redis的高性能是由于所有的数据都存储在内存当中,要是保证在重启之后数据不丢失,就需要将数据从内存同步到硬盘上,这个过程就是redis的持久化操作。

    • 持久化方式:

        -- RDB方式
        -- AOF方式
      
    • - 持久化的使用方式:

      • RDB持久化:默认支持,无需配置

      指的是在指定的时间间隔内将内存中数据集快照写入到磁盘,即:指定多少s可将数据写入到磁盘一次。

      • AOF方式:以日志的形式记录服务器所处理的每一个操作。在redis服务器启动之初,他会读取该文件来重新去构建我们的数据库,从而来保证我们数据库中的数据是完整的。

      • 无持久化:通过配置来禁用redis服务器的持久化功能。这样我们将可以认为redis就是一个“缓存”的机制。

      • 同时使用RDB和AOF

    相关文章

      网友评论

          本文标题:Redis 常用5大数据类型及应用场景

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