五大数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件MQ。它支持多种类型的数据结构,如**字符串( strings ),散列 ( hashes ),列表( lists ),集合( sets ),有序集合( sorted sets )**与范围查询,**bitmaps , hyperloglogs和地理空间( geospatial)**索引半径查询。Redis内置了复制( replication ),LUA脚本( Luascripting ),LRU驱动事件(LRU eviction),事务( transactions)和不同级别的磁盘持久化 ( persistence ),并通过Redis哨兵( Sentinel)和自动分区( Cluster)提供高可用性 ( high availability )。

Redis-key

在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作。

  • exists key:判断键是否存在
  • del key:删除键值对
  • move key db:将键值对移动到指定数据库
  • expire key second:设置键值对的过期时间
  • type key:查看value的数据类型
  • ttl key:查看key的过期剩余时间
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name lihonghui
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS names
(integer) 0
127.0.0.1:6379> move name 1  #将键值对移动到指定数据库
(integer) 1
127.0.0.1:6379> keys 
(error) ERR wrong number of arguments for 'keys' command
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> set name li
OK
127.0.0.1:6379> get li
(nil)
127.0.0.1:6379> get name
"li"
127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> ttl name #查看key的过期剩余时间
(integer) -2
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> type age
string
127.0.0.1:6379> type name
string

关于ttl命令

Redis的key,通过ttl命令返回key的过期时间,一般来说有3种:

  1. 当前key没有设置过期时间,所以会返回-1.
  2. 当前key有设置过期时间,而且key已经过期,所以会返回-2.
  3. 当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.

关于重命名RENAMERENAMENX

  1. RENAME key newkey修改 key 的名称
  2. RENAMENX key newkey仅当 newkey 不存在时,将 key 改名为 newkey 。
1、String(字符串)

普通的set、get直接略过。

常用命令及其示例:

APPEND key value: 向指定的key的value后追加字符串 ,如果key不存在,就相当于set key value

STRLEN key:查看字符串长度

127.0.0.1:6379> get name
"li"
127.0.0.1:6379> append name honghui
(integer) 9
127.0.0.1:6379> get name
"lihonghui"
127.0.0.1:6379> STRLEN name
(integer) 9
127.0.0.1:6379> APPEND name ,xiaoliuzi
(integer) 19
127.0.0.1:6379> get name
"lihonghui,xiaoliuzi"

DECR/INCR key: 将指定key的value数值进行+1/-1(仅对于数字)

127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> INCR views
(integer) 1
127.0.0.1:6379> INCR views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> DECR views
(integer) 1
127.0.0.1:6379> DECR views
(integer) 0

INCRBY/DECRBY key n: 按指定的步长对数值进行加减

127.0.0.1:6379> get views
"0"
127.0.0.1:6379> INCRBY views 10
(integer) 10
127.0.0.1:6379> decrby views 10
(integer) 0

GETRANGE key start end: 按起止位置获取字符串(闭区间,起止位置都取)

127.0.0.1:6379> get name
"lihonghui,xiaoliuzi"
127.0.0.1:6379> GETRANGE name 0 7
"lihonghu"
127.0.0.1:6379> GETRANGE name 0 -1 #查看全部字符串
"lihonghui,xiaoliuzi"

SETRANGE key offset value:用指定的value 替换key中 offset开始的值

127.0.0.1:6379> get name
"lihonghui,xiaoliuzi"
127.0.0.1:6379> SETRANGE name 2 xiaoliu
(integer) 19
127.0.0.1:6379> get name
"lixiaoliu,xiaoliuzi"

SETNX(set if not exist) key value: 仅当key不存在时进行set (在分布式锁中常常使用!)

SETEX(set with expire) key seconds value: set 键值对并设置过期时间

127.0.0.1:6379> setex key1 30 hello
OK
127.0.0.1:6379> ttl key1
(integer) 24
127.0.0.1:6379> setnx key2 redis 
(integer) 1
127.0.0.1:6379> keys *
1) "key2"
2) "name"
3) "age"
4) "views"
127.0.0.1:6379> ttl key1
(integer) -2
127.0.0.1:6379> setnx key2 nihao
(integer) 0
127.0.0.1:6379> get key2
"redis"

MSET key1 value1 [key2 value2..]: 批量set键值对

MGET key1 [key2..]: 批量获取多个key保存的值

MSETNX key1 value1 [key2 value2..]: 批量设置键值对,仅当参数中所有的key都不存在时执行 (原子性操作,一起成功,一起失败)

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

127.0.0.1:6379> msetnx k1 v1 k4 v4
(integer) 0
#对象
set user:1 iname:zhangsan ,age:3]} #设置一个user:1对象值为 json字符来保存一个对象!
#这里的key是一个巧妙的设计: user:{id}:{filed} ,如此设计在Redis中是完全OK了!
127.0.0.1:6379> mset user: 1:name zhangsan user: 1:age 2
oK
127.0.0.1:6379> mget user : 1:name user: 1:age
1) "zhangsan "
2) "2"

GETSET key value: 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db xiaoqiang
"redis"
127.0.0.1:6379> get db
"xiaoqiang"

String类似的使用场景:value除了是字符串还可以是数字,用途举例:

  • 计数器
  • 统计多单位的数量:uid:123666:follow 0
  • 粉丝数
  • 对象存储缓存
2、List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

首先我们列表,可以经过规则定义将其变为队列、栈、双端队列等。

redis的几种数据类型 redis数据类型有几种_缓存

正如图Redis中List是可以进行双端操作的,所以命令也就分为了LXXX和RLLL两类,有时候L也表示List例如LLEN

  • LPUSH/RPUSH key value1[value2..]从左边/右边向列表中PUSH值(一个或者多个)。
  • LRANGE key start end 获取list 起止元素==(索引从左往右 递增)==
  • LPUSHX/RPUSHX key value 向已存在的列名中push值(一个或者多个)
  • LINSERT key BEFORE|AFTER pivot value 在指定列表元素的前/后 插入value
  • LLEN key 查看列表长度
  • LINDEX key index 通过索引获取列表元素
  • LSET key index value 通过索引为元素设值
  • LPOP/RPOP key 从最左边/最右边移除值 并返回
  • RPOPLPUSH source destination 将列表的尾部(右)最后一个值弹出,并返回,然后加到另一个列表的头部
  • LTRIM key start end 通过下标截取指定范围内的列表
  • LREM key count value List中是允许value重复的 count > 0:从头部开始搜索 然后删除指定的value 至多删除count个 count < 0:从尾部开始搜索… count = 0:删除列表中所有的指定value。
  • BLPOP/BRPOP key1[key2] timout 移出并获取列表的第一个/最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • BRPOPLPUSH source destination timeout 和RPOPLPUSH功能相同,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
######################   LPUSH/RPUSH   ####################
127.0.0.1:6379> LPUSH list one
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list tree
(integer) 3
127.0.0.1:6379> get list
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> LRANGE list 0 -1
1) "tree"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1
1) "tree"
2) "two"
127.0.0.1:6379> RPUSH list right
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "tree"
2) "two"
3) "one"
4) "right"

#########################  LPOP/RPOP  ####################
127.0.0.1:6379> LRANGE list 0 -1
1) "tree"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> LPOP list 
"tree"
127.0.0.1:6379> RPOP list
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"


#########################  LINDEX  ####################
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> lindex list 0
"two"


#########################  LLen  ####################
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> LLEN list
(integer) 2

#########################  LREM  ####################
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> LREM list 1 one
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> LREM list 2 three
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "two"

#########################  LTRIM  ####################
127.0.0.1:6379> rpush mylist hello1
(integer) 1
127.0.0.1:6379> rpush mylist hello2
(integer) 2
127.0.0.1:6379> rpush mylist hello3
(integer) 3
127.0.0.1:6379> rpush mylist hello4
(integer) 4
127.0.0.1:6379> LTRIM mylist 1 2
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello2"
2) "hello3"

#########################  RPOPLPUSH  ####################
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
127.0.0.1:6379> RPOPLPUSH mylist myotherlist
"hello2"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "hello1"
127.0.0.1:6379> LRANGE myotherlist 0 -1
1) "hello2"

######################### LSET  ####################
127.0.0.1:6379> lset list 0 item
(error) ERR no such key
127.0.0.1:6379> lpush list v1
(integer) 1
127.0.0.1:6379> LRANGE list 0 0
1) "v1"
127.0.0.1:6379> lset list 0 v2
OK
127.0.0.1:6379> LRANGE list 0 0
1) "v2"
127.0.0.1:6379> lset list 1 v3
(error) ERR index out of range


#########################  LINSERT  ####################
127.0.0.1:6379> RPUSH mylist hello
(integer) 1
127.0.0.1:6379> RPUSH mylist world
(integer) 2
127.0.0.1:6379> LINSERT mylist before world nihao
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "nihao"
3) "world"
127.0.0.1:6379> LINSERT mylist after world new
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "nihao"
3) "world"
4) "new"

小结

  • list实际上是一个链表,before Node after , left, right 都可以插入值
  • 如果key不存在,则创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低

应用:

消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)

3、set(集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

  • SADD key member1[member2..] 向集合中无序增加一个/多个成员
  • SCARD key 获取集合的成员数
  • SMEMBERS key 返回集合中所有的成员
  • SISMEMBER key member 查询member元素是否是集合的成员,结果是无序的
  • SREM key member1[member2..] 移除集合中一个/多个成员
  • SRANDMEMBER key [count] 随机返回集合中count个成员,count缺省值为1
  • SPOP key [count] 随机移除并返回集合中count个成员,count缺省值为1
  • SMOVE source destination member 将source集合的成员member移动到destination集合
  • SDIFF key1[key2..] 返回所有集合的差集 key1- key2 - …
  • SDIFFSTORE destination key1[key2..] 在SDIFF的基础上,将结果保存到集合中==(覆盖)==。不能保存到其他类型key噢!
  • SINTER key1 [key2..] 返回所有集合的交集
  • SINTERSTORE destination key1[key2..] 在SINTER的基础上,存储结果到集合中。覆盖
  • SUNION key1 [key2..] 返回所有集合的并集
  • SUNIONSTORE destination key1 [key2..] 在SUNION的基础上,存储结果到及和张。覆盖
  • SSCAN KEY [MATCH pattern] [COUNT count] 在大量数据环境下,使用此命令遍历集合中元素,每次遍历部分
#########################  SADD   ####################
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "hello1"
(integer) 1
127.0.0.1:6379> sadd myset "hello2"
(integer) 1
127.0.0.1:6379> keys *
1) "myset"

#########################  SCARD   ####################
127.0.0.1:6379> SCARD myset
(integer) 3

#########################  SMEMBERS   ####################
127.0.0.1:6379> SMEMBERS myset
1) "hello2"
2) "hello1"
3) "hello"

#########################  SISMEMBER   ####################
127.0.0.1:6379> SISMEMBER myset "hello"
(integer) 1
127.0.0.1:6379> SISMEMBER myset "hello3"
(integer) 0

#########################  SREM   ####################
127.0.0.1:6379> SREM myset hello
(integer) 1
127.0.0.1:6379> SCARD myset
(integer) 2
127.0.0.1:6379> SMEMBERS myset
1) "hello2"
2) "hello1"

#########################  SRANDMEMBER   ###################
127.0.0.1:6379> SMEMBERS myset
1) "hello2"
2) "hello1"
3) "hello4"
4) "hello3"
127.0.0.1:6379> SRANDMEMBER myset
"hello2"
127.0.0.1:6379> SRANDMEMBER myset
"hello3"
127.0.0.1:6379> SRANDMEMBER myset 2
1) "hello1"
2) "hello2"
127.0.0.1:6379> SRANDMEMBER myset 2
1) "hello3"
2) "hello4"

#########################  SPOP   ###################
127.0.0.1:6379> spop myset
"hello1"
127.0.0.1:6379> spop myset
"hello2"
127.0.0.1:6379> spop myset
"hello3"
127.0.0.1:6379> spop myset
"hello4"

#########################  SMOVE   ###################
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SMEMBERS other
1) "4"
127.0.0.1:6379> smove myset other "3"
(integer) 1
127.0.0.1:6379> SMEMBERS other
1) "3"
2) "4"
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"

###################  SDIFF|SINTER|SUNION ###################
微博,B站,共同关注!(并集)
数字集合类:
-差集 SDIFF
-交集 SINTER
-并集 SUNION
127.0.0.1:6379> SMEMBERS key1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> SMEMBERS key2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379> SDIFF key1 key2
1) "a"
2) "b"
127.0.0.1:6379> SINTER key1 key2
1) "c"
127.0.0.1:6379> SUNION key1 key2
1) "c"
2) "a"
3) "b"
4) "e"
5) "d"

微博,A用户将所有关注的人放在一个set集合中!将它的粉丝也放在一个集合中!

共同关注,共同爱好,二度好友,推荐好友!(六度分割理论)

4、Hash(哈希)

Map集合,Key-map!这个值value是一个map值。

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

Set就是一种简化的Hash,只变动key,而value使用默认值填充。可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。

  • HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。重复设置同一个field会覆盖,返回0
  • HMSET key field1 value1 [field2 value2..] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
  • HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
  • HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
  • HGET key field value 获取存储在哈希表中指定字段的值
  • HMGET key field1 [field2..] 获取所有给定字段的值
  • HGETALL key 获取在哈希表key 的所有字段和值
  • HKEYS key 获取哈希表key中所有的字段
  • HLEN key 获取哈希表中字段的数量
  • HVALS key 获取哈希表中所有值
  • HDEL key field1 [field2..] 删除哈希表key中一个/多个field字段
  • HINCRBY key field n 为哈希表 key 中的指定字段的整数值加上增量n,并返回增量后结果 一样只适用于整数型字段
  • HINCRBYFLOAT key field n 为哈希表 key 中的指定字段的浮点数值加上增量 n。
  • HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。
#################   hset|hget|hmset|hmget  #################
127.0.0.1:6379> hset myhash field1 lihonghui # set一个具体 key-vlaue
(integer) 1
127.0.0.1:6379> hget myhash fie1d1#获取一个字段值
"lihonghui"
127.0.0.1:6379> hmset myhash field1 hello field2 world
# set多个 key-vlaue
oK
127.0.0.1:6379> hmget myhash fie1d1 fie1d2#获取多个字段值
1) "he11o"
2) "wor1d"
127.0.0.1:6379> hgetall myhash
1) "fie1d1"
2) "he11o"
3) "fie1d2"
4) "wor1d"
#################   HDEL  #################
127.0.0.1:6379>  hdel myhash field1
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"
#################   HLEN  #################
127.0.0.1:6379> hlen myhash
(integer) 1
#################   HEXISTS  #################
127.0.0.1:6379> HEXISTS myhash field1
(integer) 0
127.0.0.1:6379> HEXISTS myhash field2
(integer) 1

#################   HKEYS|HVALS  #################
127.0.0.1:6379> HKEYS myhash
1) "field2"
127.0.0.1:6379> HVALS myhash
1) "world"


#################   HINCRBY|HSETNX  #################
127.0.0.1:6379> hset myhash field3 5#指定增量!
(integer) 1
127.0.0.1:6379>HINCRBY myhash fie1d3 1
(integer) 6
127.0.0.1:6379>HINCRBY myhash field3 -1
(integer) 5
127.0.0.1:6379> hsetnx myhash field4 he1lo# 如果不存在则可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field4 wor1d#如果存在则不能设置
(integer) 0

hash变更的数据user name age,尤其是是用户信息之类的,经常变动的信息! hash更适合于对象的存储,String更加适合字符串存储!

5、Zset(有序集合)

不同的是每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大的排序。

score相同:按字典顺序排序

有序集合的成员是唯一的,但分数(score)却可以重复。

  • ZADD key score member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
  • ZCARD key 获取有序集合的成员数
  • ZCOUNT key min max 计算在有序集合中指定区间score的成员数
  • ZINCRBY key n member 有序集合中对指定成员的分数加上增量 n
  • ZSCORE key member 返回有序集中,成员的分数值
  • ZRANK key member 返回有序集合中指定成员的索引
  • ZRANGE key start end 通过索引区间返回有序集合成指定区间内的成员
  • ZRANGEBYLEX key min max 通过字典区间返回有序集合的成员
  • ZRANGEBYSCORE key min max 通过分数返回有序集合指定区间内的成员-inf 和 +inf分别表示最小最大值,只支持开区间()
  • ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
  • ZREM key member1 [member2..] 移除有序集合中一个/多个成员
  • ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员
  • ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员
  • ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员
  • ZREVRANGE key start end 返回有序集中指定区间内的成员,通过索引,分数从高到底
  • ZREVRANGEBYSCORRE key max min 返回有序集中指定分数区间内的成员,分数从高到低排序
  • ZREVRANGEBYLEX key max min 返回有序集中指定字典区间内的成员,按字典顺序倒序
  • ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
  • ZINTERSTORE destination numkeys key1 [key2 ..] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中,numkeys:表示参与运算的集合数,将score相加作为结果的score
  • ZUNIONSTORE destination numkeys key1 [key2..] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
  • ZSCAN key cursor [MATCH pattern\] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)
#################   ZADD  #################
127.0.0.1:6379> zadd myset 1 one 2 two 3 three
(integer) 3
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "three"

#############  ZRANGEBYSCORE|ZREVRANGEBYSCORE  #############
排序
127.0.0.1:6379> zadd salary 100 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 200 zhangsan1
(integer) 1
127.0.0.1:6379> zadd salary 300 zhangsan2
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf  #升序
1) "zhangsan"
2) "zhangsan1"
3) "zhangsan2"
127.0.0.1:6379> ZREVRANGEBYSCORE salary +inf -inf #降序
1) "zhangsan2"
2) "zhangsan1"
3) "zhangsan"

127.0.0.1:6379> ZRANGEBYSCORE salary 200 +inf withscores
#显示大于200的员工升序
1) "zhangsan1"
2) "200"
3) "zhangsan2"
4) "300"

127.0.0.1:6379> ZRANGEBYSCORE salary -inf 200 withscores
#显示小于200的员工升序
1) "zhangsan"
2) "100"
3) "zhangsan1"
4) "200"

#############  ZREM|ZCARD #############
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhangsan"
2) "zhangsan1"
3) "zhangsan2"
127.0.0.1:6379> ZREM salary zhangsan #移除
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhangsan1"
2) "zhangsan2"
127.0.0.1:6379> ZCARD salary #获取有序集合的成员数
(integer) 2

#############  zcount #############
127.0.0.1:6379> zadd myset 1 zhangsan 2 zhangsan1 3 zhangsan2
(integer) 3
127.0.0.1:6379> ZRANGE myset 0 -1 withscores
1) "zhangsan"
2) "1"
3) "zhangsan1"
4) "2"
5) "zhangsan2"
6) "3"
127.0.0.1:6379> zcount myset 1 3 #获取指定区间的成员数量!
(integer) 3
127.0.0.1:6379> zcount myset 1 2
(integer) 2

应用案例:

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

三种特殊数据类型

geospatial地理位置

朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.2版本就推出了!这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人 !

只有六个命令!

redis的几种数据类型 redis数据类型有几种_缓存_02

使用经纬度定位地理坐标并用一个有序集合zset保存,所以zset命令也可以使用

  • geoadd key longitud(经度) latitude(纬度) member [..] 将具体经纬度的坐标存入一个有序集合
  • geopos key member [member..] 获取集合中的一个/多个成员坐标
  • geodist key member1 member2 [unit] 返回两个给定位置之间的距离。默认以米作为单位。
  • georadius key longitude latitude radius m|km|mi|ft [WITHCOORD][WITHDIST] [WITHHASH] [COUNT count] 以给定的经纬度为中心, 返回集合包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
  • GEORADIUSBYMEMBER key member radius... 功能与GEORADIUS相同,只是中心位置不是具体的经纬度,而是使用结合中已有的成员作为中心点。
  • geohash key member1 [member2..] 返回一个或多个位置元素的Geohash表示。使用Geohash位置52点整数编码。

有效经纬度

  • 有效的经度从-180度到180度。
  • 有效的纬度从-85.05112878度到85.05112878度。

geoadd

127.0.0.1:6379> geoadd china:city 116.405285 9.904989 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 112.98227 28.19409 changsha
(integer) 1

geopos

127.0.0.1:6379> GEOPOS china:city beijing
1) 1) "116.40528291463851929"
   2) "9.90498944029606321"

geodist

指定单位的参数 unit 必须是以下单位的其中一个:

m 表示单位为米。

km 表示单位为千米。

mi 表示单位为英里。

ft 表示单位为英尺。

127.0.0.1:6379> GEODIST china:city beijing changsha
"2065453.4804"
127.0.0.1:6379> GEODIST china:city beijing changsha km
"2065.4535"

georadius

我附近的人?(获得所有附近的人的地址,定位!)通过半径来查询!

获得指定数量的人,200

所有数据应该都录入: china:city ,才会让结果更加精确!

127.0.0.1:6379>GEORADIUs china:city 110 30 1000 km
#以110,30这个经纬度为中心,寻找方圆1000km内的城市
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou "
127.0.0.1:6379> GEORADIus china:city 110 30 500 km
1) "chongqi"
2) "xian"
127.0.0.1:6379> GEORADTUs china:city 110 30 50o km withdist
# 显示到中间距离的位置
1) 1) "chongqi"
   2) "341.9374"
2) 1) "xian"
   2) "483.8340"
127.0.0.1:6379> GEORADIus china:city 110 30 500 km withcoord
#显示他人的定位信息
1) 1) "chongqi"
   2) 1) "106.49999767541885376"
	  2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
	  2)"34.25999964418929977""
127.0.0.1:6379>GEORADTus china:city 110 30 500 km withdist withcoord count 1 
#筛选出指定的结果
1) 1) "chongqi"
   2) "341.9374""
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"

GEORADIUSBYMEMBER

#找出位于指定元素周围的其他元素!
127.0.0.1:6379>GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"
127.0.0.1:6379>GEORADIUSBYMEMBER china:city shanghai 400 km
1) "hangzhou"
2) "shanghai"

GEOHASH命令-返回一个或多个位置元素的Geohash表示

该命令将返回11个字符的Geohash字符串!

#将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近
127.0.0.1:6379>geohash china:city beijing chongqin
1) "wx4fbxxfkeo"
2) "wm5xzrybtyo"

GEO底层的实现原理其实就是Zset !我们可以使用Zset命令来操作geo !

127.0.0.1:6379> ZREM china:city beijing
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "changsha"
Hyperloglog(基数统计)

edis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。

因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

其底层使用string数据类型。

什么是基数?

数据集中不重复的元素的个数。

应用场景:

网页的访问量(UV):一个用户多次访问,也只能算作一个人。

传统实现,存储用户的id,然后每次进行比较。当用户变多之后这种方式及其浪费空间,而我们的目的只是计数,Hyperloglog就能帮助我们利用最小的空间完成。

  • PFADD key element1 [elememt2..] 添加指定元素到 HyperLogLog中
  • PFCOUNT key [key] 返回给定 HyperLogLog 的基数估算值。
  • PFMERGE destkey sourcekey [sourcekey..] 将多个 HyperLogLog 合并为一个 HyperLogLog
----------PFADD--PFCOUNT---------------------
127.0.0.1:6379> PFADD myelemx a b c d e f g h i j k # 添加元素
(integer) 1
127.0.0.1:6379> type myelemx # hyperloglog底层使用String
string
127.0.0.1:6379> PFCOUNT myelemx # 估算myelemx的基数
(integer) 11
127.0.0.1:6379> PFADD myelemy i j k z m c b v p q s
(integer) 1
127.0.0.1:6379> PFCOUNT myelemy
(integer) 11

----------------PFMERGE-----------------------
127.0.0.1:6379> PFMERGE myelemz myelemx myelemy # 合并myelemx和myelemy 成为myelemz
OK
127.0.0.1:6379> PFCOUNT myelemz # 估算基数
(integer) 17
BitMaps(位图)

使用位存储,信息状态只有 0 和 1

Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作。。

应用场景: 签到统计、状态统计

  • setbit key offset value 为指定key的offset位设置值
  • getbit key offset 获取offset位的值
  • bitcount key [start end] 统计字符串被设置为1的bit数,也可以指定统计范围按字节
  • bitop operration destkey key[key..] 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
  • BITPOS key bit [start] [end] 返回字符串里面第一个被设置为1或者0的bit位。start和end只能按字节,不能按位
------------setbit--getbit--------------
127.0.0.1:6379> setbit sign 0 1 # 设置sign的第0位为 1 
(integer) 0
127.0.0.1:6379> setbit sign 2 1 # 设置sign的第2位为 1  不设置默认 是0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> type sign
string

127.0.0.1:6379> getbit sign 2 # 获取第2位的数值
(integer) 1
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 4 # 未设置默认是0
(integer) 0

-----------bitcount----------------------------
127.0.0.1:6379> BITCOUNT sign # 统计sign中为1的位数
(integer) 4