Redis数据类型和常用命令,看这篇就够了

Redis不是简单的键值存储,它实际上是一个数据结构服务器,支持不同类型的值。这意味着在传统键值存储中,您将字符串键与字符串值相关联,而在Redis中,该值不仅限于简单的字符串,还可以容纳更复杂的数据结构。


Redis键

Redis键是二进制安全的,这意味着您可以使用任何二进制序列作为键,从“ foo”之类的字符串到JPEG文件的内容。空字符串也是有效的键。

redis中,用:表示分层结构,如 object-type:id


Redis 数据类型

Redis Strings

这是最简单Redis类型。如果你只用这种类型,Redis就像一个可以持久化的memcached服务器(注:memcache的数据仅保存在内存中,服务器重启后,数据将丢失)。
Redis字符串是二进制安全的,这意味着一个Redis字符串能包含任意类型的数据,例如: 一张JPEG格式的图片或者一个序列化的Ruby对象。

使用Redis Strings,用SET command 和 GET command来设置和获取字符串值。

例:

127.0.0.1:6379> set onekey hello
OK
127.0.0.1:6379> get onekey
"hello"

当我们的key已经存在,再使用set命令,会用新值替换掉新值

例:

127.0.0.1:6379> set onekey hello
OK
127.0.0.1:6379> get onekey
"hello"
127.0.0.1:6379> set onekey update
OK
127.0.0.1:6379> get onekey
"update"

值可以是任何种类的字符串(包括二进制数据),例如你可以在一个键下保存一副jpeg图片。值的长度不能超过512 MB。

我们可以在set命令后加一个nx,当key存在时SET会失败,只有当key不存在时它只会成功。

例:

127.0.0.1:6379> get onekey
"update"
127.0.0.1:6379> set onekey new nx
(nil)

虽然字符串是Redis的基本值类型,但你仍然能通过它完成一些有趣的操作。例如:原子递增:

127.0.0.1:6379> set numm 1
OK
127.0.0.1:6379> incr numm
(integer) 2

注意:递增的值只能是整型的,如果是字符型的,则会报错。如下

127.0.0.1:6379> incr onekey
(error) ERR value is not an integer or out of range

INCR 命令将字符串值解析成整型,将其加一,最后将结果保存为新的字符串值,类似的命令有INCRBY, DECR 和 DECRBY。

INCRBY 命令

将key对应的数字加decrement。如果key不存在,操作之前,key就会被置为0。如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的正型数字。

返回值

integer-reply: 增加之后的value值。

例子

redis> SET mykey "10"
OK
redis> INCRBY mykey 5
(integer) 15
redis> 

DECR和DECRBY表示减法,用法和INCR和INCRBY 是一样的,只不过表示的是减法

注:以上的增减命令,如果key不存在,那么在操作之前,这个key对应的值会被置为0,所以不用担心key不存在的问题

INCR是原子性操作的,就是说即使多个客户端对同一个key发出INCR命令,也决不会导致竞争的情况。例如如下情况永远不可能发生:『客户端1和客户端2同时读出“10”,他们俩都对其加到11,然后将新值设置为11』。最终的值一定是12,read-increment-set操作完成时,其他客户端不会在同一时间执行任何命令。


获取或存储多个值

我们如果想一次存储或获取多个key对应的值,可以使用MSET和MGET命令:

127.0.0.1:6379> mset a 1 b 2
OK
127.0.0.1:6379> mget a b

  1. “1”
  2. “2”

MGET 命令返回由值组成的数组。


GETSET命令

语法
GETSET key value

将key的值设置成value值并且返回原来key对应的value(旧值)。如果key存在但是对应的value不是字符串,就返回错误。


修改或查询键空间

有些指令不是针对任何具体的类型定义的,而是用于和整个键空间交互的。因此,它们可被用于任何类型的键。

使用EXISTS命令返回1或0标识给定key的值是否存在,使用DEL命令可以删除key对应的值,DEL命令返回1或0标识值是被删除(值存在)或者没被删除(key对应的值不存在)。


> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0

TYPE命令可以返回key对应的值的存储类型:

> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none

设置过期时间:

我们可以对key设置一个超时时间,当这个时间到达后该key会被删除。

一、使用expire设置过期时间(也可以再次调用这个命令来改变超时时间,使用PERSIST命令去除超时时间 )适用于key已经存在的情况,时间单位为秒

expire key 5

二、我们也可以在创建值的时候设置超时时间,ex表示秒,px表示毫秒

127.0.0.1:6379> set k 100 ex 10
OK
127.0.0.1:6379> get k
"100"
127.0.0.1:6379> get k
(nil)

TTL命令用来查看key对应的值剩余存活时间。例:ttl key


Redis Lists

一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表。但用数组实现的List和用Linked List实现的List,在属性方面大不相同。

Redis lists基于Linked Lists实现。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用LPUSH 命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。

那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。

Redis Lists用linked list实现的原因是:因为对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要因素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。

如果快速访问集合元素很重要,建议使用可排序集合(sorted sets)。

Redis lists 入门

LPUSH 命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素。最后LRANGE 命令可从list中取出一定范围的元素:

127.0.0.1:6379> LPUSH mylist 1
(integer) 1
127.0.0.1:6379> LPUSH mylist 2
(integer) 2
127.0.0.1:6379> RPUSH mylist 3
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
2) "1"
3) "3"

注意:LRANGE 带有两个索引,一定范围的第一个和最后一个元素。这两个索引都可以为负来告知Redis从尾部开始计数,因此-1表示最后一个元素,-2表示list中的倒数第二个元素,以此类推。

当然,我们使用lpush和rpush的时候,可以传入多个值

删除list的元素使用lpop或者rpop,lpop为在list的左边(头部)删除一个元素,rpop为在list的右边(尾部)删除一个元素

LTRIM把list从左边截取指定长度。

修剪(trim)一个已存在的 list,这样 list 就会只包含指定范围的指定元素。start 和 stop 都是由0开始计数的, 这里的 0 是列表里的第一个元素(表头),1 是第二个元素,以此类推。start 和 end 也可以用负数来表示与表尾的偏移量,比如 -1 表示列表里的最后一个元素, -2 表示倒数第二个,等等。

List的常用案例

正如你可以从上面的例子中猜到的,list可被用来实现聊天系统。还可以作为不同进程间传递消息的队列。关键是,你可以每次都以原先添加的顺序访问数据。这不需要任何SQL ORDER BY 操作,将会非常快,也会很容易扩展到百万级别元素的规模。

例如在评级系统中,比如社会化新闻网站 reddit.com,你可以把每个新提交的链接添加到一个list,用LRANGE可简单的对结果分页。

在博客引擎实现中,你可为每篇日志设置一个list,在该list中推入博客评论,等等。


List上的阻塞操作

可以使用Redis来实现生产者和消费者模型,如使用LPUSH和RPOP来实现该功能。但会遇到这种情景:list是空,这时候消费者就需要轮询来获取数据,这样就会增加redis的访问压力、增加消费端的cpu时间,而很多访问都是无用的。为此redis提供了阻塞式访问 BRPOP 和 BLPOP 命令。 消费者可以在获取数据时指定如果数据不存在阻塞的时间,如果在时限内获得数据则立即返回,如果超时还没有数据则返回null, 0表示一直阻塞。

同时redis还会为所有阻塞的消费者以先后顺序排队。

BRPOP 命令

语法

BRPOP key [key …] timeout

返回值

当没有元素可以被弹出时返回一个 nil 的多批量值,并且 timeout 过期。

当有元素弹出时会返回一个双元素的多批量值,其中第一个元素是弹出元素的 key,第二个元素是 value。

例:

127.0.0.1:6379> BRPOP mylist 2

  1. “mylist”
  2. “3”

key 的自动创建和删除

目前为止,在我们的例子中,我们没有在推入元素之前创建空的 list,或者在 list 没有元素时删除它。在 list 为空时删除 key,并在用户试图添加元素(比如通过 LPUSH)而键不存在时创建空 list,是 Redis 的职责。

这不光适用于 lists,还适用于所有包括多个元素的 Redis 数据类型 – Sets, Sorted Sets 和 Hashes。

基本上,我们可以用三条规则来概括它的行为:

1、当我们向一个聚合数据类型中添加元素时,如果目标键不存在,就在添加元素前创建空的聚合数据类型。

2、当我们从聚合数据类型中移除元素时,如果值仍然是空的,键自动被销毁。(即所有的元素被弹出之后, key 不复存在。)

3、对一个空的 key 调用一个只读的命令,比如 LLEN (返回 list 的长度),或者一个删除元素的命令,将总是产生同样的结果。该结果和对一个空的聚合类型做同个操作的结果是一样的。


Redis哈希

Redis Hashes是字符串字段和字符串值之间的映射,所以它们是完美的表示对象的数据类型。

一个拥有少量字段的hash只需要 很少的空间来存储,所有你可以在一个小型的 Redis实例中存储上百万的对象。

Redis哈希使用字段-值对的方式,看起来与人们期望的“散列”看起来完全一样:

127.0.0.1:6379> HMSET user name m age 18
OK
127.0.0.1:6379> HGET user name
"m"

HMSET 语法

HMSET key field1 value1 field2 value2...

Hash 便于表示 objects,实际上,你可以放入一个 hash 的域数量实际上没有限制(除了可用内存以外)。

HMSET命令设置哈希的多个字段,HSET设置哈希的一个字段,而HGET检索单个字段。HMGET检索多个字段,返回一个数组。

hash的命令跟普通string命令差不多,只是前面多了个h

下面介绍一些常用的hash命令

//删除某个key的field

HDEL key field [field ...]

//返回哈希的所有键值对

HGETALL key

//返回哈希中包含的字段数

HLEN key

//设置哈希中field 的值,只有当field不存在才能成功

HSETNX key field value

//返回哈希中的所有值

HVALS key

值得注意的是,小哈希(即,一些具有较小值的元素)以特殊方式在内存中进行编码,从而使它们具有很高的内存效率。


Redis Sets

Redis Sets是一个无序的字符串合集。你可以以O(1) 的时间复杂度(无论集合中有多少元素时间复杂度都为常量)完成 添加,删除以及测试元素是否存在的操作。

Redis Sets有着不允许相同成员存在的优秀特性。向集合中多次添加同一元素,在集合中最终只会存在一个此元素。实际上这就意味着,在添加元素前,你并不需要事先进行检验此元素是否已经存在的操作。

Redis Sets集是字符串的无序集合。SADD 指令把新的元素添加到 set 中,对 set 也可做一些其他的操作,比如测试一个给定的元素是否存在,对不同 set 取交集,并集或差,等等

下面介绍下sets的常用命令

//往set添加元素

SADD key member [member ...]

//返回set集合中的所有元素

SMEMBERS key

//删除并返回删除的元素,可以指定删除的个数,如果未指定个数,默认为1个

SPOP key [count]

//返回set集合的元素个数,为0则表示集合为空

SCARD key

//返回由第一个集合和所有连续集合之间的差得出的集合成员(即第一个集合中其他集合没有的元素)。

SDIFF key [key ...]

例:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}

//判断该member元素是否是存储在集合的成员

SISMEMBER key member

//将source集合的member元素移动到destination集合。如果源集不存在或不包含指定的元素,则不执行任何操作并0返回。否则,该元素将从源集中删除,并添加到目标集中。如果指定的元素已存在于目标集中,则仅将其从源集中删除。

SMOVE source destination member

//从指定的集合中删除指定的成员member ,不是该集合成员的指定成员将被忽略。如果key不存在,则将其视为空集,并且此命令返回 0。

SREM key member [member ...]

//返回所有给定集合的并集产生的集合成员。

SUNION key [key ...]
例:
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}

SUNIONSTORE 用于对多个集合取并集,并把结果存入另一个 set(即destination ) 中

SUNIONSTORE destination key [key ...]

//随机返回count个元素,不指定count,则为返回一个

SRANDMEMBER key [count]

//sinter 第一个集合与后续集合做比较,并返回第一个集合的交集

SINTER key [key ...]

例:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}

//将集合的交集放到destination 集合中

SINTERSTORE destination key [key ...]

有序集合(Sorted sets)

Redis有序集合和Redis集合类似,也称ZSET,是不包含 相同字符串的合集。它们的差别是,每个有序集合 的成员都关联着一个评分,这个评分用于把有序集 合中的成员按最低分到最高分排列。

使用有序集合,你可以非常快地(O(log(N)))完成添加,删除和更新元素的操作。 因为元素是在插入时就排好序的,所以很快地通过评分(score)或者 位次(position)获得一个范围的元素。 访问有序集合的中间元素同样也是非常快的,因此你可以使用有序集合作为一个没用重复成员的列表。 在这个列表中, 你可以轻易地访问任何你需要的东西: 有序的元素,快速的存在性测试,快速访问集合中间元素!

有序集合按照以下规则排序:

1、如果A和B是两个具有不同分数的元素,则如果A.score是> B.score,则A>B。

2、如果A和B的得分完全相同,那么如果A字符串在字典上大于B字符串,则A>B。A和B字符串不能相等,因为排序集仅具有唯一元素。

下面是有序集合的常用命令:

ZADD key [NX|XX] [CH] [INCR] score member [score member ...]

例:

127.0.0.1:6379> ZADD myzset 1 "one" 2 "two"
(integer) 2

将所有指定成员添加到键为key有序集合(sorted set)里面。 添加时可以指定多个分数/成员(score/member)对。 如果指定添加的成员已经是有序集合里面的成员,则会更新改成员的分数(scrore)并更新到正确的排序位置。

如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合,就像原来存在一个空的有序集合一样。如果key存在,但是类型不是有序集合,将会返回一个错误应答。

分数值是一个双精度的浮点型数字字符串。+inf和-inf都是有效值。

ZADD 命令在key后面的分数/成员对(score/member)前面支持添加一些参数,他们是:

XX: 仅仅更新存在的成员,不添加新成员。

NX: 不更新存在的成员。只添加新成员。

CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。

INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。

ZCARD key

返回key的有序集元素个数,不存在返回0。

ZCOUNT key min max

返回指定分数范围的元素个数。

例:

127.0.0.1:6379> ZCOUNT myzset 1 2
(integer) 2
ZINCRBY key increment member

为有序集key的成员member的score值加上增量increment。如果key中不存在member,就在key中添加一个member,score是increment(就好像它之前的score是0.0)。如果key不存在,就创建一个只含有指定member成员的有序集合。


ZLEXCOUNT key min max

计算有序集合中指定成员之间的成员数量。

完整示例

zlexcount zset [member1 [member5
指令	    是否必须	    说明
zlexcount	是	    指令
key	        是	    有序集合键名称
min	        是	    在有序集合中分数排名较小的成员
max	        是	    在有序集合中分数排名较大的成员

提示:
成员名称前需要加 [ 符号作为开头, [ 符号与成员之间不能有空格

可以使用 - 和 + 表示得分最小值和最大值

min 和 max 不能反, max 放前面 min放后面会导致返回结果为0

计算成员之间的成员数量时,参数 min 和 max 的位置也计算在内。


ZRANK key member

返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。


ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

返回有序集合中指定分数区间内的成员,分数由高到低排序。


ZREMRANGEBYSCORE key min max

移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。 自版本2.1.6开始,score值等于min或max的成员也可以不包括在内。增加(符号可以不包括min或max值。

例:

ZREMRANGEBYSCORE myzset (1 (10

Zrevrange 命令

返回有序集中,指定区间内的成员。其中成员的位置按分数值递减(从大到小)来排列。

语法:

redis 127.0.0.1:6379> ZREVRANGE key start stop [WITHSCORES]

例:

ZREVRANGE salary 0 -1 WITHSCORES

Zrange 命令

返回有序集中,指定区间内的成员。其中成员的位置按分数值递增(从小到大)来排序。

其中成员的位置按分数值递增(从小到大)来排序。

语法:

ZRANGE key start stop [WITHSCORES]

例:

ZRANGE salary 0 -1 WITHSCORES
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值