Redis的全称是REmote Dictionary Server,它主要提供了5种数据结构:字符串、哈希、列表、集合、有序集合,同时在字符串的基础之上演变 出了位图(Bitmaps)和HyperLogLog两种神奇的“数据结构”,并且随着 LBS(Location Based Service,基于位置服务)的不断发展,Redis3.2版本中 加入有关GEO(地理信息定位)的功能



哈希

几乎所有的编程语言都提供了哈希(hash)类型,它们的叫法可能是哈 希、字典、关联数组。在Redis中,哈希类型是指键值本身又是一个键值对 结构,形如value={{field1,value1},...{fieldN,valueN}}

注意

哈希类型中的映射关系叫作field-value,注意这里的value是指field对应 的值,不是键对应的值

命令

设置值,获取值

设置值

hset key field value

获取值

hget key field

实例

127.0.0.1:6379> hset user1 name nerrys

(integer) 1

127.0.0.1:6379> hget user1 name

"nerrys"

键或field不存在

如果键或field不存在,会返回nil:

127.0.0.1:6379> hget user2 name

(nil)

删除field

hdel key field [field ...]

实例

127.0.0.1:6379> hdel user1 name

(integer) 1

127.0.0.1:6379> hget user1 name

(nil)

计算field个数

hlen key

实例

127.0.0.1:6379> hget user1 name

"nerrys"

127.0.0.1:6379> hget user1 age

"22"

127.0.0.1:6379> hget user1 sex

"man"

127.0.0.1:6379> hget user1 city

"beijing"

127.0.0.1:6379> hlen user1

(integer) 4

批量设置或获取field-value

hmget key field [field ...]

hmset key field value [field value ...]


hmset和hmget分别是批量设置和获取field-value,

hmset需要的参数是key 和多对field-value,hmget需要的参数是key和多个field。

实例

127.0.0.1:6379> hmget user name user2 22 sex

  1. "nerrys"
  2. "age"
  3. "user3"
  4. "man"

    127.0.0.1:6379> hmset user1 name nerrys age 22 sex man city beijing

    OK

    127.0.0.1:6379> hmget user1 name age sex city
  5. "nerrys"
  6. "22"
  7. "man"
  8. "beijing"

判断field是否存在

hexists key field

实例

127.0.0.1:6379> hexists user1 name

(integer) 1

获取所有field

hkeys key

实例

127.0.0.1:6379> hkeys user1

  1. "name"
  2. "age"
  3. "sex"
  4. "city"

获取所有value

hvals key

实例

127.0.0.1:6379> hvals user1

  1. "nerrys"
  2. "22"
  3. "man"
  4. "beijing"

获取所有的field-value

hgetall key

实例

127.0.0.1:6379> hgetall user1

  1. "name"
  2. "nerrys"
  3. "age"
  4. "22"
  5. "sex"
  6. "man"
  7. "city"
  8. "beijing"

    注意:

    在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能

hincrby hincrbyfloat

hincrby key field

hincrbyfloat key field

hincrby和hincrbyfloat,就像incrby和incrbyfloat命令一样,但是它们的作用域是filed。

实例

127.0.0.1:6379> hincrby user1 age 1

(integer) 23

127.0.0.1:6379> hget user1 age

"23"

计算value的字符串长度

hstrlen key field

实例

127.0.0.1:6379> hstrlen user1 name

(integer) 6

127.0.0.1:6379> hget user1 name

"nerrys"

内部编码

哈希类型的内部编码有两种:

·ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的 结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

·hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使 用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而 hashtable的读写时间复杂度为O(1)。

测试

127.0.0.1:6379> object encoding user1

"ziplist"


当有value大于64字节,内部编码会由ziplist变为hashtable:


127.0.0.1:6379> hset hashkey f1 thishashkeyisbetterthan64byteisisisisisiisisisisisiisisisisisisisiisisisisiisisisisiisisisisisisisiisisisisisiisis

(integer) 1

127.0.0.1:6379> object encoding hashkey

"hashtable"


当field个数超过512,内部编码也会由ziplist变为hashtable:

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 f3 v3 ...忽略... f513 v513(太长了)

使用场景

1.对关系型数据库的数据存储

相比于使用字符串序列化缓存用户信息,哈希类型变得更加直观,并且在更新操作上会更加便捷。可以将每个用户的id定义为键后缀,多对field- value对应每个用户的属性

·哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型 每个键可以有不同的field,而关系型数据库一旦添加新的列,所有行都要为 其设置值(即使为NULL)

·关系型数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询 开发困难,维护成本高。

列表

列表(list)类型是用来存储多个有序的字符串,如a、 b、c、d、e五个元素从左到右组成了一个有序的列表,列表中的每个字符串 称为元素(element),一个列表最多可以存储2^32-1个元素。在Redis中,可 以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列 表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表类型有两个特点:第一、列表中的元素是有序的,这就意味着可以 通过索引下标获取某个元素或者某个范围内的元素列表,例如要获取图的第5个元素,可以执行lindex user:1:message4(索引从0算起)就可以得 到元素e。第二、列表中的元素可以是重复的,例如图所示列表中包含 了两个字符串a。

命令

添加操作

(1)从右边插入元素

rpush key value [value ...]

lrange0-1命令可以从左到右获取列表的所有元素

命令

127.0.0.1:6379> rpush listkey a b c

(integer) 3

127.0.0.1:6379> lrange listkey 0 -1

  1. "a"
  2. "b"
  3. "c"

    (2)从左边插入元素

    lpush key value [value ...]

127.0.0.1:6379> lpush listkey1 a b c

(integer) 3

127.0.0.1:6379> lrange listkey1 0 -1

  1. "c"
  2. "b"
  3. "a"

(3)向某个元素前或者后插入元素

linsert key before|after pivot value

linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后 (after)插入一个新的元素value

127.0.0.1:6379> linsert listkey before b e

(integer) 4

127.0.0.1:6379> lrange listkey 0 -1

  1. "a"
  2. "e"
  3. "b"
  4. "c"

查找

(1)获取指定范围内的元素列表

lrange key start end

lrange操作会获取列表指定索引范围所有的元素。索引下标有两个特点:

  • 第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N。
  • 第二,lrange中的end选项包含了自身

127.0.0.1:6379> lrange listkey 1 3

  1. "e"
  2. "b"
  3. "c"

(2)获取列表指定索引下标的元素

lindex key index

实例

127.0.0.1:6379> lindex listkey 0

"a"

(3)获取列表长度

llen key

实例

127.0.0.1:6379> llen listkey

(integer) 4

删除

(1)从列表左侧弹出元素

lpop key

实例

127.0.0.1:6379> lpop listkey

"a"

127.0.0.1:6379> lrange listkey 0 -1

  1. "e"
  2. "b"
  3. "c"

(2)从列表右侧弹出

rpop key

实例

127.0.0.1:6379> rpop listkey

"c"

127.0.0.1:6379> lrange listkey 0 -1

  1. "e"
  2. "b"

(3)删除指定元素

lrem key count value

lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:

  • count>0,从左到右,删除最多count个元素。
  • count<0,从右到左,删除最多count绝对值个元素。
  • count=0,删除所有。

实例

127.0.0.1:6379> lpush listdel a a a b b b c c c

(integer) 9

127.0.0.1:6379> lrange listdel 0 -1

  1. "c"
  2. "c"
  3. "c"
  4. "b"
  5. "b"
  6. "b"
  7. "a"
  8. "a"
  9. "a"

    127.0.0.1:6379> lrem listdel 2 a

    (integer) 2

    127.0.0.1:6379> lrange listdel 0 -1
  10. "c"
  11. "c"
  12. "c"
  13. "b"
  14. "b"
  15. "b"
  16. "a"

(4)按照索引范围修剪列表

ltrim key start end

127.0.0.1:6379> lrange listdel 0 -1

  1. "c"
  2. "c"
  3. "c"
  4. "b"
  5. "b"
  6. "b"
  7. "a"

    127.0.0.1:6379> ltrim listdel 2 4

    OK

    127.0.0.1:6379> lrange listdel 0 -1
  8. "c"
  9. "b"
  10. "b"

    修改

    修改指定索引下标的元素:

    lset key index newValue

    实例

    127.0.0.1:6379> lset listdel 0 a

    OK

    127.0.0.1:6379> lrange listdel 0 -1
  11. "a"
  12. "b"
  13. "b"

阻塞操作

blpop key [key ...] timeout

brpop key [key ...] timeout

blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同,所以下面以brpop命令进行说明,brpop命令包含两个参数: ·key[key...]:多个列表的键。 ·timeout:阻塞时间(单位:秒)。

1)列表为空:如果timeout=3,那么客户端要等到3秒后返回,如果 timeout=0,那么客户端一直阻塞等下去:

实例

127.0.0.1:6379> lrange empty 0 -1

(empty array)

127.0.0.1:6379> brpop empty 3

(nil)

(3.08s)

2)列表不为空:客户端会立即返回

实例

127.0.0.1:6379> brpop listdel 0

  1. "listdel"
  2. "b"

使用brpop时,有两点需要注意。 第一点,如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回

如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值

内部编码

列表类型的内部编码有两种。

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置 (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时 (默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使 用。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用 linkedlist作为列表的内部实现。

quicklist内部编码,简单地说它是以一个ziplist为节 点的linkedlist,它结合了ziplist和linkedlist两者的优势,为列表类型提供了一 种更为优秀的内部编码实现

实例

127.0.0.1:6379> object encoding code

"quicklist"

使用场景

1.消息队列

Redis的lpush+brpop命令组合即可实现阻塞队列,生产 者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令 阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性

2.文章列表

实际上列表的使用场景很多,在选择时可以参考以下:

  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=Capped Collection(有限集合)
  • lpush+brpop=Message Queue(消息队列)

集合

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过 索引下标获取元素。一个集合最多可以存储2^32-1个元 素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并 集、差集

命令

集合内操作

(1)添加元素

sadd key element [element ...]

127.0.0.1:6379> sadd myset a b c

(integer) 3

127.0.0.1:6379> sadd myset a b c

(integer) 3

127.0.0.1:6379> smembers myset

  1. "c"
  2. "a"
  3. "b"

(2)删除元素

srem key element [element ...]

127.0.0.1:6379> srem myset a b

(integer) 2

127.0.0.1:6379> smembers myset

  1. "c"

(3)计算元素个数

scard key

scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用 Redis内部的变量

127.0.0.1:6379> scard myset

(integer) 1

(4)判断元素是否在集合中

sismember key element

127.0.0.1:6379> sismember myset c

(integer) 1

(5)随机从集合返回指定个数元素

srandmember key [count]

[count]是可选参数,如果不写默认为1

实例

127.0.0.1:6379> sismember myset c

(integer) 1

127.0.0.1:6379> srandmember set 2

  1. "a"
  2. "b"

    127.0.0.1:6379> srandmember set 2
  3. "c"
  4. "a"

(6)从集合随机弹出元素

spop key

实例

127.0.0.1:6379> spop set

"b"

127.0.0.1:6379> spop set

"a"

(7)获取所有元素

smembers key

集合间操作

先add两个集合

127.0.0.1:6379> sadd user:a it is a man

(integer) 4

127.0.0.1:6379> sadd user:b this is a girl

(integer) 4

(1)求多个集合的交集

sinter key [key ...]

实例

127.0.0.1:6379> sinter user:a user:b

  1. "a"
  2. "is"

(2)求多个集合的并集

sunion key [key ...]

实例

127.0.0.1:6379> sunion user:a user:b

  1. "this"
  2. "girl"
  3. "is"
  4. "a"

(3)求多个集合的差集

sdiff key [key ...]

(4)将交集、并集、差集的结果保存

sinterstore destination key [key ...]

suionstore destination key [key ...]

sdiffstore destination key [key ...]

集合间的运算在元素较多的情况下会比较耗时,所以Redis提供了上面 三个命令(原命令+store)将集合间交集、并集、差集的结果保存在 destination key

内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-max- intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实 现,从而减少内存的使用。
  • hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使 用hashtable作为集合的内部实现。

    1)当元素个数较少且都为整数时,内部编码为intset

    2)当元素个数超过512个,内部编码变为hashtable

    3)当某个元素不为整数时,内部编码也会变为hashtable

使用场景

给用户添加标签,给标签添加用户,etc

有序集合

有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序 集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性, 但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为 排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依 据。如图2-24所示,该有序集合包含kris、mike、frank、tim、martin、tom, 它们的分数分别是1、91、200、220、250、251,有序集合提供了获取指定 分数和元素范围查询、计算成员排名等功能


有序集合中的元素不能重复,但是score可以重复


命令

集合内

(1)添加成员

zadd key score member [score member ...]

127.0.0.1:6379> zadd zset 175 bob

(integer) 1

有关zadd命令有两点需要注意: nx、xx、ch、incr四个选项:

  • nx:member必须不存在,才可以设置成功,用于添加。
  • xx:member必须存在,才可以设置成功,用于更新。
  • ch:返回此次操作后,有序集合元素和分数发生变化的个数
  • incr:对score做增加

    有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间 复杂度为O(log(n)),sadd的时间复杂度为O(1)

(2)计算成员个数

zcard key

实例

127.0.0.1:6379> zcard zset

(integer) 3

(3)计算某个成员的分数

zscore key member

实例

127.0.0.1:6379> zscore zset member

(nil)

127.0.0.1:6379> zscore zset bob

"175"

(4)计算成员的排名

zrank key member

zrevrank key member

zrank是从分数从低到高返回排名,zrevrank反之。

实例

127.0.0.1:6379> zrank zset bob

(integer) 0

127.0.0.1:6379> zrevrank zset bob

(integer) 2

(5)删除成员

zrem key member [member ...]

实例

127.0.0.1:6379> zrem zset bob

(integer) 1

(6)增加成员的分数

zincrby key increment member

实例

127.0.0.1:6379> zincrby zset 20 lili

"200"

(7)返回指定排名范围的成员

zrange key start end [withscores]

zrevrange key start end [withscores]


有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之,如果加上withscores选项,同时会返 回成员的分数

实例

127.0.0.1:6379> zrange zset 0 1 withscores

  1. "ss"
  2. "190"
  3. "lili"
  4. "200"

(8)返回指定分数范围的成员

zrangebyscore key min max [withscores] [limit offset count]

zrevrangebyscore key max min [withscores] [limit offset count]


其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之,withscores选项会同时返回每个 成员的分数

同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和 +inf分别代表无限小和无限大

实例

127.0.0.1:6379> zrangebyscore zset 180 190 withscores

  1. "ss"
  2. "190"

(9)返回指定分数范围成员个数

zcount key min max


实例

127.0.0.1:6379> zcount zset 180 200

(integer) 2

(10)删除指定排名内的升序元素

zremrangebyrank key start end

(11)删除指定分数范围的成员

zremrangebyscore key min max

集合间的操作

(1)交集

zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

参数说明:

  • destination:交集计算结果保存到这个键。
  • numkeys:需要做交集计算键的个数。
  • key[key...]:需要做交集计算的键。
  • weights weight[weight...]:每个键的权重,在做交集计算时,每个键中 的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
  • aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、 min(最小值)、max(最大值)做汇总,默认值是sum。

(2)并集

zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

该命令的所有参数和zinterstore是一致的,只不过是做并集计算

内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist- entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配 置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。
  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作 为内部实现,因为此时ziplist的读写效率会下降。

1)当元素个数较少且每个元素较小时,内部编码为ziplist

127.0.0.1:6379> object encoding zset

"ziplist"

2)当元素个数超过128个,内部编码变为skiplist

使用场景

(1)添加用户赞数,(2)取消用户赞数 等等

关于字符串的介绍,见合集中

redis字符串理解

redis(三)-----redis基本数据类型的更多相关文章

  1. redis(三)redis+Keepalived主从热备秒级切换

    一 简介 安装使用centos 5.10 Master 192.168.235.135 Slave 192.168.235.152 Vip 192.168.235.200 编译环境 yum -y in ...

  2. Redis系列三 Redis数据类型

    一 .Redis的五大数据类型 1.String(字符串) string是redis最基本的数据类型,可以理解成与 Memached一模一样的数据类型,一个key对应一个value. string 类 ...

  3. Redis学习手册(Set数据类型)

    一.概述: 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复杂度 ...

  4. Redis API与常用数据类型简介

    Redis API与常用数据类型简介 一.Redis API For .Net 首先,不得不说Redis官方提供了众多的API开发包,但是目前Redis官方版本不支持.Net直接进行连接,需要使用一些 ...

  5. 3 Redis 的常用五大数据类型

    2016-12-21 14:54:20 该系列文章链接NoSQL 数据库简介Redis的安装及及一些杂项基础知识Redis 的常用五大数据类型(key,string,hash,list,set,zse ...

  6. Redis学习之二 数据类型和相关命令

    原文:https://www.cnblogs.com/lonelyxmas/p/9073928.html 如果还不懂安装的,请看 Windows环境下安装Redis Redis一共支持五种数据类型 1 ...

  7. 缓存系列之三:redis安装及基本数据类型命令使用

    一:Redis是一个开源的key-value存储系统.与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串.哈希表.链表.集合.有序集合以及基于这些数据类型的相关操 ...

  8. Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势

    一.Redis数据类型 1.string string是Redis的最基本数据类型,一个key对应一个value,每个value最大可存储512M.string一半用来存图片或者序列化的数据. 2.h ...

  9. redis之 Redis常用数据类型

    Redis最为常用的数据类型主要有以下7种: 一. String (字符) 常用命令:  set,get,decr,incr,mget 等. 应用场景:String是最常用的一种数据类型,普通的key ...

随机推荐

  1. ubuntu 18.04 关掉sudo密码

    关掉sudo密码 $ sudo visudo 找到如下行 %sudo ALL=(ALL:ALL) ALL 修改为 %sudo ALL=(ALL:ALL) NOPASSWD:ALL 这样sudo用户组的 ...

  2. 【Java】多线程入门

    Java多线程学习(入门) 前言 目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程.那么这次选择的是Java的多线程学习, ...

  3. [USB波形分析] 全速USB波形数据分析(二)

    在上一篇文章全速USB波形数据分析(一)介绍了全速USB的数据包(Packet)的组成,数据的类型等基本知识.这篇文章介绍USB的几种传输方式 事务(Transaction) USB协议定义了三种不同 ...

  4. [FatFs 学习] SD卡总结-SPI模式

    SD卡为移动设备提供了安全的,大容量存储解决方法.它本身可以通过两种总线模式和MCU进行数据传输,一种是称为SD BUS的4位串行数据模式,另一种就是大家熟知的4线SPI Bus模式.一些廉价,低端的 ...

  5. 【刷题-LeetCode】122 Best Time to Buy and Sell Stock II

    Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...

  6. 【记录一个问题】go1.17中,把代码文件放在main.go的同级目录,导致无法编译

    写了类似目录结构的代码: myproxy - main.go - server.go 编译的时候总是出现main.go中找不到类型定义.但是用goland却可以直接执行. 最后调整了目录结构后解决: ...

  7. 一文读懂 HTTP/1HTTP/2HTTP/3

    转自 https://zhuanlan.zhihu.com/p/102561034

  8. Windows Server 2008 R2 数据离机备份与恢复操作手册

    Windows Server 2008 R2 数据离机备份与恢复操作手册 实验环境 Windows server 2008 R2(服务器) IP地址:192.168.136.175 计算机名:CXH ...

  9. python3 类的学习

    # -*-coding:utf-8-*- # 定义类是通过class关键字,class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来 ...

  10. python开发之函数

    转:https://www.tuicool.com/wx/vEVrqeR 06 python开发之函数 博客园精华区12-12 20:56 06 python开发之函数 目录 6.2 调用函数与函数返 ...