• Redis 学习-上


    一、Redis 概述

    1.1、Redis 定义

    • Redis (Remote Dictionary Server):远程字典服务
    • 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、 key-Value 数据库,并提供多种语言的 API。
    • 数据都是缓存在内存中 ,Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。
    • Reids 官方网站:https://redis.io/

    1.2、Redis 特性

    • 数据间没有必然的关联关系
    • 内部采用单线程机制进行工作
    • 高性能
    • 支持多种数据格式(字符串、列表、集合、哈希、有序集合...)
    • 支持持久化,可进行数据灾难恢复

    二、Redis 常用数据类型

    2.1、Redis key

    1、redis 键的特性

    • 在 redis 中无论什么数据类型,在数据库中都市以 key-Value 形式保存,通过进行对 Redis-key 的操作,来完成对数据中数据的操作。
    • 空字符串也是一个有效的键
    • 允许的最大 key 大小为 512MB
    • key 中允许存在 点或破折号/冒号,如:"comment🔢reply-to"

    2、redis 相关命令

    • exists key:判断键是否存在

    • del key:删除键值对

    • move key db:将键值对移动到指定数据库

    • expire key second:设置键值对过期时间

    • type key:查看 value 的数据类型

    • TTL key:返回 key 的过期时间,一般来说有三种

      • 当前 key 没有设置过期时间,所以会返回 -1
      • 当前 key 有设置过期时间,而且 key 已经过期,所以会返回 -2
      • 当前 key 有设置过期时间,且 key 还没有过期,故会返回 key 的正常剩余时间
    • rename key newkey:修改 key 的名称

    • renamenx key newkey:仅当 newkey 不存在时,将 key 改名为 newkey

    2.2、String 字符串

    2.2.1、概述

    • 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。

    2.2.2、相关命令

    1、赋值命令

    命令原型:*SET* key value

    时间复杂度:O(1)

    命令描述:设定该Key持有指定的字符串Value,如果该Key已经存在,则覆盖其原有值。

    返回值:总是返回"OK"。

    2、取值命令

    命令原型:G*ET* key

    时间复杂度:O(1)

    命令描述:获取指定Key的Value。如果与该Key关联的Value不是string类型,Redis将返回错误信息,因为GET命令只能用于获取string Value。

    返回值:与该Key相关的Value,如果该Key不存在,返回nil。

    3、GETSET命令

    命令原型:G*ETSET* key value

    时间复杂度:O(1)

    命令描述:原子性的设置该Key为指定的Value,同时返回该Key的原有值。和GET命令一样,该命令也只能处理string Value,否则Redis将给出相关的错误信息。

    返回值:返回该Key的原有值,如果该Key之前并不存在,则返回nil。

    4、递增数字

    命令原型:*INCR* key

    时间复杂度:O(1)

    命令描述:将指定Key的Value原子性的递增1。如果该Key不存在,其初始值为0,在incr之后其值为1。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。注意:该操作的取值范围是64位有符号整型。

    返回值:递增后的Value值。

    5、递减数字

    命令原型:DE*CR* key

    时间复杂度:O(1)

    命令描述:将指定Key的Value原子性的递减1。如果该Key不存在,其初始值为0,在decr之后其值为-1。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。注意:该操作的取值范围是64位有符号整型。

    返回值:递增后的Value值。

    6、增加指定的整数

    命令原型:*INCRBY* key increment

    时间复杂度:O(1)

    命令描述:将指定Key的Value原子性的增加increment。如果该Key不存在,其初始值为0,在incrby之后其值为increment。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。注意:该操作的取值范围是64位有符号整型。

    返回值:增加后的value值。

    7、减少指定的整数

    命令原型:DE*CRBY* key decrement

    时间复杂度:O(1)

    命令描述:将指定Key的Value原子性的减少decrement。如果该Key不存在,其初始值为0,在decrby之后其值为-decrement。如果Value的值不能转换为整型值,如Hello,该操作将执行失败并返回相应的错误信息。注意:该操作的取值范围是64位有符号整型。

    返回值:减少后的value值。

    8、SETEX命令

    命令原型:SETEX key seconds value

    时间复杂度:O(1)

    命令描述:原子性完成两个操作,一是设置该Key的值为指定字符串,同时设置该Key在Redis服务器中的存活时间(秒数)。该命令主要应用于Redis被当做Cache服务器使用时。

    返回值:

    9、SETNX命令

    命令原型:SETNX key value

    时间复杂度:O(1)

    命令描述:如果指定的Key不存在,则设定该Key持有指定字符串Value,此时其效果等价于SET命令。相反,如果该Key已经存在,该命令将不做任何操作并返回。

    返回值:1表示设置成功,否则0。

    10、向尾部追加值

    命令原型:APPEND key value

    时间复杂度:O(1)

    命令描述:如果该Key已经存在,APPEND命令将参数Value的数据追加到已存在Value的末尾。如果该Key不存在,APPEND命令将会创建一个新的Key/Value。

    返回值:追加后Value的长度。

    11、获取字符串长度

    命令原型:STRLEN key value

    时间复杂度:O(1)

    命令描述:返回指定Key的字符值长度,如果Value不是string类型,Redis将执行失败并给出相关的错误信息。

    返回值:返回指定Key的Value字符长度,如果该Key不存在,返回0。

    12、设置多个键值

    命令原型:*MSET* key value [key value ...]

    时间复杂度:O(N)

    命令描述:N表示指定Key的数量。该命令原子性的完成参数中所有key/value的设置操作,其具体行为可以看成是多次迭代执行SET命令。

    返回值:该命令不会失败,始终返回OK。

    13、获取多个键值

    命令原型:*MGET* key [key ...]

    时间复杂度:O(N)

    命令描述:N表示获取Key的数量。返回所有指定Keys的Values,如果其中某个Key不存在,或者其值不为string类型,该Key的Value将返回nil。

    返回值:返回一组指定Keys的Values的列表。

    14、MSETNX命令

    命令原型:*MSETNX* key value [key value ...]

    时间复杂度:O(N)

    命令描述:N表示指定Key的数量。该命令原子性的完成参数中所有key/value的设置操作,其具体行为可以看成是多次迭代执行SETNX命令。然而这里需要明确说明的是,如果在这一批Keys中有任意一个Key已经存在了,那么该操作将全部回滚,即所有的修改都不会生效。

    返回值:1表示所有Keys都设置成功,0则表示没有任何Key被修改。

    2.2.3、String 的应用场景

    1、计数器

    2、缓存基础数据

    3、对象存储缓存

    4、页面防重提交

    2.3、List 列表

    2.3.1、概述

    • 在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。
    • 从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。相信对于有良好数据结构基础的开发者而言,这一点并不难理解。

    2.3.2、相关命令

    1、向列表左边添加元素

    命令原型:*LPUSH* key value [value ...]

    时间复杂度:O(1)

    命令描述:在指定Key所关联的List Value的头部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的头部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。

    返回值:插入后链表中元素的数量。

    2、向列表右边添加元素

    命令原型:R*PUSH* key value [value ...]

    时间复杂度:O(1)

    命令描述:在指定Key所关联的List Value的尾部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的尾部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。

    返回值:插入后链表中元素的数量。

    3、*LPUSHX命令*

    命令原型:****LPUSHX key value

    时间复杂度:O(1)

    命令描述:仅有当参数中指定的Key存在时,该命令才会在其所关联的List Value的头部插入参数中给出的Value,否则将不会有任何操作发生。

    返回值:插入后链表中元素的数量。

    4、R*PUSHX命令*

    命令原型:R****PUSHX key value

    时间复杂度:O(1)

    命令描述:仅有当参数中指定的Key存在时,该命令才会在其所关联的List Value的尾部插入参数中给出的Value,否则将不会有任何操作发生。

    返回值:插入后链表中元素的数量。

    5、从列表左边弹出元素

    命令原型:LPOP key

    时间复杂度:O(1)

    命令描述:返回并弹出指定Key关联的链表中的第一个元素,即头部元素。如果该Key不存在,返回nil。LPOP命令执行两步操作:第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。

    返回值:链表头部的元素。

    6、从列表右边弹出元素

    命令原型:RPOP key

    时间复杂度:O(1)

    命令描述:返回并弹出指定Key关联的链表中的最后一个元素,即尾部元素。如果该Key不存在,返回nil。

    返回值:链表尾部的元素。

    7、获取列表中元素的个数

    命令原型:LLEN key

    时间复杂度:O(1)

    命令描述:返回指定Key关联的链表中元素的数量,如果该Key不存在,则返回0。如果与该Key关联的Value的类型不是链表,则返回相关的错误信息。

    返回值:链表中元素的数量。

    8、获得列表片段

    命令原型:****LRANGE key start stop

    时间复杂度:O(S+N)

    命令描述:时间复杂度中的S为start参数表示的偏移量,N表示元素的数量。该命令的参数start和end都是0-based。即0表示链表头部(leftmost)的第一个元素。其中start的值也可以为负值,-1将表示链表中的最后一个元素,即尾部元素,-2表示倒数第二个并以此类推。该命令在获取元素时,start和end位置上的元素也会被取出。如果start的值大于链表中元素的数量,空链表将会被返回。如果end的值大于元素的数量,该命令则获取从start(包括start)开始,链表中剩余的所有元素。注:Redis的列表起始索引为0。显然,LRANGE numbers 0 -1 可以获取列表中的所有元素。

    返回值:返回指定范围内元素的列表。

    9、删除列表中指定的值

    命令原型:****LREM key count value

    时间复杂度:O(N)

    命令描述:时间复杂度中N表示链表中元素的数量。在指定Key关联的链表中,删除前count个值等于value的元素。如果count大于0,从头向尾遍历并删除,如果count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。如果指定的Key不存在,则直接返回0。

    返回值:返回被删除的元素数量。

    10、设置指定索引的元素值

    命令原型:****LSET key index value

    时间复杂度:O(N)

    命令描述:时间复杂度中N表示链表中元素的数量。但是设定头部或尾部的元素时,其时间复杂度为O(1)。设定链表中指定位置的值为新值,其中0表示第一个元素,即头部元素,-1表示尾部元素。如果索引值Index超出了链表中元素的数量范围,该命令将返回相关的错误信息。

    返回值:

    11、获取指定索引的元素值

    命令原型:****LINDEX key index

    时间复杂度:O(N)

    命令描述:时间复杂度中N表示在找到该元素时需要遍历的元素数量。对于头部或尾部元素,其时间复杂度为O(1)。该命令将返回链表中指定位置(index)的元素,index是0-based,表示头部元素,如果index为-1,表示尾部元素。如果与该Key关联的不是链表,该命令将返回相关的错误信息。

    返回值:返回请求的元素,如果index超出范围,则返回nil。

    12、只保留列表指定片段

    命令原型:****LTRIM key start stop

    时间复杂度:O(N)

    命令描述:N表示被删除的元素数量。该命令将仅保留指定范围内的元素,从而保证链接中的元素数量相对恒定。start和stop参数都是0-based,0表示头部元素。和其他命令一样,start和stop也可以为负值,-1表示尾部元素。如果start大于链表的尾部,或start大于stop,该命令不报错,而是返回一个空的链表,与此同时该Key也将被删除。如果stop大于元素的数量,则保留从start开始剩余的所有元素。

    返回值:

    13、向列表中插入元素

    命令原型:****LINSERT key BEFORE|AFTER pivot value

    时间复杂度:O(N)

    命令描述:时间复杂度中N表示在找到该元素pivot之前需要遍历的元素数量。这样意味着如果pivot位于链表的头部或尾部时,该命令的时间复杂度为O(1)。该命令的功能是在pivot元素的前面或后面插入参数中的元素value。如果Key不存在,该命令将不执行任何操作。如果与Key关联的Value类型不是链表,相关的错误信息将被返回。

    返回值:成功插入后链表中元素的数量,如果没有找到pivot,返回-1,如果key不存在,返回0。

    14、将元素从一个列表转到另一个列表

    命令原型:****RPOPLPUSH source destination

    时间复杂度:O(1)

    命令描述:原子性的从与source键关联的链表尾部弹出一个元素,同时再将弹出的元素插入到与destination键关联的链表的头部。如果source键不存在,该命令将返回nil,同时不再做任何其它的操作了。如果source和destination是同一个键,则相当于原子性的将其关联链表中的尾部元素移到该链表的头部。

    RPOPLPUSH是个很有意思的命令,从名字就可以看出它的功能:先执行RPOP命令再执行LPUSH命令。RPOPLPUSH命令会先从source 列表类型键的右边弹出一个元素,然后将其加入到destination 列表类型键的左边,并返回这个元素的值,整个过程是原子的。

    返回值:返回弹出和插入的元素。

    2.3.3、List 应用场景

    1、消息队列

    2、更新最新动态

    2.4、Hash 哈希

    2.4.1、概念

    • 我们可以将Redis中的Hash类型看成具有String Key和String Value的map容器。所以该类型非常适合于存储值对象的信息。如Username、Password和Age等。如果Hash中包含很少的字段,那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。

    2.4.2、相关命令

    1、赋值命令

    命令原型:****HSET key field value

    时间复杂度:O(1)

    命令描述:为指定的Key设定Field/Value对,如果Key不存在,该命令将创建新Key以用于存储参数中的Field/Value对,如果参数中的Field在该Key中已经存在,则用新值覆盖其原有值。

    返回值:1表示新的Field被设置了新值,0表示Field已经存在,用新值覆盖原有值。

    2、取值命令

    命令原型:****HGET key field

    时间复杂度:O(1)

    命令描述:返回指定Key中指定Field的关联值。

    返回值:返回参数中Field的关联值,如果参数中的Key或Field不存在,返回nil。

    3、判断字段是否存在

    命令原型:****HEXISTS key field

    时间复杂度:O(1)

    命令描述:判断指定Key中的指定Field是否存在。

    返回值:1表示存在,0表示参数中的Field或Key不存在。

    4、获得字段数量

    命令原型:****HLEN key

    时间复杂度:O(1)

    命令描述:获取该Key所包含的Field的数量。

    返回值:返回Key包含的Field数量,如果Key不存在,返回0。

    5、删除字段

    命令原型:****HDEL key field [field ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示参数中待删除的字段数量。从指定Key的Hashes Value中删除参数中指定的多个字段,如果不存在的字段将被忽略。如果Key不存在,则将其视为空Hashes,并返回0。

    返回值:实际删除的Field数量。

    6、当字段不存在时赋值

    命令原型:****HSETNX key field value

    时间复杂度:O(1)

    命令描述:只有当参数中的Key或Field不存在的情况下,为指定的Key设定Field/Value对,否则该命令不会进行任何操作。

    返回值:1表示新的Field被设置了新值,0表示Key或Field已经存在,该命令没有进行任何操作。

    7、增加数字

    命令原型:****HINCRBY key field increment

    时间复杂度:O(1)

    命令描述:增加指定Key中指定Field关联的Value的值。如果Key或Field不存在,该命令将会创建一个新Key或新Field,并将其关联的Value初始化为0,之后再指定数字增加的操作。该命令支持的数字是64位有符号整型,即increment可以负数。

    返回值:返回运算后的值。

    8、获取指定键中所有的字段/值

    命令原型:****HGETALL key

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示Key包含的Field数量。获取该键包含的所有Field/Value。其返回格式为一个Field、一个Value,并以此类推。

    返回值:Field/Value的列表。

    9、只获取字段名

    命令原型:HKEYS key

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示Key包含的Field数量。返回指定Key的所有Fields名。

    返回值:Field的列表。

    10、只获取字段值

    命令原型:HVALS key

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示Key包含的Field数量。返回指定Key的所有Values名。

    返回值:value的列表。

    11、设置多个字段的值

    命令原型:****HMSET key field value [field value ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示被设置的Field数量。逐对依次设置参数中给出的Field/Value对。如果其中某个Field已经存在,则用新值覆盖原有值。如果Key不存在,则创建新Key,同时设定参数中的Field/Value。

    返回值:

    12、获取多个字段的值

    命令原型:HMGET key field [field ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示请求的Field数量。获取和参数中指定Fields关联的一组Values。如果请求的Field不存在,其值返回nil。如果Key不存在,该命令将其视为空Hash,因此返回一组nil。

    返回值:返回和请求Fields关联的一组Values,其返回顺序等同于Fields的请求顺序。

    2.4.3、Hash 应用场景

    1、Hash 更适合对象的存储,String 更适合字符串的存储。

    2.5、Set 集合

    2.5.1、概念

    • Redis的Set是string类型的 无序集合 ,集合成员是 唯一 的,这就意味着集合中不能出现重复的数据。
    • Redis 中 集合是通过 哈希表 实现的,所以添加,删除,查找的复杂度都是O(1)。
    • 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储 40多亿 个成员)。

    2.5.2、相关命令

    1、增加元素

    命令原型:****SADD key member [member ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示操作的成员数量。如果在插入的过程用,参数中有的成员在Set中已经存在,该成员将被忽略,而其它成员仍将会被正常插入。如果执行该命令之前,该Key并不存在,该命令将会创建一个新的Set,此后再将参数中的成员陆续插入。如果该Key的Value不是Set类型,该命令将返回相关的错误信息。

    返回值:本次操作实际插入的成员数量。

    2、获得集合中元素个数

    命令原型:****SCARD key

    时间复杂度:O(1)

    命令描述:获取Set中成员的数量。

    返回值:返回Set中成员的数量,如果该Key并不存在,返回0。

    3、判断元素是否在集合中

    命令原型:****SISMEMBER key member

    时间复杂度:O(1)

    命令描述:判断参数中指定成员是否已经存在于与Key相关联的Set集合中。

    返回值:1表示已经存在,0表示不存在,或该Key本身并不存在。

    4、获得集合中的所有元素

    命令原型:****SMEMBERS key

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示Set中已经存在的成员数量。获取与该Key关联的Set中所有的成员。

    返回值:返回Set中所有的成员。

    5、从集合中弹出一个元素

    命令原型:****SPOP key

    时间复杂度:O(1)

    命令描述:随机的移除并返回Set中的某一成员。 由于Set中元素的布局不受外部控制,因此无法像List那样确定哪个元素位于Set的头部或者尾部。

    返回值:返回移除的成员,如果该Key并不存在,则返回nil。

    6、删除元素

    命令原型:****SREM key member [member ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示被删除的成员数量。从与Key关联的Set中删除参数中指定的成员,不存在的参数成员将被忽略,如果该Key并不存在,将视为空Set处理。

    返回值:从Set中实际移除的成员数量,如果没有则返回0。

    7、随机获得集合中的元素

    命令原型:****SRANDMEMBER key [count]

    时间复杂度:O(1)

    命令描述:和SPOP一样,随机的返回Set中的一个成员,不同的是该命令并不会删除返回的成员。还可以传递count参数来一次随机获得多个元素,根据count的正负不同,具体表现也不同。当count 为正数时,SRANDMEMBER 会随机从集合里获得count个不重复的元素。如果count的值大于集合中的元素个数,则SRANDMEMBER 会返回集合中的全部元素。当count为负数时,SRANDMEMBER 会随机从集合里获得|count|个的元素,这些元素有可能相同。

    返回值:返回随机位置的成员,如果Key不存在则返回nil。

    8、将元素从一个集合转到另一个集合

    命令原型:****SMOVE source destination member

    时间复杂度:O(1)

    命令描述:原子性的将参数中的成员从source键移入到destination键所关联的Set中。因此在某一时刻,该成员或者出现在source中,或者出现在destination中。如果该成员在source中并不存在,该命令将不会再执行任何操作并返回0,否则,该成员将从source移入到destination。如果此时该成员已经在destination中存在,那么该命令仅是将该成员从source中移出。如果和Key关联的Value不是Set,将返回相关的错误信息。

    返回值:1表示正常移动,0表示source中并不包含参数成员。

    9、集合间差集运算

    命令原型:****SDIFF key [key ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示所有Sets中成员的总数量。返回参数中第一个Key所关联的Set和其后所有Keys所关联的Sets中成员的差异。如果Key不存在,则视为空Set。

    返回值:差异结果成员的集合。

    10、集合间差集运算并将结果存储

    命令原型:****SDIFFSTORE destination key [key ...]

    时间复杂度:O(N)

    命令描述:该命令和SDIFF命令在功能上完全相同,两者之间唯一的差别是SDIFF返回差异的结果成员,而该命令将差异成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。

    返回值:返回差异成员的数量。

    11、集合间交集运算

    命令原型:****SINTER key [key ...]

    时间复杂度:O(N*M)

    命令描述:时间复杂度中的N表示最小Set中元素的数量,M则表示参数中Sets的数量。该命令将返回参数中所有Keys关联的Sets中成员的交集。因此如果参数中任何一个Key关联的Set为空,或某一Key不存在,那么该命令的结果将为空集。

    返回值:交集结果成员的集合。

    12、集合间交集运算并将结果存储

    命令原型:****SINTERSTORE destination key [key ...]

    时间复杂度:O(N*M)

    命令描述:命令和SINTER命令在功能上完全相同,两者之间唯一的差别是SINTER返回交集的结果成员,而该命令将交集成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。

    返回值:返回交集成员的数量。

    13、集合间并集运算

    命令原型:****SUNION key [key ...]

    时间复杂度:O(N)

    命令描述:时间复杂度中的N表示所有Sets中成员的总数量。该命令将返回参数中所有Keys关联的Sets中成员的并集。

    返回值:并集结果成员的集合。

    14、集合间并集运算并将结果存储

    命令原型:****SUNIONSTORE destination key [key ...]

    时间复杂度:O(N)

    命令描述:该命令和SUNION命令在功能上完全相同,两者之间唯一的差别是SUNION返回并集的结果成员,而该命令将并集成员存储在destination关联的Set中。如果destination键已经存在,该操作将覆盖它的成员。

    返回值:返回并集成员的数量

    2.5.3、Set 应用场景

    1、使用场景: ①交集,并集,差集:(Set)

    //book表存储book名称set book:1:name    ”The Ruby Programming Language”set book:2:name     ”Ruby on rail”set book:3:name     ”Programming Erlang” //tag表使用集合来存储数据,因为集合擅长求交集、并集sadd tag:ruby 1 sadd tag:ruby 2 sadd tag:web 2 sadd tag:erlang 3//即属于ruby又属于web的书?inter_list = redis.sinter("tag.web", "tag:ruby") //即属于ruby,但不属于web的书?inter_list = redis.sdiff("tag.ruby", "tag:web") //属于ruby和属于web的书的合集?inter_list = redis.sunion("tag.ruby", "tag:web")
    

    2.6、Zset 有序集合

    2.6.1、概念

    • 不同的是每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大的排序。score相同:按字典顺序排序
    • 有序集合的成员是唯一的,但分数(score)却可以重复

    2.6.2、相关命令

    1、增加元素

    命令原型:****ZADD key score member [score] [member]

    时间复杂度:O(log(N))

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量。添加参数中指定的所有成员及其分数到指定key的Sorted Set中,在该命令中我们可以指定多组score/member作为参数。如果在添加时参数中的某一成员已经存在,该命令将更新此成员的分数为新值,同时再将该成员基于新值重新排序。如果键不存在,该命令将为该键创建一个新的Sorted Set Value,并将score/member对插入其中。如果该键已经存在,但是与其关联的Value不是Sorted Set类型,相关的错误信息将被返回。

    返回值:本次操作实际插入的成员数量。

    2、获得集合中元素个数

    命令原型:Z****CARD key

    时间复杂度:O(1)

    命令描述:获取与该Key相关联的Sorted Set中包含的成员数量。

    返回值:返回Sorted Set中的成员数量,如果该Key不存在,返回0。

    3、获得指定分数范围内的元素个数

    命令原型:****ZCOUNT key min max

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted-Sets中成员的数量,M则表示min和max之间元素的数量。该命令用于获取分数(score)在min和max之间的成员数量。针对min和max参数需要额外说明的是,-inf和+inf分别表示Sorted-Sets中分数的最高值和最低值。**缺省情况下,min和max表示的范围是闭区间范围,即min <= score <= max内的成员将被返回。然而我们可以通过在min和max的前面添加"("字符来表示开区间,如(min max表示min < score <= max,而(min (max表示min < score < max。

    返回值:分数指定范围内成员的数量。

    4、获得元素的分数

    命令原型:****ZSCORE key member

    时间复杂度:O(1)

    命令描述:获取指定Key的指定成员的分数。

    返回值:如果该成员存在,以字符串的形式返回其分数,否则返回nil。

    5、增加某个元素的分数

    命令原型:****ZINCRBY key increment member

    时间复杂度:O(log(N))

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量。该命令将为指定Key中的指定成员增加指定的分数。如果成员不存在,该命令将添加该成员并假设其初始分数为0,此后再将其分数加上increment。如果Key不存在,该命令将创建该Key及其关联的Sorted Set,并包含参数指定的成员,其分数为increment参数。如果与该Key关联的不是Sorted Set类型,相关的错误信息将被返回。

    返回值:以字符串形式表示的新分数。

    6、获得排名在某个范围的元素列表

    命令原型:****ZRANGE key start stop [WITHSCORES]

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示返回的成员数量。该命令返回顺序在参数start和stop指定范围内的成员,这里start和stop参数都是0-based,即0表示第一个成员,-1表示最后一个成员。如果start大于该Sorted Set中的最大索引值,或start > stop,此时一个空集合将被返回。如果stop大于最大索引值,该命令将返回从start到集合的最后一个成员。如果命令中带有可选参数WITHSCORES选项,该命令在返回的结果中将包含每个成员的分数值,如value1,score1,value2,score2...。  

    返回值:返回索引在start和stop之间的成员列表。

    7、获得排名在某个范围的元素列表(元素分数从大到小排序)

    命令原型:****ZREVRANGE key start stop [WITHSCORES]

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示返回的成员数量。该命令的功能和ZRANGE基本相同,唯一的差别在于该命令是通过反向排序获取指定位置的成员,即从高到低的顺序。如果成员具有相同的分数,则按降序字典顺序排序。

    返回值:返回指定的成员列表。

    8、获得指定分数范围的元素

    命令原型:****ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示返回的成员数量。该命令将返回分数在min和max之间的所有成员,即满足表达式min <= score <= max的成员,其中返回的成员是按照其分数从低到高的顺序返回,如果成员具有相同的分数,则按成员的字典顺序返回。可选参数LIMIT用于限制返回成员的数量范围。可选参数offset表示从符合条件的第offset个成员开始返回,同时返回count个成员。可选参数WITHSCORES的含义参照ZRANGE中该选项的说明。最后需要说明的是参数中min和max的规则可参照命令ZCOUNT。

    返回值:返回分数在指定范围内的成员列表。

    9、获得指定分数范围的元素(元素分数从大到小排序)

    命令原型:****ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示返回的成员数量。该命令除了排序方式是基于从高到低的分数排序之外,其它功能和参数含义均与ZRANGEBYSCORE相同。需要注意的是该命令中的min和max参数的顺序和ZRANGEBYSCORE命令是相反的。

    返回值:返回分数在指定范围内的成员列表。

    10、获得元素的排名

    命令原型:****ZRANK key member

    时间复杂度:O(log(N))

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量。Sorted Set中的成员都是按照分数从低到高的顺序存储,该命令将返回参数中指定成员的位置值,其中0表示第一个成员,它是Sorted Set中分数最低的成员。

    返回值:如果该成员存在,则返回它的位置索引值。否则返回nil。

    11、获得元素的排名(元素分数从大到小排序)

    命令原型:****ZREVRANK key member

    时间复杂度:O(log(N))

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量。该命令的功能和ZRANK基本相同,唯一的差别在于该命令获取的索引是从高到低排序后的位置,同样0表示第一个元素,即分数最高的成员。

    返回值:如果该成员存在,则返回它的位置索引值。否则返回nil。

    12、删除一个或多个元素

    命令原型:****ZREM key member [member ...]

    时间复杂度:O(M log(N))

    命令描述:时间复杂度中N表示Sorted Set中成员的数量,M则表示被删除的成员数量。该命令将移除参数中指定的成员,其中不存在的成员将被忽略。如果与该Key关联的Value不是Sorted Set,相应的错误信息将被返回。

    返回值:实际被删除的成员数量。

    13、按照排名范围删除元素

    命令原型:****ZREMRANGEBYRANK key start stop

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示被删除的成员数量。删除索引位置位于start和stop之间的成员,start和stop都是0-based,即0表示分数最低的成员,-1表示最后一个成员,即分数最高的成员。

    返回值:被删除的成员数量

    14、按照分数范围删除元素

    命令原型:*ZREMRANGEBYSCORE* key start stop

    时间复杂度:O(log(N)+M)

    命令描述:时间复杂度中的N表示Sorted Set中成员的数量,M则表示被删除的成员数量。删除分数在min和max之间的所有成员,即满足表达式min <= score <= max的所有成员。对于min和max参数,可以采用开区间的方式表示,具体规则参照ZCOUNT。

    返回值:被删除的成员数量。

    2.6.3、Zset 应用场景

    • set排序 存储班级成绩表 工资表排序!
    • 普通消息,1.重要消息 2.带权重进行判断
    • 排行榜应用实现,取Top N测试

    2.7、三种特殊数据类型

    2.7.1、Geospatial(地理位置)

    • 使用经纬度定位地理坐标并用一个 有序集合 Zset 保存 ,所以 zset 命令也可以使用
    • 有效的经度从-180度到180度。
    • 有效的纬度从-85.05112878度到85.05112878度。

    2.7.2、Hyperloglog(基数统计)

    • HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。 花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。 因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。 其底层使用string数据类型
    • 什么是基数:数据集中不重复的元素的个数。

    2.7.3、BitMaps(位图)

    • 使用位存储,信息状态只有 0 和 1,Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作。
  • 相关阅读:
    javaBS景区票务管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    快速上手Linux核心命令(十一):Linux用户相关命令
    Kafka数据同步原理详解
    Spring Boot
    信息安全、网络安全以及数据安全三者之间的区别
    分布式事务(Seata)——Seata分布式事务XA模式、AT模式、TCC模式的介绍和对比 & 结合案例分析AT模式和XA模式【源码】
    企业数据防泄密软件-文件外发管理,文件,文档,图纸不外泄
    【springboot+vue项目(十四)】基于Oauth2的SSO单点登录(一)整体流程介绍
    stm32 - Cortex
    MATLAB中syms函数使用
  • 原文地址:https://www.cnblogs.com/s-cheng/p/15929655.html