使用redis的常见数据类型

Mysql:

  • 首先应该考虑建立什么样的表或者模式
  • 使用SQL来操作redis中的数据
    Redis:
  • 首先应该考虑的是redis支持的哪种数据类型最适合我们的场景。
  • 不使用SQL来操作redis中的数据,需要直接使用API发送数据所对应的命令来操作想要操作的目标数据

准备

启动一个redis服务器,并且使用redis-cli连接这个redis服务器

使用字符串string类型

redis中所有的键都必须是字符串,字符串可以存储字节串,整数,浮点数。

1、SET系列

  • set
    作用:用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
    返回值:设置操作成功完成时,返回 OK

SET key “value”
GET key 【结果: “value”】
SET key “newvalue”
GET key 【结果: “newvalue”】
del key 【删除key】
get key 【结果:nil】

  • setnx(不存在时set):
    作用:仅在键不存在时设置键的值
    返回值:如果键的值设置成功,则返回1,如果键已经存在,则返回0且不覆盖原来的值

EXISTS job 【结果:0表示不存在】
SETNX job “programmer” 【结果1:成功】
SETNX job “programmer” 【覆盖失败:0】

  • MSET
    作用:一次设置多个key
    MSET PK SET:Mset的优点在于整个操作是原子性的,意味着所有的键都是在客户机与服务器之间的一次通信中设置的,因为,我们可以通过使用MSET而不是多个set来节省网络开销。
  • MSET key1 “Hello” key2 “World”
  • GET key1
  • GET key2
  • Msetnx命令
    作用:用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。[只要有一个key已经存在就失败]
    返回值:当所有 key 都成功设置,返回 1 。 只要有一个设置失败就全部失败,因为它们是原子性的,那么返回 0 。
  • MSETNX rmdbs “MySQL” nosql “MongoDB” key-value-store “redis”
  • MGET rmdbs nosql key-value-store
  1. “MySQL”
  2. “MongoDB”
  3. “redis”
  • MSETNX rmdbs “Sqlite” language “python” # rmdbs 键已经存在,操作失败
  • EXISTS language # 因为 MSET 是原子性操作,language 没有被设置,返回0
  • GET rmdbs # rmdbs 也没有被修改
    “MySQL”
  • Setex
    作用:为指定的 key 设置值及其过期时间[以秒为单位],如果 key 已经存在, SETEX 命令将会替换旧的值。key的值如果超出过期时间就为nil
    返回值:操作成功返回OK
  • SETEX mykey 30 redis
  • TTL mykey 【查看还剩下多少秒】
  • GET mykey
  • Psetex
    作用:以ms为单位设置key 的生存时间
    返回值:设置成功时返回 OK 。
  • PSETEX mykey 1000 “Hello”
  • PTTL mykey
  • get mykey
  • Setrange 命令
    作用:用指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始。如果不指定偏移,会默认从0开始
    返回值:被修改后的字符串长度。
  • SET key1 “Hello World”
  • SETRANGE key1 6 “Redis”
  • GET key1 【结果:“Hello Redis”】
  • GETSET 命令
    作用:设置指定 key 的值
    返回值:返回给定 key 的旧值。 当 key 没有旧值时,即 key 不存在时,返回 nil 。当 key 存在但不是字符串类型时,返回一个错误。
  • GETSET mynewkey “This is my test key” 【结果:(nil)】
  • GETSET mynewkey “This is my new value to test getset” 【结果:“This is my test key” 】

2、GET系列

  • GET命令
    作用:用于获取指定 key 的值
    返回值:
    返回 key 的值,
    如果 key 不存在时,返回 nil。
    如果 key 不是字符串类型,那么返回一个错误。

GET db【结果:(nil)】

  • Getrange 命令
    作用:用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。
    返回值:截取得到的子字符串。
  • SET mykey “This is my test key”
  • GETRANGE mykey 0 3 【结果:“This”】
  • GETRANGE mykey 0 -1 【结果: “This is my test key”】
  • MGET命令:
    作用:用于一次性获取多个键的值。
    返回值:如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。

SET key1 “hello”
SET key2 “world”
MGET key1 key2 someOtherKey
Redis系列(2):Redis的数据类型

4、对key-value的value进行加减

命令 描述和例子
incr incr key-name —将键存储的值加1
decr desc key-name —将键存储的值减1
incrby incrby key-name amount–将键存储的值加上整数amount
decrby decrby key-name amount–将键存储的值减去整数amount
incrByFloat incrByFloat key-name amount–将键存储的值加上浮点数amount

当用户将一个值存储到redis字符串里面的时候,如果这个值可以被解释为十进制整数或者浮点数,那么redis会察觉到这一点,并且允许用户对这个字符串执行加减,并且以字符串形式返回执行了命令之后的key对应的值。如果用户对一个不存在的键或者一个保存了空串的key进行加减,那么redis会在执行操作时将这个键的值当中0处理。不可以对非自然数的字符串进行加减,此时会返回错误

  • Incr 命令
  • incr num 【返回:(integer) 1】
  • get num 【返回:“1”】
  • incr num 【返回:(integer) 2】
  • get num 【返回:“2”】
  • Incrby
  • incrby num 20 【返回:(integer)22】
  • get num 【返回:“22”】
  • incrby num -2 【返回:(integer)20】
  • get num 【返回:“20”】
  • incrbyfloat
  • incrbyfloat num 9.9 【结果:”29.9“】
  • incrbyfloat num 0.100000000000000000【结果:”30“】
  • incrbyfloat num 314e-2 【结果:”33.14“】
    执行 INCRBYFLOAT 之后格式会被改成非指数符号

5、处理子串

命令 例子和描述 返回值和备注
append apped key-name value --将value追加到key存储的值的末尾 追加指定值之后, key 中字符串的长度
getrange getname key-name start end --获取索引[start, end]的子串 建议使用getrange而不是substr来获取子串
setrange setrange key-name offset value --从start偏移量开始的子串设置位给定值 返回字符串的长度
strlen 返回字符串的长度
  • append ‘key-name’ “hello”
  • getrange key-name 0 3 【结果:“hell”】
  • append ‘key-name’ " worldddddddddd"
  • setrange key-name 6 “redis” 【结果:“hello redisddddddddd”】
    strlen “key-name”【结果:(integer) 20】

6、使用object命令来查看与键相关联的redis值对象的内部编码方式
Redis使用了三种不同的编码方式来存储字符串对象,并会根据每个字符串值自动决定所使用的编码方式:

  • int:用于能够使用64位有符号整数表示的字符串
  • embstr:通用语长度小于或者等于44字节的字符串;这种类型的编码在内存使用和性能方面更有效率
  • raw:用于长度大于44字节的字符串
  • SET mykey 12345
  • OBJECT ENCODING mykey【结果int】
  • SET mykey “a string”
  • OBJECT ENCODING mykey 【结果embstr】
  • SET mykey “a llllllllllllllllllllllongongongong stringstringstingstring whos lengt is more 66”
  • OBJECT ENCODING mykey【结果raw】

使用list列表类型

列表可以从序列的两端推入或者弹出元素,获取列表元素等。列表可以用来存储任务信息,最近浏览过的文章或者常用联系人信息。类似双向链表

命令 描述 返回值
lpush lpush k-name value [value …]–将一个或者多个值推入列表的右端 执行 lpush 命令后,当前列表的长度
rpush rpush k-name value [value …]–将一个或者多个值推入列表的左端 执行 rpush命令后,当前列表的长度
lpop lpop k-name --移除并且返回列表最右端的元素 被移除的元素,当列表 key 不存在时,返回 nil
rpop rpop k-name–移除并且返回列表最左端的元素 被移除的元素,当列表 key 不存在时,返回 nil
lpushx lpushx k-name value [value …]–将一个或者多个值推入已经存在了边列表的右端 执行 lpushx 命令后,当前列表的长度。当且仅当列表存在时,此命令有效。如果列表不存在,返回长度0
rpushx rpushx k-name value [value …]–将一个或者多个值推入已经存在了边列表的左端 执行 lpushx 命令后,当前列表的长度。当且仅当列表存在时,此命令有效。如果列表不存在,返回长度0
blpop blpop k-name [k-name …]timeout 在超时时间内等待元素弹出
brpop brpop k-name [k-name …]timeout 在超时时间内等待元素弹出
rpoplpush rpoplpush source-key dest-key –从s-key列表种弹出位于最右端的元素并推入dest-key中 被弹出的元素
rpoplpush rpoplpush source-key dest-key timeout–在timeout内从s-key列表种弹出位于最右端的元素并推入dest-key中 被弹出的元素。
lindex lindex k-name offset –从列表种取出索引位offset的元素 0为起始索引,-1为结束索引。如果指定索引值不在列表的区间范围内,返回 nil
lrange lrange k-name start end–返回索引[start, end]之内的元素 0为起始索引,-1为结束索引。如果指定索引值不在列表的区间范围内,什么也不返回
ltrim ltrim k-name start end–只保留索引[start, end]内的元素,其他的删除 0为起始索引,-1为结束索引
llen llen k-name –返回列表的长度 如果是空列表,返回0.如果不是列表返回错误
lset lset k-name index new-value –设置索引index处的值位new-value. 操作成功返回ok, 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
  • lpush
  • LPUSH list “first-dibu”
  • LPUSH list “second” “third” “four” 【结果:4】
  • LRANGE list 0 -1
  • Lpop
  • LPOP list 【结果:“four”】
  • RPOP list 【结果:“first-dibu”】
  • lindex
  • LRANGE list 0 -1
  • lindex 0
  • lrange
  • LRANGE list 0 -1
  • LRANGE list 0 2
  • llen
  • llen list
  • Rpoplpush
  • RPOPLPUSH mylist myotherlist
    lset
    lset list 5 five
    Redis系列(2):Redis的数据类型
  • Linsert
    作用:在列表的元素前或者后插入元素。 当列表不存在时或者指定元素不存在于列表中时,不执行任何操作。如果 key 不是列表类型,返回一个错误。
    返回值:如果命令执行成功,返回插入操作完成之后,列表的长度。 如果没有找到指定元素 ,返回 -1 。 如果 key 不存在或为空列表,返回 0

LINSERT list1 BEFORE “bar” “Yes”
LINSERT list1 AFTER “bar” “Yes”

  • lrem
    作用:根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素
    返回值:被移除元素的数量。 列表不存在时返回 0

lrem list1 1 “foo” 从表头[最顶端]开始,移除1个“foo”
lrem list1 -1 “foo” 从表尾[最底端]开始,移除1个“foo”
lrem list1 0 “foo” 移除所有的"foo"

总结:
1、lpop和rpop命令有对应的阻塞版本:BLPOP和BRPOP,它们之间的不同在于当列表为空时,阻塞版本会将客户端阻塞,我们必须在这些阻塞版本的命令中指定一个以秒为单位的超时时间,表示最长等待几秒。当超时时间为零时,表示永久等待,可以用于任务调度

2、redis在内部使用quicklist存储列表对象。有两个配置选项可以调整列表对象的存储逻辑:

  • list-max-ziplist-size:一个列表条目中一个内部节点的最大大小[quicklist的每个节点都是一个ziplist]。使用默认值即可
  • list-compress-depth:该参数表示quicklist两端不被压缩的节点的个数

3、在redis里面,多个命令原子的执行指的是,在这些命令正在读取或者修改数据的时候,其他客户端不能读取或者修改相同的数据

4、对于阻塞弹出命令和弹出并推入命令,最常见用于消息传递和任务队列

使用HASH类型

Redis的散列可以存储多个键值对之间的映射

命令 描述 返回值和备注
HSET Hset key-name key value–为散列里面的一个字段赋值 如果字段或者散列不存在则创建并且返回1,如果字段已经存在则覆盖并且返回0
HMSET Hset key-name key value [key value …]–为散列里面的一个或者多个键赋值 如果不存在则创建,存在则覆盖。操作成功返回OK。推荐使用
Hsetnx Hset key-name key value–用于为哈希表中不存在的的字段赋值 如果字段已经存在,操作无效返回0,否则创建字段并设置值并且返回0
HDEL HDEL key-name key [key …]–删除散列 中的一个或多个指定字段,不存在的字段将被忽略 返回成功删除的键值对的数量
HLEN HLEN key-name --查看hash中有几个字段 返回散列包含的键值对数量, 当 key 不存在时,返回 0
HEXISTS HEXISTS key-name key–查看散列的指定字段是否存在 如果存在返回1,不存在返回0
HKEYS HKEYS key-name–获取散列中包含的所有字段 包含散列中所有字段的列表
HVALS HVALS key-name–获取散列中包含的所有值 包含散列中所有值的列表
HGET HGET key-name key --获取散列中指定字段的值 返回给定字段的值。如果给定的字段或 key 不存在时,返回 nil
HMGET HMGET key-name key value [key value …]–获取散列中一个或多个指定字段的值 推荐
HGETALL HGETALL key-name --获取散列中所有的字段和值 以列表形式返回哈希表的字段及字段值,若 key 不存在,返回空列表。返回值的长度是哈希表大小的两倍。
HINCRBY hincrby key-name key increment–将键key存储的值加上整数increment
HINCRBYFLOAT HINCRBYFLOAT key-name key increment–将键key存储的值加上浮点数increment

1、设置hash值

  • HSET:

HSET myhash field1 “foo”
HGET myhash field1
HSET website google “www.g.cn” # 设置一个新域
HSET website google “www.google.com” # 覆盖一个旧域

  • hmset:

HSET myhash field1 “foo” field2 “bar”

  • Hsetnx

HSETNX nosql key-value-store redis
HSETNX nosql key-value-store redis # 操作无效, key-value-store 已存在

2、查看

  • Hget

HSET site redis redis.com
HGET site redis 【结果:“redis.com”】

  • HGETALL
> HSET myhash field1 "foo"
> HSET myhash field2 "bar"
> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
  • Hmget
> HMGET myhash field1 field2 nofield
 1) "foo"
 2) "bar"
 3) (nil)
  • Hkeys
> HSET myhash field1 "foo"
> HSET myhash field2 "bar"
> HKEYS myhash
1) "field1"
2) "field2"
  • Hvals

HVALS myhash

  • hexists:

HEXISTS myhash field1
HEXISTS myhash field5

  • Hlen
  • HLEN myhash
  • HDEL
  • HDEL myhash field2

总结
1、不需要再添加字段前先初始化一个空哈希,redis会自动实现初始化,redis会自动回收空哈希

2、HSET和HMSET会覆盖现有字段,HSETNX仅在字段不存在的情况下才设置字段的值,可以防止默认覆盖

3、对于不存在的键或者字段,HMGET和HGET会返回nil

4、一个hash最大能够容纳2^32-1个字段,如果一个哈希的字段非常多,执行HGETALL时可能会阻塞服务器,这时,可以使用HSCAN命令来增量获取所有字段和值
HSCAN是redis的scan命令的一种[SCAN,HSCAN,SSCAN,ZSCAN],该命令会增量的迭代遍历元素,从而不会造成服务器阻塞。HSCAN命令是一种基于指针的迭代器,因此我们需要在每次调用命令时指定一个游标[从0开始],当一次HSCAN允许结束之后,Redis将返回一个元素列表以及一个新的游标,这个游标可以用于下一个迭代。

  • HSCAN key cursor [MATCH pattern] [count number]
    • cursor从0开始,count每次迭代返回多少个元素,默认为10
    • 当服务器返回的新游标为0时,整个遍历完成

5、Redis在内部使用两种编码来存储哈希对象

  • ziplist:对于那些长度度小于配置中hash-max-ziplist-entries选项配置的值[默认512字节],且所有元素的大小都小于配置中hash-max-ziplist-value选项配置的值[默认64字节],采用此编码。ziplist编码对于较小的哈希而言可以节省占用空间
  • hashtable:当ziplist不使用时采用

使用set集合类型

集合和散列都可以存储多个字符串,它们之间的不同在于,列表可以存储多个相同的字符串,而集合则通过使用散列表来保证自己存储的每个字符串都是各不相同的。
集合是无序的方式存储各不相同的元素

命令 描述 返回值和备注
sadd sadd k-name item[item…]–将一个或多个集合中不存在的元素加入到集合中 成功添加的元素,不包括被忽略的元素
srem srem k-name item[item…]–从集合中移除元素,不存在的成员元素会被忽略 返回被移除的元素数量
Sismember SISMEMBER k-name item --判断元素是否存在于集合中 如果成员元素是集合的成员,返回 1 。 如果成员元素不是集合的成员,或 key 不存在,返回 0
Scard SCARD k-name–求集合中包含元素的数量 当集合 key 不存在时,返回 0
Smembers Smembers k-name --返回集合中所有成员 如果集合太大可能会阻塞服务器,不推荐使用,推荐使用sscan
Srandmember Srandmember k-name [count]–从集合中随机返回一个或者多个元素
spop spop k-name --随机移除集合中的一个元素 返回被移除的元素,当集合不存在或是空集时,返回 nil
smove smove source-key dest-key item–将指定成员 member 元素从 source 集合移动到 destination 集合 如果操作成功返回1,失败返回0
  • sadd
  • SADD myset “hello” “redis”
  • Sismember
  • SISMEMBER myset “hello”
  • Scard
  • SCARD myset
  • Smembers
  • Smembers myset
  • Smembers myset11(empty list or set)
  • spop

spop myset

  • srem
  • SREM myset1 “foo”
  • Srandmember
    作用:返回集合中的一个随机元素。
    如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
    如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。
    返回值:只提供集合 key 参数时,返回一个元素;如果集合为空,返回 nil 。 如果提供了 count 参数,那么返回一个数组;如果集合为空,返回空数组。
    语法:SRANDMEMBER KEY [count]

SRANDMEMBER myset
SRANDMEMBER myset 2

  • Smove
    作用:将指定成员 member 元素从 source 集合移动到 destination 集合。
    如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。
    当 destination 集合已经包含 member 元素时, SMOVE 命令只是简单地将 source 集合中的 member 元素删除。
    返回值:如果成员元素被成功移除,返回 1 。 如果成员元素不是 source 集合的成员,并且没有任何操作对 destination 集合执行,那么返回 0 。当 source 或 destination 不是集合类型时,返回一个错误。

SMOVE myset1 myset2 “bar”

5、集合运算

  • SADD myset “hello” “foo” “bar”
  • SADD myset1 “hello” “world”

求交集

  • sinter
    作用:求交集。 不存在的集合 key 被视为空集。
    返回值:返回同时存在与所有集合的元素
    语法:sinter key-name [key-name 。。。]
  • SADD myset “hello” “foo” “bar”
  • SADD myset1 “hello” “world”
  • SINTER myset myset1
  • SINTERSTORE
    作用:将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在,则将其覆盖
    返回值:返回同时存在与所有集合的元素
    语法:sinter dest-key key-name [key-name 。。。]
  • SINTERSTORE destset myset myset1
  • SMEMBERS destset

求并集

  • Sunion
    作用:返回给定集合的并集。不存在的集合 key 被视为空集。
    返回值:只至少存在一个集合中的元素
    语法:sunion key-name [key-name …]
  • SUNION myset myset1
  • SUNIONSTORE
    作用:将给定集合的并集存储在指定的集合 destination 中
    返回值:只至少存在一个集合中的元素
    语法:sunion dest-key key-name [key-name …]
  • SUNIONSTORE myset myset1 myset1
  • SMEMBERS myset

求差集

  • sdiff
    作用:求差集。不存在的集合 key 将视为空集。
    返回值:返回存在第一个集合,但是不存在其他集合中的元素
    语法:sdiff key-name [key-name …]
  • SADD myset “hello” “foo” “bar”
  • SADD myset1 “hello” “world”
  • SDIFF myset myset1 【结果:1) “bar” 2) “foo”】
  • Sdiffstore
    作用:将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。
    返回值:返回存在第一个集合,但是不存在其他集合中的元素
    语法:sdiffstore dest-key key-name [key-name …]
  • SDIFFSTORE destset myset myset1
  • SMEMBERS destset

带store和不带store的区别:不带store后缀的命令只返回相应操作的结果集合,而带store后缀的命令将会将结果存储到一个自定的键中

  • Sscan
>SADD myset4 "hello" "hi" "bar"
>sscan myset4 0 match h*
1) "0"
2) 1) "hi"
   2) "hello"

总结:
2、在redis中,一个集合最大可以容纳2^23-1个成员
3、Redis在内部由两种编码方式来存储集合对象

  • intset:对于那些元素都是整数,且元素个数小于配置中set-max-intset-entries选择设置的值(默认512)的集合,采用此编码。intset编码对于较小的集合而言可以节省占用空间
  • hashtable:intset不适用时采用

使用有序集合sorted-set类型

有序集合和散列一样,都用于存储键值对:有序集合的键被称为成员,每个成员都是各不相同的,而有序集合的值称为分值,分值必须为浮点数。有序集合是redis里面唯一一个既可以根据成员访问元素,又可以根据分值以及分值的排列顺序来访问元素的结构

  • ZADD:
    作用:用于将一个或多个成员元素及其分数值加入到有序集当中。
    分数值可以是整数值或双精度浮点数。
    返回值:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
    语法: ZADD KEY_NAME SCORE1 VALUE1… SCOREN VALUEN
>ZADD myzset 2 "world" 3 "bar" 1 "foo" 1 "bar"
>zrange myzset 0 -1
1) "bar"
2) "foo"
3) "world"
> zrange myzset 0 -1 withscores
1) "bar"     //如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。
2) "1"
3) "foo"
4) "1"
5) "world"
6) "2"

在zadd中使用nx和xx

ZADD rangking:restaurants NX 50 “Olive” 【增添新成员,不可以修改旧成员,如果是旧成员,什么也不发生】
ZADD rangking:restaurants XX 0 “Olive Graden”【修改旧成员】

  • Zincrby
    作用:对有序集合中指定成员的分数加上增量 increment
    返回值:member 成员的新分数值,以字符串形式表示。

Zincrby myzset 5 “foo”

  • Zrem
    作用:用于移除有序集中的一个或多个成员,不存在的成员将被忽略。
    返回值:被成功移除的成员的数量,不包括被忽略的成员。

ZRANGE myzset 0 -1 WITHSCORES
ZREM myzset bar 【移除单个元素】
ZREM myzset world foo 【移除多个元素】
ZREM myzset da 【移除不存在元素返回0】

  • zscore
    作用:返回有序集中,成员的分数值
    返回值:成员的分数值,以字符串形式表示
  • zadd sarary 2500 jack 5000 tom 12000 peter
  • zscore sarary peter 【结果12000】
  • Zcard
    作用:用于计算集合中元素的数量。

zcard sarary

  • zcount
    返回值:分数值在 min 和 max 之间的成员的数量
    语法:ZCOUNT key min max

zcount sarary 2500 5000 【结果为2】

  • Zrange
    作用:返回有序集中,指定区间内的成员。其中成员的位置按分数值递增(从小到大)来排序。具有相同分数值的成员按字典序(lexicographical order )来排列。
    返回值:指定区间内,带有分数值(可选)的有序集成员的列表。
    备注:zrevrange和zrange相反,成员按值递减(从大到小)来排列
    语法: ZRANGE key start stop [WITHSCORES]

>ZRANGE sarary 0 -1 WITHSCORES        # 显示所有成员及其 score 值
>zrange sarary 0 1 withscores
>zrevrange sarary 0 -1 withscores
  • zrangebyscore
    作用:返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。具有相同分数值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。
    备注: Zrevrangebyscore 相反
> zrangebyscore sarary  -inf +inf    # 显示整个有序集
1) "jack"
2) "tom"
3) "peter"
>  ZRANGEBYSCORE salary -inf +inf WITHSCORES    # 显示整个有序集及成员的 score 值
1) "jack"
2) "2500"
3) "tom"
4) "5000"
5) "peter"
6) "12000"
>  ZRANGEBYSCORE sarary -inf 5000 WITHSCORES   # 显示工资 <=5000 的所有成员
1) "jack"
2) "2500"
3) "tom"
4) "5000"
> ZRANGEBYSCORE sarary (5000 400000            # 显示工资大于 5000 小于等于 400000 的成员
1) "peter"
  • zrank
    作用:返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。
    返回值:如果成员是有序集 key 的成员,返回 member 的排名。 如果成员不是有序集 key 的成员,返回 nil 。
    备注: Zrevrank 相反,有序集成员按分数值递减(从大到小)排序。排名以 0 为底

zrank sarary tom【结果:1】 # 显示 tom 的薪水排名,第二

  • Zremrangebyrank
    作用:用于移除有序集中,指定排名(rank)区间内的所有成员。
    返回值:被移除成员的数量。
  • ZRANGE sarary 0 -1 WITHSCORES
  • ZREMRANGEBYRANK sarary 0 1 # 移除下标 0 至 1 区间内的成员
  • Zremrangebyscore
    作用:用于移除有序集中,指定分数(score)区间内的所有成员
    返回值
    被移除成员的数量。

ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工

  • Zinterstore
    作用:计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
    返回值:保存到目标结果集的的成员数量。默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
>* zadd mid_test 70 "lilei" 70 "hanweiwei" 10 "Tom"
>* zadd fin_test 30 "lilei" 70 "hanweiwei" 10 "Tom" 20 "yueyue"
>* zinterstore sum_point 2 mid_test  fin_test  
>* zrange sum_point 0 -1 withscores
1) "Tom"
2) "20"
3) "lilei"
4) "100"
5) "hanweiwei"
6) "140"

5、ZUNIONSTORE合并两个排名:将两个有序集合的并集保存到指定的键中,而且可以指定各个有序集合的不同权重

ZADD rangking2:restaurants 50 “Olive Graden” 33 “PF Chang’s” 55 “Outback Steakhouse” 190 “kuang”
ZUNIONSTORE totalranking 2 rangking:restaurants rangking2:restaurants WEIGHTS 1 2
ZREVRANGE totalranking 0 -1 WITHSCORES

Redis系列(2):Redis的数据类型
Redis系列(2):Redis的数据类型
Redis系列(2):Redis的数据类型

使用HyperLogLog类型

应用场景:如果不需要获取数据集的内容,只是想得到不同值得个数。“唯一计数”

1、场景:计算访问得不同客户数

PFADD “Counting:Olive Garden” “000123”
PFADD “Counting:Olive Garden” “002399”

使用PFCOUNT命令获取餐厅得不同到访者数量

PFCOUNT “Counting:Olive Garden”

2、获取Olive Garden每周来得不同客人数:每天生成一个HLL,然后用pfmerge命令把7天得数据合并为一个

PFADD “Counting:Olive Garden:20170903” “000123” “0023291”
PFADD “Counting:Olive Garden:20170904” “000123” “0023291”
PFADD “Counting:Olive Garden:20170905” “000123” “0023211”
PFADD “Counting:Olive Garden:20170906” “000123” “0023291”
PFADD “Counting:Olive Garden:20170907” “000123” “0023291”
PFADD “Counting:Olive Garden:20170908” “004523” “0023291”
PFADD “Counting:Olive Garden:20170909” “002323” “0023291”

PFMERGE “Counting:Olive Garden:20170903week” “Counting:Olive Garden:20170903” “Counting:Olive Garden:20170904” “Counting:Olive Garden:20170905” “Counting:Olive Garden:20170906” “Counting:Olive Garden:20170907” “Counting:Olive Garden:20170908” “Counting:Olive Garden:20170909”

PFCOUNT “Counting:Olive Garden:20170903week” 【5个】

3、

PFADD key a b c a a a a
PFCOUNT key 【3个】

1、HLL类型相关得所有命令都是以PF开头的,用来想HLL数据结构的发明者致敬。Redis中HLL的优势在于能够使用固定数量的内存[每个HyperLogLog类型的键只需要占用12KB内存,却可以计算最多2^64个不同元素的基数]和常数时间复杂度(每个键O(1))进行唯一基数。不够由于HLL算法返回的基数可能不准确(标准差小于1%),因此在决定是否使用HLL时需要权衡

2、HLL实际上是当作字符串存储的,因此,作为一个键值对,他可以很容易的被持久化至外部或者从外部持久化中恢复。
在redis内部中,使用了两种方式来存储HLL对象

  • 稀疏Sparse:对于那些长度小于配置中hll-sparse-max-bytes选项设置的值(默认为3000)的HLL对象,采用此编码,存储效率更高,但是会消耗更多CPU
  • 稠密Dense:当Sparse不适用时采用

3、PFADD返回值:如果至少有个元素被添加返回 1, 否则返回 0。

使用Geo类型

场景:Geo用于存储和查询地理位置相关场景中的坐标,可以用于基于地理位置的服务

1、GROADD:添加Geo数据类型
作用:将指定得地址空间位置[经纬度、名称]添加到指定key中,然后用sortet set存储起来,编译 GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作
注意:

  • 经度必须在纬度之前
  • 有效的经度从-180°到180°,有效的纬度从-85.05112878度到85.05112878度。

GEOADD Sicily 13.361389 38.115556 “Palermo” 15.087269 37.502669 “Catania”

2、GEOPOS:
作用:从Geo集合中获取指定成员的坐标
返回值:GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 经度,纬度。
当给定的位置元素不存在时, 对应的数组项为空值。

  • GEOPOS Sicily Palermo Catania NonExisting
    Redis系列(2):Redis的数据类型

3、GEODIST:
作用:返回两个给定位置之间的距离
返回值: 计算出的距离会以双精度浮点数的形式被返回。 如果两个位置之间的其中一个不存在, 那么命令返回空值。返回单位:

  • m 表示单位为米。【如果不指定则默认】
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
  • GEOADD Sicily 13.361389 38.115556 “Palermo” 15.087269 37.502669 “Catania”
  • GEODIST Sicily Palermo Catania 【结果:“166274.1516”】
  • GEODIST Sicily Palermo Catania km 【结果:“166.2742”】
  • GEODIST Sicily Palermo Catania mi 【结果:“103.3182”】
  • GEODIST Sicily Foo Bar 【nil】

4、georadius:
应用场景:距经纬度-121.923470/37.985802位置5KM以内的餐厅
作用:以给定的经纬度为中心, 找出某一半径内的元素
在给定以下可选项时, 命令会返回额外的信息
返回值:返回线性(linear)列表或者二层嵌套数组

  • GEORADIUS restaurants:CA -121.923470 37.985802 5 km
  • GEORADIUS Sicily 15 37 200 km WITHDIST 【返回位置元素的同时,将位置元素与中心之间的距离也一并返回。距离的单位与用户给定的范围单位保持一致】
    Redis系列(2):Redis的数据类型
  • GEORADIUS Sicily 15 37 200 km WITHCOORD 【将位置元素的经纬度一并返回】
    Redis系列(2):Redis的数据类型
  • GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD
    【以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值,这个选项主要用于底层应用或者调试,实际中的作用不大,命令默认返回未排序的元素】
    Redis系列(2):Redis的数据类型
  • GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD ASC 【ASC从中心到远方返回元素,通过desc从远到近返回位置元素】
    Redis系列(2):Redis的数据类型

5、georadiusbymember命令
作用:找出位于指定范围内的元素,
不同:GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点

  • GEOADD Sicily 13.583333 37.316667 “Agrigento”
  • GEORADIUSBYMEMBER Sicily Agrigento 100 km

6、GEOHASH 命令
作用:返回一个或多个位置元素的 Geohash 表示
返回值:一个数组, 数组的每个项都是一个 geohash 。 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。
注意:geohash的实现是基于一种52位整数的表示(实现了低于1m的精度)。当需要一个标准geohash字符串时,我们可以使用geohash命令来获取一个长度位11的字符串。

  • GEOHASH Sicily Palermo Catania
  1. “sqc8b49rny0”
  2. “sqdtr74hyu0”

总结
1、sorted set使用一种称为Geohash的技术进行填充。经度和纬度的位是交错的,以形成一个独特的52位整数. 我们知道,一个sorted set 的double score可以代表一个52位的整数,而不会失去精度。
这种格式允许半径查询检查的1 + 8个领域需要覆盖整个半径,并丢弃元素以外的半径。通过计算该区域的范围,通过计算所涵盖的范围,从不太重要的部分的排序集的得分,并计算得分范围为每个区域的sorted set中的查询。但是因为它假设地球是一个完美的球体,但是实际地球是个椭圆形,因此可能会有偏差,偏差最大可以达到0.5%

2、geo集合实际上被存储位一个有序集合,因此有序集合中所有命令都可以用于geo数据类型

3、性能:GEORADIUS的时间复杂度为o(N+log(M)),其中N为由中心点和半径所决定的原型区域的外接矩形中成员的个数。所以我们在一次查询中将半径参数设置得尽可能少,覆盖更少得点,可以获得更高得性能

参考:http://www.redis.net.cn/order/3546.html

相关文章:

  • 2021-10-13
  • 2021-10-10
  • 2022-12-23
  • 2022-12-23
  • 2021-05-18
  • 2022-01-03
  • 2021-10-10
  • 2021-09-23
猜你喜欢
  • 2022-01-08
  • 2022-12-23
  • 2021-05-28
  • 2021-12-17
  • 2021-12-17
  • 2021-10-04
相关资源
相似解决方案