Redis学习-数据类型(二)

摘要:
安装完Redis并知道如何启动和关闭服务器/客户端后,继续学习Redis的基本数据类型。Redis有五种数据类型,即字符串哈希(hash)列表集有序集。Redis也是一个基于内存的数据库。这五种数据类型的共同特点是数据保存在键值对中。对于习惯于Java的程序员来说,可以自定义Map的Key和Value,并且该值还可以与Map/List/Set嵌套,例如Map<Str公司

在安装好redis,也了解了如何启动和关闭服务端/客户端之后,继续学习redis的基本数据类型

redis的数据类型有五种,分别是

字符串

散列(哈希)

列表

集合

有序集合

redis也是一种基于内存的数据库,五种数据类型的共同之处是数据都以Key-Value键值对保存,对于习惯了Java的程序员来说,Map的Key和Value可以自定义,value还可以嵌套Map/List/Set,比如Map<String,Object> m,Object可以是任意的数据类型,但是这种在redis中是不允许的,key只能是一个类型,例如字符串的Key如果存入的value为散列数据,那么redis会抛出一个错误

Redis学习-数据类型(二)第1张

说明这个key已经存入了其他数据类型的value。接下来逐个学习各种数据类型。

字符串

字符串是reids最基本的数据类型,可以存储图片、字符、Json格式化的对象,一个字符串类型允许存储的大小最大512MB(已经很大了,内存可是很宝贵的!)

字符串的常用命令如下(斜体表示形式参数,[]表示可选参数)

命令功能复杂度可选参数说明
setkey value [p]保存key-valueO(1)

ex second

px millisecond

nx

xx

设置过期时间为秒

设置过期时间为毫秒

key不存在时,才执行set

key存在时,才执行set

getkey读取key的valueO(1) key不存在,返回(nil)
incrkey整数递增O(1) 

key不存在,创建,value先初始化为0,然后+1

key不是数字,抛出异常

key为数字,+1且返回递增后的值

incrbykey increment按 increment递增O(1) 

incr相似

increment>0,增加数值

increment<0,减少数值

返回值为计算后的结果

decrkey整数递减O(1) 

key不存在,创建,value先初始化为0,然后-1

key不是整数,抛出异常

key为整数,-1且返回递减后的值

decrbykey increment按 increment递减O(1) 

decrby相似

increment>0,减少数值

increment<0,增加数值

返回值为计算后的结果

incrbyfloat key increment增加指定浮点值O(1) 

increment如果是整数,效果等同于incrby,

增量可以用科学计数法表示,如3e5,4e-2

increment>0,减少数值

increment<0,增加数值

返回值为计算后的结果

appendkey value尾部追加O(1) 

如果key不存在,等同于setkey value

追加value,返回追加后的长度

strlen key计算value字符串长度O(1) 

如果key不存在,返回0,

对于中文或其他字符,按照实际utf-8的编码长度

返回,如“你好”,返回的长度是6

msetkey...批量设置key-valueO(N) 

操作多个key时,是一个原子操作

如果成功,则所有key都同时设置

mget key...批量获取key-valueO(N) 如果给定的key不存在,返回nil
setbit key offset value设置偏移量上的bitO(1) 

value只能是0或1

当key不存在时,自动生成一个新的字符串扩容时,

非填充的位置以0填充,offser的值在[0,2^32)之间

getbitkey offset获取偏移量上的bitO(1) 如果offset大于字符串的长度,或者key不存在,返回0
bitcountkey [start] [end]统计bit被设置为1的数量O(N)

start

end

起始位置

结束位置

bitop[op] destkey key...

对key进行位操作

结果保存到destkey上

O(N)

and

or

xor

not

逻辑且

逻辑或

逻辑异或

逻辑非

bitpos key bit [start] [end]返回第一个被设置为1或0的bit位O(N)

start

end

起始位置

结束位置

以上字符串命令在项目中会经常使用,关于bit的相关操作,很有必要掌握,确实解决了很多业务和性能问题。最常遇到的应该是统计用户活跃度问题,举个例子,产品要求统计上线以来,每个用户的活跃度曲线,我们要做的就是两件事,

1、统计每个用户的活跃天数,具体的访问日期

2、根据维度、粒度绘制曲线图

Redis学习-数据类型(二)第2张

这种统计方式与关系型数据库相比,性能更高,也不用写复杂的SQL,取得数据后就是绘制曲线图,这不是本文的重点,就不详述了。

如果有其他的统计需求,比如用户A第一次使用产品或某个日期区间内第一次使用产品的日期,可以使用bitpos命令,

Redis学习-数据类型(二)第3张

 

散列(哈希)

散列也是以kv结构存储,与Java的Map很像,但是它的value只能是字符串,也就是无法像Map那样可以嵌套。散列的存储结构可以简单的用下图表示

Redis学习-数据类型(二)第4张

 

散列的常用命令如下

命令功能复杂度可选参数说明
hsetkey field value设置key中的field值为valueO(1) 

如果field不存在且value设置成功,返回1

如果field已存在,新值将覆盖旧值,返回0

hgetkey field获取key中指定域的值O(1)  
hmsetkey field value [field value...]设置一个或多个field-value对O(N) 如果filed已存在,将会覆盖
hmgetkey field...获取key中一个或多个域的值O(N) 

key不存在,返回nil

field不存在,返回nil

hgetallkey获取key所有域和值O(N)  
hexists key field判断field是否存在O(1) 

如果field存在,返回1

如果field不存在,或key不存在,返回0

hsetnx key field value

当且仅当field不存在时,赋值为value

O(1) 

如果field存在,不执行赋值操作

如果key不存在,相当于创建key并赋值field

hincrby key field increment让key中的field按increment递增O(1) 

field的value不是数字,报错

increment>0,增加数值

increment<0,减少数值

返回值为计算后的结果

hincrbyfloat key field increment让key中的field按increment浮点数递增O(1) 

hincrby

hdelkey field...删除key的一个或多个fieldO(N) 返回成功删除field的个数
hkeys key只获取key的所有fieldO(N) 
包含所有field的表
当key不存在时,返回一个空表
hvalskey只获取key的所有field的值O(N) 
包含所有value的表
当key不存在时,返回一个空表
hlenkey返回field的数量O(1) key不存在时,返回0

有了散列数据类型,当作为数据库时,一个用户的属性包含id,姓名,性别,联系电话,在关系型数据库的表结构可以表示为

Idnamegendermobile
1张三135xxxxxx
2李四135xxxxxx

用redis的散列可以表示为

Redis学习-数据类型(二)第5张

假如要增加一个属性驾驶证号码,这个属性只针对id=1的数据有效,对于其他数据是冗余的,那么只能对表结构进行修改,增加一个字段

IdnamegendermobilecardId
1张三135xxxxxxxxxxxx
2李四135xxxxxx 

redis的散列结构不需要这么做,它的存储结构都是独立的,可以自由的增减field,不影响其他field

Redis学习-数据类型(二)第6张

列表

列表类型可以存储一个有序的字符串列表,支持双端操作,底层的实现是双向链表,所以两端添加元素时性能很高,越接近两端的元素越快,但是随机访问的性能就比较差,这跟Java的链表很相似。

命令功能复杂度可选参数说明
lpush key value...将一个或多个value插入key列表的表头O(1) 返回列表的长度
rpush key value...将一个或多个value插入key列表的表尾O(1) 返回列表的长度
lpop key移除并返回key列表的头元素O(1) 

返回列表的头元素

key不存在时,返回nil

rpopkey移除并返回key列表的尾元素O(1) 

返回列表的尾元素

key不存在时,返回nil

llen key返回列表的长度O(1) 

如果key不存在,返回0

如果key不是列表类型,报错

lrangekey start end

返回列表key中起始和

结束区间内的元素

O(S+N)

 

start end以0为底,可以>0也可以<0,

为0时表示最左边第一个元素

1表示最左边第二个元素,

-1表示最右边第一个元素,

-2表示最右边第二个元素,依此类推,

start end的区间为闭区间,包含start和end下标

的元素。如果start>列表最大下标,返回空列表,

如果end>列表的最大下标,则返回到最右边的元素

lrem key count value移除列表中与value相等的元素O(N)  

count>0,从表头开始向表尾遍历,

删除与value相等的元素,数量为count

count<0,从表尾开始向表头遍历,

删除与value相等的元素,数量为count绝对值

count=0,删除所有表中与value相等的元素

lindex key index返回列表中下标为index的元素 O(N) 

index>0,列表从表头开始遍历第index个元素

index<0,列表从表尾开始遍历第index个元素

lset key index value将下标为index的元素值设置为valueO(N)  

index>0,列表从表头开始遍历第index个元素 

index<0,列表从表尾开始遍历第index个元素

linsert key Before/After

pivot value

将value插入列表中

插入pivot之前或之后

O(N) 

在列表中不存在pivot值时,不执行操作

key不存在时,不执行操作

rpoplpush src dest

将列表src的表尾元素弹出

插入列表dest的表头

 O(1) 

弹出的元素会作为返回值返回

如果src不存在,返回nil,不执行其他操作

如果dest不存在,创建dest列表

如果src和dest相同,等同于将表尾元素移到表头

集合

集合与列表有一些相似之处,也很容易区分,集合的元素是不可重复的,与Java的HashSet类似,也是无序的。

命令功能复杂度可选参数说明
sadd key member...将一个或多个member元素加入到集合key中O(N) 

如果key不存在,自动创建

已存在与集合的member元素将被忽略

成功返回加入的元素数量

(忽略的元素不计算在内)

srem key member...将一个或多个member元素删除O(N) 返回成功移除的元素数量
smemberskey返回集合key中的所有元素O(N) key不存在,返回空集合
sismemberkey member判断元素member是否在集合key中O(1) 

如果member元素在集合key中,返回1

如果key不存在或member元素不在集合key中,返回0

sdiff key...差集运算O(N) 

当key不存在,视为空集合

返回差集集合

sidffstore dest key...差集运算,将结果保存到dest中O(N) 

dest如果已存在,将其覆盖

dest可以是key自身

返回结果集中的元素数量

sinterkey...交集运算O(N*M) 

当key不存在,视为空集合

返回交集集合

sinterstore dest key...交集运算,将结果保存到dest中O(N*M) 

dest如果已存在,将其覆盖

dest可以是key自身

返回结果集中的元素数量

sunionkey...并集运算O(N) 

当key不存在,视为空集合

返回并集集合

sunionstore dest key...并集运算,将结果保存到dest中O(N) 

dest如果已存在,将其覆盖

dest可以是key自身

返回结果集中的元素数量

scardkey获取集合key的元素数量O(1) 返回集合个数,当key不存在时,返回0
srandmember key

随机获取集合key中的一个或多个元素(取决于

count的大小)

O(1)

O(N)

count

当0<count<集合size,返回count个不重复的元素

当count>=集合size,返回整个集合

当count<0,返回|count|个可能重复的元素

当key不存在,未提供count参数,返回nil

当key不存在,提供count参数,返回空集合

spop key删除并返回集合中的一个随机元素O(1) 

返回被移除的随机元素

当key不存在或key是空集合,返回nil

smove src dest member将member元素从src集合移动到dest集合O(1) 

当src不存在或member元素不在src中,

不执行任何操作,当dest中已包含member元素,

该操作仅将src的member元素删除

如果member元素在src中且被成功移除,返回1

如果member元素不是src集合成员,并且没有

对dest执行操作返回0 

有序集合

有序集合与集合的区别就在于它是有序的,在集合的基础上,有序集合中的元素多了一个score属性,使得有序集合可以基于score进行排序等与数值有关的操作,有序集合和列表也有些相似,以下是列表、集合、有序集合三者的比较

 列表集合有序集合
是否有序x
是否唯一x
底层实现链表散列表散列表和跳表

有序集合与列表的差异还在于:

(1)列表访问两端的元素很快,元素越多,访问中间的元素越慢,有序集合基于散列表和跳表实现,读取中间部门的数据也很快

(2)列表无法简单的调整元素的位置,有序集合可以

以下是有序集合的常用命令

命令功能复杂度可选参数说明
zaddkey score member [score member ...]

将一个或多个member元素及其score

加入有序集合key中

O(M*log(N)) 

当member元素已存在有序集合中将更新score值和元素的位置

如果key不存在,创建一个有序集合并执行插入操作

返回成功添加的元素数量

(不包含已存在的元素)

zscorekey member获得元素的scoreO(1) 

如果key不存在或member元素不在有序集合key中,返回nil

zrangekey start stop [withscores]获取有序集合key中,指定区间内的元素O(log(N)+M)withscores

按照score从小到大的顺序返回索引从start

到stop之间的所有元素

如果start或stop大于0,表示从前向后查找

如果start或stop小于0,表示从后向前查找,

-1表示最后一个与元素

可选参数withscores表示一起返回元素和score值

例如元素1,score1,元素2,score2...

zrevrange key start stop [withscores]获取有序集合key中,指定区间内的元素O(log(N)+M)withscoreszrange不同的是,zrevrange是按照从大到小的顺序来排列

zrangebyscorekey min max 

[withscores] [limit offset count]

获取有序集合 key 中,所有 score 值介于 min 和

max 之间(包括等于 min 或 max )的元素。

O(log(N)+M)

withscores

limit offset count

 

有序集合元素按 score 值递增(从小到大)次序排列,

withscores参数会将score一起返回,limit参数指定

返回结果的数量和区间类似sql的 select limit offset count

min,max在默认情况下的取值为闭区间

也可以通过加(符号来使用开区间

zincrbykey increment member为一个元素的score值加上增量incrementO(log(N))  

返回元素新的score值

当key不存在,或member不在有序集合key中时,

等同于zadd key score member

increment>0,增加score

increment<0,减少score

zcard key获取有序集合key中元素的数量O(1) 

返回有序集合元素个数

当key不存在时,返回0

zcount key min max

获取有序集合key中,score值在min和max之间

(包括等于min或max)的元素数量

O(log(N)+M)  返回score值在min和max之间的元素数量
zrem key member ... 删除有序集合key中一个或多个member元素O(M*log(N)) 

如果member不存在,忽略

返回成功删除的元素数量(不包含忽略的元素)

zremrangebyrank key start stop

删除有序集合key中指定排名(rank)

区间内(包含start和stop)的所有元素

O(log(N)+M) 

有序集合按照score从小到大排序,

删除start和stop区间内(包含start和stop)的元素

当start或stop>0,表示从前向后查找

当start或stop<0,表示从后向前查找

zremrangebyscore key min max删除有序集合key中,指定score区间内的所有元素O(log(N)+M) 

有序集合按照score从小到大排序,

删除score区间在min和max之间的元素

默认情况下,删除的元素包含等于min或max的元素,

可以使用(符号表示开区间

zrankkey member获取member元素在有序集合key中从小到大排序后的索引O(log(N)) score值最小的索引为0
zrevrank key member获取member元素在有序集合key中从大到小排序后的索引O(log(N)) score值最大的索引为0

zinterstore dest numkeys key ...

[weights weight...][aggregate sum|min|max]

计算给定的一个或多个有序集合的交集

其中给定 key 的数量必须以 numkeys 参数指定,

并将该交集(结果集)储存到 dest 

O(N*K)+O(M*log(M))

weights

aggregate

weights,设置每个集合的权重

参与计算时元素要乘上该集合的权重

aggregate默认取值为sum,计算每个元素score的和,

设置为min时,计算每个元素的最小score值,

设置为max时,计算每个元素的最大score值

zunionstore dest numkeys key ...

[weights weight...][aggregate sum|min|max]

计算给定的一个或多个有序集合的并集

其中给定 key 的数量必须以 numkeys 参数指定,

并将该并集(结果集)储存到 dest 

O(N)+O(M log(M)) weights

aggregate

weights,设置每个集合的权重

参与计算时元素要乘上该集合的权重

aggregate默认取值为sum,计算每个元素score的和,

设置为min时,计算每个元素的最小score值,

设置为max时,计算每个元素的最大score值

免责声明:文章转载自《Redis学习-数据类型(二)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇什么是LMDB闪电记忆映射数据库太阳八大行星运行轨迹下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

redis缓存策略

常用策略有“求留余数法”和“一致性HASH算法” redis存储的是key,value键值对 一、求留余数法 使用HASH表数据长度对HASHCODE求余数,余数作为索引,使用该余数,直接设置或访问缓存。 计算key的HashCode 缺点:增加服务器,由于除数不一样了,之前缓存的数据都没办法访问了,即不支持热部署【扩展】 二、一致性HASH算法 一致性...

DockerCompose

一、Docker Compose 1、前言 我们知道使⽤⼀个 Dockerfile 模板⽂件,可以让⽤户很⽅便的定义⼀个单独的应⽤容器。然⽽,在⽇常⼯作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。 例如要实现⼀个 Web 项⽬,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚⾄还包括负载均衡容器等,我们只能一个一个`写doc...

redis实现消息队列

业务需求 本文是以laravel框架来介绍redis队列,具体用法你可以参考http://www.cnblogs.com/lengthuo/p/7277260.html最近接受一个很简单的东西,(说起来很简单,硬是搞了2天。)我们业务中的一些定时是在晚上执行,但是有的定时必须推送微信消息给用户,为了不影响客户的休息,我们之后想把发去推迟这个任务。对于我们...

redis常见命令

一、介绍 1、Redis是什么 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis提供了一些丰富的数据结构,包括 lists, sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当...

Nginx + Tomcat7 + redis session一致性问题

        Nginx 作负载均衡时,由于是每次都需要把请求分发到不同的机器,同一个用户在一台机器上创建了 session,下一次的请求很有可能会转发到另外一台机器,会造成 session 丢失。我们可以使用 Redis 来保存 session。具体步骤如下: 1.  https://files.cnblogs.com/files/langfanyun...

redis以服务模式开机启动

第一步 修改redis为后台启动 vim /usr/redis/redis.conf #路径根据实际情况决定 # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/...