• Redis之Datatype概述


    官方原文档:

      https://redis.io/topics/data-types

      https://redis.io/topics/data-types-intro

    Redis支持的数据类型:

    String、List、Set、Sorted Set、Hashes、Bit array、HyperLogLog

    Reids Keys(键):
    • Redis的键是二进制安全的:可以使用任何的二进制序列作为键。 比如"foo"这样的字符串,甚至是JPEG文件的二进制内容,空串""也是合法的键。
    • 不推荐使用特别长的键:
              影响性能,做键的比较,查找键是很耗费性能的
              同时对带宽以及内存要求很大,如果当前的任务是匹配大值的存在
              建议使用hash,比如SHA1 ,、MD5等
    • 不推荐使用特别短的键:
              例如使用"user:1000:followers"而不是"u1000flw"
              前者明显可读性高,而且增加的空间较小
    • 坚持用统一的命名结构:
              比如 "object-type:id"
              使用"."或"-"来表示由多个词语组成的字段
              比如"comment:1234:reply.to"或者"comment:1234:reply-to"
    • 键的最大长度是512MB
              这里的最大长度指的是单个key的长度
              对于value同样限制的是512MB

    String类型(字符串类型)

      String 是Redis中最基本的类型。Redis中的String 类型是二进制安全的,也就是说在Redis中String类型可以包含各种数据,比如一张JPEG图片或者是一个序列化的Ruby对象。一个String类型的值最大长度可以是512M。

    在Redis中String有很多有趣的用法,比如:

    • 把String当做原子计数器,这可以使用INCR家族中的命令来实现:INCRDECRINCRBY
    • 使用APPEND命令来给一个String追加内容。
    • 把String当做一个随机访问的向量(Vector),这可以使用GETRANGE和 SETRANGE命令来实现
    • 使用GETBIT 和SETBIT方法,在一个很小的空间中编码大量的数据,或者创建一个基于Redis的Bloom Filter 算法
    List类型
        List有两种底层实现机制:一种是基于array,而另一种是基于linked list。
        而Redis中的list就是基于后者(linked list)
        这样做的好处就是:
               在list头部/尾部 添加数据的时候,都可以以很快的速度去处理,不管你是添加1条数据,还是插入1亿条数据效率上都是差不多的。
        坏处就是:
               当你访问list的时候,随着index的变大,消耗的时间也将成比例增加。
        如果访问一个比较大的list 中间的元素的需求比较重要的话,建议使用sorted set。
     
        常用命令:
               LPUSH,RPUSH,LPOP,RPOP,LRANGE,LTRIM ... 
               LRANGE 
                        接受3个参数:一个list实例参数,两个index参数(起始位置、结束位置)
                        两个index参数均可以为负数,表示list.size() - index 处的元素的索引数
                        LRANGE mylist 0 -3 
               LPUSH/RPUSH 
                        它们的参数是可变长的参数
                        具体来说第一个参数接收一个list实例,后面n个参数均是要添加到list最开始/最末端 的元素,多个参数之间用空格分割
                         LPUSH mylist 12 4 www "ss" 
               LTRIM 
                        类似于LRANGE,所不同的是 LRANGE只是为了展现,而LTRIM会将在它抽取的范围外的元素都给移除
                        和LPUSH合作,可以实现保留最新多少条数据
                        LPUSH mylist 100 3 4
                        LTRIM mylist 0 999 
              LPOP/RPOP
                        将list最前端/最尾端的元素返回回来,并且将它从源list中删除掉
                        可以和PUSH操作一起使用实现生产者消费者模式    
     
    Redis的Lists类型有很多有趣的用法,比如:
    • 在社交网络中使用List进行时间表建模,使用LPUSH命令在用户时间线中加入新的元素,然后使用LRANGE 命令来获得最近加入的元素。
    • 可以把LPUSH 和LTRIM 命令结合使用来实现定长的列表,列表中只保存最近的N个元素
    • 在创建后台运行的工作时,Lists可以作为消息传递原语,例如著名的Ruby库 Resque
    • 还有很多可以使用lists来做的事,这种数据类型支持很多命令,包括像BLPOP这样的阻塞命令
        list最普遍的两个代表性用法
            1).记载用户发布到社交网络的最新更新
            2).使用消费者-生产者模式进行进程之间的通信:
                    生产者向一个list中添加元素
                    消费者消耗这些元素,并执行操作
                    Redis提供了一些list命令来保证这种做法的高效性以及可靠性
        list拥有一个特性使得它适合实现 队列,并且通常作为进程间通信系统的构建块。这个特性就是BLPOPBRPOP 是个阻塞操作
     
        Note : 
                正常来讲 生产者消费者模式,当消费者向list索取元素的时候,发现该队列为空,那么消费者通常会进行等待一会儿,然后再重试索取(这个过程叫轮询)
                这样,会导致redis以及客户端都做了很多无用的命令行操作,因此Redis提供了两个阻塞型的 pop 操作
                当list为空时,只有当新的元素被添加到list中后或者达到了用户指定的超时时间,BRPOP/BLPOP指令才会返回给调用者(一个结果)
        
                demo : 
                        BRPOP tasks 5  --等待tasks中的元素,如果超过5秒钟没有可以用的元素,就返回
       
                如果timeout参数 设置为 0 ,那么会永远等待新元素(不会超时,一直阻塞)
                其中list参数可以接受 多个列表,比如task1 task2 ...,当有一个列表任务有新增元素,就返回pop的结果
        
        关于BRPOP/BLPOP的一些需要注意的事情:
              1).客户端是按照顺序来享受服务的
                       第一个客户端阻塞的来等待一个list,那么当有新的元素被其它的客户端push进来,那么它(即第一个客户端)将会首先享受这个服务 
              2).和RPOP/LPOP的返回值不同
                      它是个包含键名的双元素的数组,因为BRPOP/BLPOP可以同时阻塞式地从多个list列表中等待元素 
              3).如果过期时间的阀值到了,将返回NULL
     
        关于list以及阻塞操作的更多内容:
             1).可以使用RPOPLPUSH指令 来构建更安全的队列 或者 旋转队列
             2).redis提供了一个阻塞的变种指令:BRPOPLPUSH
     
        主键的自动创建与删除
                三条规则来总结:
                    1). 当我们添加一个元素到聚合数据类型,如果目标关键字不存在,在添加这个元素之前会(自动)创建一个空的聚合数据类型
                    2). 当我们从聚合数据类型中移除元素的时候,,如果该值是空的,那么键也将自动被销毁
                    3). 调用 只读命令/移除元素的写命令 在一个空的关键字上,永远会返回同样的结果,好像该关键字正持有命令行希望找到空的数据类型
     
    Hashes (散列.哈希类型)
        Redis Hashes 保存 string fields和 string values之间的映射,所以它们是用来表示对象的绝佳数据类型(比如一个User对象):
        > hmset user:1000 username antirez birthyear 1977 verified 1
      OK
      > hget user:1000 username
      "antirez"
      > hget user:1000 birthyear
      "1977"
      > hgetall user:1000
      1) "username"
      2) "antirez"
      3) "birthyear"
      4) "1977"
      5) "verified"
      6) "1"

        一个有着少量数据域(这里的少量大概100上下)的hash,其存储方式占用很小的空间,所以在一个小的Redis实例中就可以存储上百万的这种对象。

        虽然Hashes主要用于表示对象,他们可以存储很多的元素,所以你可以使用Hashes来做许多其他的工作。

        Hash的最大长度是2^32 – 1个域值对(4294967295,一个Hash中可以有多达40多亿个域值对)

    Sets类型(集合类型)
        Redis的Sets类型是String的无序集合。增加,删除,测试元素是否存在的时间复杂度都是O(1)(不管集合中有多少元素都是稳定的时间消耗)
        Redis Sets的一个重要特性是不允许重复元素。向集合中添加多次相同的元素,集合中只存在一个该元素。在实际应用中,这意味着在添加一个元素前不需要先检查元素是否存在。
        关于Redis Sets一个非常有意思的事情是,它们支持多个服务器端命令来从现有集合开始计算集合,所以执行集合的交集,并集,差集都可以很快。
        set的最大长度是2^32 – 1个元素(4294967295,一个set中可以有多达40多亿个元素)

    Redis Sets有很多有趣的用法,比如:

    • 你可以使用Redis Sets来记录唯一的事物,比如,你想知道访问某个博客的IP地址,不要重复的IP,这种情况只需要在每次处理一个请求时简单的使用SADD命令就可以了,可以确信不会插入重复的IP.
    • Redis Sets 可以很好的表示关系。你可以使用Redis创建一个标签系统,每个标签使用一个Set来表示。然后你可以使用SADD 命令把具有特定标签的所有对象的所有ID放在表示这个标签的Set中。如果你想要知道同时拥有三个不同标签的对象,那么使用SINTER命令就好了。
    • 你可以使用SPOP 或者 SRANDMEMBER 命令从集合中随机的提取元素。
    Sorted sets 类型(有序集合类型)
        Redis有序集合类型与Redis的集合类型类似,是非重复的String元素的集合,Sorted Set像是Set以及Hash的混合体。不同之处在于,有序集合中的每个成员都关联一个Score,Score是在排序时候使用的,按照Score的值从小到大进行排序。集合中每个元素是唯一的,但Score有可能重复。
        使用有序集合可以很高效的进行,添加,移除,更新元素的操作(时间消耗与元素个数的对数成比例)。由于元素在集合中的位置是有序的,使用get ranges by score或者by rank(位置)来顺序获取或者随机读取效率都很高。(本句不确定,未完全理解原文意思,是根据自己对Redis的浅显理解进行的翻译)访问有序集合中间部分的元素也非常快,所以可以把有序集合当做一个不允许重复元素的智能列表,你可以快速访问需要的一切:获取有序元素,快速存在测试,快速访问中间的元素等等。
        简短来说,使用有序集合可以实现很多高性能的工作,这一点在其他数据库是很难实现的。

    使用有序集合你可以:

    • 在大型在线游戏中创建一个排行榜,每次有新的成绩提交,使用ZADD命令加入到有序集合中。可以使用ZRANGE命令轻松获得成绩名列前茅的玩家,你也可以使用ZRANK根据一个用户名获得该用户的分数排名。把ZRANK 和 ZRANGE结合使用你可以获得与某个指定用户分数接近的其他用户。这些操作都很高效。
    • 有序集合经常被用来索引存储在Redis中的数据。比如,如果你有很多用户,用Hash来表示,可以使用有序集合来为这些用户创建索引,使用年龄作为Score,使用用户的ID作为Value,这样的话使用ZRANGEBYSCORE 命令可以轻松和快速的获得某一年龄段的用户。
        排序规则:
              1).按照score(一个设置的浮点值)从小到大顺序排列的
              2).如果score一致,那么按照value的字段顺序排列
        实践注意:
              Sorted Set实现自两个接口(dual-ported):skip list 以及 hash table
              因此每次添加元素的时候,以O(log(N))复杂度进行操作.,这个复杂度是ok的
              但取数的时候,redis几乎不用做什么额外操作,因为顺序是已经排列好的
        常用命令:
               ZADD     some_set     any_score     the_element
               ZRANGE     some_set     start_index     end_index     [withscores]
               ZREVRANGE     some_set     start_index     end_index     [withsores]
               ZRANGEBYSCORE     some_set     -inf     any_score
               ZREMRANGEBYSCORE     some_set     any_start_score     any_end_score
               ZREVRANK     some_set
     
    以下命令是基于字典而非score来取得结果的
                ZRANGEBYLEX , ZREVRANGEBYLEX , ZREMRANGEBYLEX , ZLEXCOUNT
            
                demo : zrangebylex hackers [B [P -- 表示闭区间
     
                注意,所有*range*的操作,都会把这些元素从set中删除哦
     
    Bitmap
        Bitmap 并非是一种数据类型,而是String类型上的一组"面向-位"的操作 
        由于String是二进制安全的大文本(可以有512M大小),因此就有了 2^32种不同的位组合 
        bit操作分为两组:常量时间-单个位 的操作;bit组的操作(即多个bit的批量操作)
     
        常用命令 SETBIT , GETBIT , BITOP , BITCOUNT , BITPOS
     
        bitmap普遍使用场景:
            1).各种实时分析
            2).存储和对象id关联的boolean信息,,高效而又节省空间
     
    HyperLogLog (以下简称HLL)
        redis提供的一种概率数据结构,用于计算唯一事物(技术上来讲,是指估计一个集合的基数)
        如果用其它方式,会消耗成比例的内存来实现
        而是用redis提供的hyperloglog,可以得到比较精确的统计结果,这个结果相比真实结果,误差小于1%
        
        使用 PFADD 来添加计数;使用 PFCOUNT 来查询集合中的基数
     
        HLL中不会真的存储这些元素,该数据结构只保存一个状态
     
    Redis的其它显著特性
        1).支持 对大集合的中的键空间进行逐步迭代
        2).可以云信Lua脚本服务器端 来提升延迟和带宽
        3).Redis也是一个pub-sub服务器(即发布与订阅)
  • 相关阅读:
    day12 Python操作rabbitmq及pymsql
    day11 队列、线程、进程、协程及Python使用缓存(redis/memcache)
    day10 Python作用域 Python2.7与Python3.x的类继承的区别、异步IO、多进程,多线程简介
    day09 Python socket编程
    day08 面向对象补充及单例模式
    day07 configparser xml subprocess 面向对象
    day06 Python的一些内建变量、反射、hashlib模块、re模块、os模块、sys模块
    day05 Python多层装饰器、模块、序列化、字符串格式化、生成器和迭代器、递归、time、datetime模块、logging模块
    day04 Python一些内置函数及装饰器
    查看旧版jexus命令
  • 原文地址:https://www.cnblogs.com/hypo106/p/13258190.html
Copyright © 2020-2023  润新知