一,什么是Redis?
Redis—— Remote Dictionary Server,它是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、
Key-Value数据库,并提供多种语言的API,我们可使用它构建高性能,可扩展的Web应用程序。
二,传统数据库在遇到大量数据时面临的问题
- MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
- Memcached与MySQL数据库数据一致性问题。
- Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
- 跨机房cache同步问题。
这些数据类型都支持push/pop、add/remove及取交集、并集和差集及更丰富的操作,而且这些操作都是原子性的。
Redis具备以下特点:
- 异常快速: Redis数据库完全在内存中,因此处理速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
- 数据持久化: redis支持数据持久化,可以将内存中的数据存储到磁盘上,方便在宕机等突发情况下快速恢复。
- 支持丰富的数据类型: 相比许多其他的键值对存储数据库,Redis拥有一套较为丰富的数据类型。
- 数据一致性: 所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
- 多功能实用工具: Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),
- 任何短暂的数据,应用程序,如 Web应用程序会话,网页命中计数等。
SET
string 是 redis 中最基础的数据类型, redis 字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,
所以你可以存储任何东西,512兆为上限。
SET指令是将字符串值 value 关联到 key 。语法格式:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
示例:添加键page,值为‘hubwiz’。
- redis> SET page "hubwiz"
- OK
如果 key 已经持有其他值,SET就覆写旧值,无视类型。因此,对于某个原本带有生存时间(TTL)的键来说, 当SET命令成功
在这个键上执行时, 这个键原有的 TTL 将被清除。
SETEX
SETEX指令的作用是将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX
命令将覆写旧值,语法格式:
SETEX key seconds value
示例 - 设置page的值为‘hubwiz’,生存时间为60秒。
- redis> SETEX page 60 "hubwiz"
- OK
SETEX指令的作用类似如下两个命令:
不同之处是, SETEX 是一个 原子性 (atomic)操作, 关联值 和 设置生存时间 两个动作会在 同一时间 内完成,该命令在 Redis 用作
- SET name "hubwiz"
- EXPIRE key 60 # 设置生存时间
GET
GET指令是返回 key 所关联的字符串值。如果 key 不存在那么返回特殊值 nil 。假如key 储存的值不是字符串类型,返回一
个错误,因为GET只能用于处理字符串值,语法格式:
GET key
示例 - 获取page和test的值。
- redis> GET page
- "hubwiz"
- redis> GET test
- (nil)
返回值
- 当key不存在时,返回nil,否则返回key的值。
- 如果key的值不是字符串类型,那么将会返回一个错误。
APPEND
如果 key 已经存在并且是一个字符串,APPEND命令将 value 追加到 key 原来的值的末尾,语法格式:
APPEND key value
示例 - 向name追加字符‘.com’。
- redis> APPEND name ".com" # 对已存在的字符串进行 APPEND
- (integer) 10
- redis> GET name
- "hubwiz.com"
如果 key 不存在,APPEND就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
MSET
MSET指令可以同时设置一个或多个 key-value 对,如果某个给定 key 已经存在,那么MSET会用新值覆盖原来的旧值,语法格式:
MSET key value [key value ...]
示例 - 设置date、time和weather的值。
- redis> MSET date "2015.5.10" time "11:00 a.m." weather "sunny"
- OK
MSET是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情
况,不可能发生。
MGET
执行MGET指令,将返回所有(一个或多个)给定 key 的值,语法格式:
MGET key [key ...]
示例 - 获取date、time、weather、year的值。
如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。
- redis> MGET date time weather year
- 1) "2015.5.10"
- 2) "11:00 a.m."
- 3) "sunny"
- 4)(nil)
SETRANGE
SETRANGE指令是用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量offset开始。
不存在的 key 当作空白字符串处理,语法格式:
SETRANGE key offset value
示例 - 覆写say的值。
- redis> SET say "hello world"
- OK
- redis> SETRANGE say 6 "Redis"
- (integer) 11
- redis> GET say
- "hello Redis"
SETRANGE命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定 key 原来储存的字符串长度比偏移量小(比如
字符串只有 5 个字符长,但你设置的 offset 是 10 ),那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )来填充。
注意你能使用的最大偏移量是 2^29-1(536870911) ,因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内。如果你需要
使用比这更大的空间,你可以使用多个 key 。
STRLEN
STRLEN指令将会返回 key 所储存的字符串值的长度,语法格式:
STRLEN key
示例 - 获取say值的长度。
值得注意的是当 key 储存的不是字符串值时,返回一个错误。
- redis> STRLEN say
- (integer) 11
其他指令
除了前面我们提到的那些常用指令以外,还有很多其他的指令,这些指令只作了解即可,
当我们真正用到的时候再来详细了解如何使用它。
指令 | 用途 |
---|---|
GETSET | 设置键的字符串值,并返回旧值。 |
GETRANGE | 得到字符串的子字符串存放在一个键。 |
GETBIT | 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 |
SETBIT | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 |
SETNX | 将 key 的值设为 value ,当且仅当 key 不存在。 |
MSETNX | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 |
PSETEX | 和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 |
INCR | 将 key 中储存的数字值增一。 |
INCRBY | 将 key 所储存的值加上指定增量。 |
INCRBYFLOAT | 为 key 中所储存的值加上指定浮点数增量。 |
DECR | 将 key 中储存的数字值减一。 |
DECRBY | 将 key 所储存的值加上指定增量。 |
- getset name "tom"
- getrange name 0 2
- getbit name 2
- setbit name 2 0
什么是hash?
Redis的哈希值是字符串字段和字符串值之间的映射。
相比string等数据类型,它提供很多方便的域操作,因此在表示对象时,它是非常适合的数据类型。
在Redis中的哈希值存储容量也是非常大的,可存储超过400十亿键值对。
HSET
在 redis 中,使用HSET命令来将哈希表 key 中的域 field 的值设为 value ,语法如下:
HSET key field value
示例 - 添加键hubwiz,值为‘hubwiz.com’。
- redis> HSET site huwiz "hubwiz.com" # 设置一个新域
- (integer) 1
如果 key 不存在,一个新的哈希表被创建并进行HSET操作。
如果域 field 已经存在于哈希表中,旧值将被覆盖。
HMSET
除了HSET命令,HMSET命令的用途也是用来设置值,不同的是,HMSET一次可以设置多个 field-value (域-值)对设置到哈希表 key 中,语法如下:
HMSET key field value [field value ...]
示例 - 添加键www、lab。
- redis> HMSET site www www.hubwiz.com lab lab123.hubwiz.com
- OK
如果 key 不存在,将会创建一个空的哈希表并执行HMSET操作。
如果添加的域已存在哈希表中,那么它将被覆盖。
获取值
redis 中如何获取key的值呢?HGET是用来获取指定 key 值的命令,语法如下:
HGET key field
示例 - 获取域hubwiz的值。
执行 HGET 命令,如果 key 存在,将返回哈希表 key 中给定域 field 的值,如果 key 不存在,则返回 (nil) 。
- redis> HGET site hubwiz
- "www.hubwiz.com"
HMGET
作为HMSET命令对应的获取命令,HMGET可以一次性获取哈希表 key 中,一个或多个给定域的值,基本语法:
HMGET key field [field ...]
示例 - 获取域www、lab、test的值。
- redis> HMGET site www lab test # 返回值的顺序和传入参数的顺序一样
- 1) "www.hubwiz.com"
- 2) "lab.hubwiz.com"
- 3) (nil) # 不存在的域返回nil值
如果给定的域不存在于哈希表,那么返回一个 nil 值。
因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行HMGET操作将返回一个只带有 nil 值的表。
获取全部值
如果我们想要一次性获取全部域的值,很显然 HGET 和 HMGET 都是不合适的,所幸的是我们还有HGETALL指令,通过它,
我们可以轻松的获取到全部域值,基本语法如下:
HGETALL key
示例 - 获取people全部域的值。
- redis> HSET people jack "Jack Sparrow"
- (integer) 1
- redis> GET name
- redis> HSET people gump "Forrest Gump"
- (integer) 1
- redis> HGETALL people
- 1) "jack" # 域
- 2) "Jack Sparrow" # 值
- 3) "gump"
- 4) "Forrest Gump"
在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
HEXISTS
在应用环境中,我们经常会需要知道一个 key 中是否存在某个 field ,HEXISTS命令可以帮助我们达到这个目的,基本语法:
HEXISTS key field
示例 - 验证键www是否存在。
- redis> HEXISTS site www
- (integer) 0
查看哈希表 key 中,给定域 field 是否存在。
如果哈希表含有给定域,返回 1 。
如果哈希表不含有给定域,或 key 不存在,返回 0 。
HKEYS
我们经常会遇见这样的应用场景,比如在线用户列表、课堂列表等等,这时候我们可以使用HKEYS来获取哈希表 key 中的所
有域,基本语法:
HKEYS key
示例 - 查看键people中所有的域。
- redis> HMSET people jack "Jack Sparrow" gump "Forrest Gump"
- OK
- redis> HKEYS people
- 1) "jack"
- 2) "gump"
当 key 存在时,将返回一个包含哈希表中所有域的表。 当 key 不存在时,返回一个空表。
HLEN
HLEN命令将返回哈希表 key 中域的数量,什么时候会用到它呢?比如:在线聊天室,显示在线用户数,基本语法:
HLEN key
示例 - 查看db键中域的个数。
- redis> HSET db redis redis.com
- (integer) 1
- redis> HSET db mysql mysql.com
- (integer) 1
- redis> HLEN db
- (integer) 2
- redis> HSET db mongodb mongodb.org
- (integer) 1
- redis> HLEN db
- (integer) 3
当 key 存在时,将返回哈希表中域的数量。 当 key 不存在时,返回 0 。
HDEL
有添加就必定有删除的需求,当我们想要删除哈希表 key 中的一个或多个指定域时,可以使用HDEL命令,基本语法:
HDEL key field [field ...]
示例 - 删除键people中的jack域。
如果是不存在的域,那么它将被忽略掉。
- redis> HDEL people jack
- (integer) 1
简介
Redis 列表是简单的字符串列表,按照插入顺序排序。
你可以添加一个元素导列表的头部(左边)或者尾部(右边) LPUSH 命令插入一个新的元素导头部, 而RPUSH插入一个新元素导尾部.当一个这两个操作在一个空的Key上被执行的时候一个新的列表被创建。相似的,如果一个列表操作清空一个列表那么对应的key将被从key空间删除。这是非常方便的语义,因为他们被调用使用一个空列表完全就像他们被调用时使用一个不存在的键值(可以)做为参数。
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。 从时间复杂度的角度来看 Redis 列表的主要特征是在头和尾的元素插入和删除是固定时间,即便是数以百万计的插入。. 在列表的两端访问元素是非常快的但是如果你试着访问一个非常大的列表的中间的元素是很慢的,因为那是一个O(N)操作。 你可以用 Redis 列表做很多有趣的事情,比如你可以:
- 在一个社交网络中建立一个时间线模型,使用 LPUSH 去添加新的元素到用户的时间线, 使用 LRANGE 去接收一些
- 最近插入的元素。
- 你可以将 LPUSH 和 LTRIM 一起用去创建一个永远也不会超过指定元素数目的列表,但是记住是最后的N个元素。
- 列表能够被用来作为消息传递primitive。
LPUSH
LPUSH的作用是将一个或多个值 value 插入到列表 key 的表头,基本语法:
LPUSH key value [value ...]
示例:将Tony添加到朋友列表。
- redis> LPUSH friends Tony
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头,比如说,对空列表 mylist 执行命令
LPUSH mylist a b c ,列表的值将是 c b a 。
如果 key 不存在,一个空列表会被创建并执行LPUSH操作。
执行成功时,返回列表长度,当 key 存在但不是列表类型时,返回一个错误。
LSET
LSET可以将列表 key 下标为index的元素的值设置为 value ,基本语法:
LSET key index value
示例
- redis>LSET friends 0 Lucy
- ok
需要注意的是,列表 key 必须是已存在的,而且index不能超出列表长度范围。
LPOP
LPOP命令执行时会移除列表第一个元素,并将其返回,基本语法:
LPOP key
示例 - 取出friends中的第一个元素。
请注意, LPOP 命令会移除列表中的元素,如果仅仅是想要获取该元素,那么就不应该使用 LPOP 操作,因为redis中有专门获取
- redis>LPOP friends
- Lucy
LINDEX
如果要获取列表元素,LINDEX命令是比较常用的,使用LINDEX,我们可以获取到指定位置的 value ,基本语法:
LINDEX key index
示例 - 获取friends的第一个元素。
- redis>LINDEX friends 0
- Tony
下标 (index)为正数时,0表示第一个元素,1表示第二个元素,以此类推。
下标 可以是负数,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
插入元素
插入元素是一个必要功能,LINSERT可以将值 value 插入到列表 key 当中,位于值 pivot 之前或之后,基本语法:
LINSERT key BEFORE|AFTER pivot value
示例 - 将Andy插入到Lucy之前。
- redis> LINSERT friends BEFORE "Lucy" "Andy"
- (integer) 3
当 pivot 不存在于列表 key 时,不执行任何操作。
当 key 不存在时, key 被视为空列表,不执行任何操作。
如果 key 不是列表类型,返回一个错误。
LREM
在redis中,移除列表元素使用LREM命令,根据参数 count 的值,移除列表中与参数value 相等的元素,基本语法:
LREM key count value
示例 - 移除friends中,所有的名叫‘Tom’的元素。
count 的值可以是以下几种:
- redis> LREM friends 0 Tom
- (integer) 1
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
- count = 0 : 移除表中所有与 value 相等的值。
LLEN
现在friends列表中记载着我所有朋友的名字,可是要怎样才能知道我现在拥有多少个朋友呢?
在redis中,LLEN命令可以获取到列表的长度,基本语法:
LLEN key
示例 - 查看myList列表长度。
- redis> LLEN mylist
- (integer) 0
返回列表 key 的长度。
如果 key 不存在,则 key 被解释为一个空列表,返回 0 。
如果 key 不是列表类型,返回一个错误。
LTRIM
LTRIM可以对一个列表进行修剪,就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除,基本语法:
LTRIM key start stop
示例 - 只保留列表 list 的前三个元素,其余元素全部删除。
- LTRIM list 0 2
下标(index)参数start和stop都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
集合
Redis 集合(Set)是一个无序的字符串集合. 你可以快速的完成添加、删除、以及测试元素是否存在。
Redis 集合拥有令人满意的不允许包含相同成员的属性。多次添加相同的元素,最终在集合里只会有一个元素。 实际上说这些就
是意味着在添加元素的时候无须检测元素是否存在。 一个Redis集合的非常有趣的事情是他支持一些服务端的命令从现有的集合出
发去进行集合运算,因此你可以在非常短的时间内进行合并(unions), 求交集(intersections),求差集(differences of sets)。
我们可以使用集合做很多有趣的事情,比如:
- 使用集合追踪一件(独一无二的)事情,比如想要知道所有访问一个博客文章的独立IP? 每次当你处理一个页面访问时非
- 常简单,因为可以肯定重复的IP是不会被插入的。
- Redis 集合是很擅长表现关系的。你可以使用Redis集合创建一个tagging系统去表现每一个tag。接下来你能够使用SADD
- 命令将有一个给定tag的所有对象的所有ID添加到一个用来展现这个特定tag的集合里。你想要同时有三个不同tag的所有
- 对象的ID吗?使用SINTER就好了。
- 使用 SPOP 或者 SRANDMEMBER 命令你可以使用集合去随意的抽取元素。
- 查看 完整的集合命令列表 以获得更多的信息。
添加
集合操作中,SADD命令可以将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略,
基本语法:
SADD key member [member ...]
示例 - 添加‘tom’到room集合中。
- redis> SADD room "tom"
- (integer) 1
假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
当 key 不是集合类型时,返回一个错误。
SPOP
如果我们需要随机取出集合中的某个元素,可以使用SPOP命令,基本语法:
SPOP key
示例:随机取出website集合中的元素。
需要注意的是,执行 SPOP 命令返回的元素将被 移除 该集合。
- redis> SPOP website
- "hubwiz.com"
SMEMBERS
如果要获取集合中全部的元素,则需要使用SMEMBERS命令,基本语法如下:
SMEMBERS key
示例 - 获取website集合中全部的元素。
- redis> SMEMBERS 获取website集合中全部的元素
- 1) "www.hubwiz.com"
- 2) "lab123.hubwiz.com"
SMEMBERS命令只会返回集合中的全部成员,并不会移除它们,如果集合不存在,则视为空集合。
SCARD
如果想要查看集合中元素的数量,可以使用SCARD命令,基本语法:
SCARD key
示例 - 查看website集合中元素的数量。
执行 SCARD 命令,当集合存在时,返回集合中元素的数量,若集合不存在,则返回0。
- redis>SCARD website
- (integer) 3
SDIFF
假如现在有两个集合,我们想要获取到它们之间不同的元素,通常情况下,我们需要通过循环集合来比较,然后取得不同的元素。
在redis里面取得集合的差集非常简单,通过SDIFF命令即可轻松实现,基本语法:
SDIFF key [key ...]
示例 - 取得mySet1和mySet2的差集。
- redis> SMEMBERS mySet1
- 1) "bet man"
- 2) "start war"
- 3) "2012"
- redis> SMEMBERS mySet2
- 1) "hi, lady"
- 2) "Fast Five"
- 3) "2012"
- redis> SDIFF mySet1 mySet2
- 1) "bet man"
- 2) "start war"
如果 key 都存在,则返回一个集合的全部成员,该集合是所有给定集合之间的差集。
不存在的 key 被视为空集。
SINTER
redis 中获取集合的交集也是非常简单的,执行SINTER命令将返回集合的交集,基本语法:
SINTER key [key ...]
示例 - 获取集合group1和group2的交集。
- redis> SMEMBERS group1
- 1) "LI LEI"
- 2) "TOM"
- 3) "JACK"
- redis> SMEMBERS group2
- 1) "HAN MEIMEI"
- 2) "JACK"
- redis> SINTER group1 group2
- 1) "JACK"
当集合都存在时,将返回一个集合的全部成员,该集合是所有给定集合的交集。
不存在的集合被视为空集。因此,当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
SUNION
既然有差集和交集运算,当然少不了并集,在 redis 中,执行SUNION命令将返回给定集合的并集,基本语法:
SUNION key [key ...]
示例:获取集合songs和my_songs的并集。
- redis> SMEMBERS songs和
- 1) "Billie Jean"
- redis> SMEMBERS my_songs
- 1) "Believe Me"
- redis> SUNION songs my_songs
- 1) "Billie Jean"
- 2) "Believe Me"
如果给定的集合都存在,则返回一个集合的全部成员,该集合是所有给定集合的并集。
同样,不存在的集合被视为空集。
SISMEMBER
如果要判断集合是否包含某个元素也不需要循环对比了,因为 redis 提供SISMEMBER命令可以实现这个功能,基本语法:
SISMEMBER key member
示例 - 判断 member 元素是否集合 key 的成员。
- redis> SMEMBERS website
- 1) "hubwiz.com"
- 2) "google.com"
- 3) "baidu.com"
- redis> SISMEMBER website "hubwiz.com"
- (integer) 1
如果集合包含给定的元素,则返回1,反之则返回0。
SMOVE
执行SMOVE可以移动元素,基本语法:
SMOVE source destination member
将 member 元素从 source 集合移动到 destination 集合。SMOVE是原子性操作,因此可以保证数据的一致性。
示例 - 将songs集合中的歌曲‘Believe Me’移动到‘my_songs’集合。
- redis> SMEMBERS songs
- 1) "Billie Jean"
- 2) "Believe Me"
- redis> SMEMBERS my_songs
- (empty list or set)
- redis> SMOVE songs my_songs "Believe Me"
- (integer) 1
- redis> SMEMBERS songs
- 1) "Billie Jean"
- redis> SMEMBERS my_songs
- 1) "Believe Me"
如果 source 集合不存在或不包含指定的 member 元素,则SMOVE命令不执行任何操作,仅返回 0 。否则, member 元素
source 集合中被移除,并添加到 destination 集合中去。
当 destination 集合已经包含 member 元素时,SMOVE命令只是简单地将 source 集合中的 member 元素删除。
当 source 或 destination 不是集合类型时,返回一个错误。
SREM
执行命令SREM可以将元素从集合中移除,基本语法:
SREM key member [member ...]
示例 - 从languages集合中移除ruby。
- redis> SMEMBERS languages # 测试数据
- 1) "c"
- 2) "lisp"
- 3) "python"
- 4) "ruby"
- redis> SREM languages ruby # 移除单个元素
- (integer) 1
移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
当 key 不是集合类型,返回一个错误。
zset
Redis 有序集合与普通集合非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分,
这个评分被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但评分可以重复。
使用有序集合你可以以非常快的速度 添加 、 删除 和 更新 元素。因为元素是有序的, 所以你也可以很快的根据评分(score)或
者次序(position)来获取一个范围的元素。
访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。在有序集合中,你可以很快
捷的访问一切你需要的东西:有序的元素,快速的存在性测试,快速访问集合的中间元素! 简而言之使用有序集合你可以做完成
许多对性能有极端要求的任务,而那些任务使用其他类型的数据库真的是很难完成的。 使用有序集合你可以:
- 在一个大型的在线游戏中展示一个排行榜,在那里一旦一个新的分数被提交,你可以使用ZADD命令去更新它.你也可用使
- 用ZRANGE命令来得到顶级的用户,你还可以使用ZRANK命令根据用户名返回该用户在排行榜中的位次。同时使用ZRANK和
- ZRANGE你可以显示和给定用户分数相同的所有用户。所有这些操作都非常的快速。
- 有序集合常常被用来索引存储在 Redis 中的数据。举个例子,如果你有许多的哈希 (Hashes)来代表用户,你可以使用
- 一个有序集合,这个集合中的元素的年龄字段被用来当做评分,而ID作为值。因此,使用ZRANGEBYSCORE命令,那是微不
- 足道的并且能够很快的接收到给定年龄段的所有用户。
- 有序集合或许是最高级的Redis数据类型,
ZADD
在redis中,使用ZADD命令将一个或多个 member 元素及其 score 值加入到有序集 key 当中,基本语法:
ZADD key score member [[score member] [score member] ...]
示例 - 添加google.com到rank集合,评分5。
- # 添加单个元素
- redis> ZADD rank 10 google.com
- (integer) 1
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该
member 在正确的位置上。
score 值可以是整数值或双精度浮点数。
如果 key 不存在,则创建一个空的有序集并执行ZADD操作。
当 key 存在但不是有序集类型时,返回一个错误。
ZREM
ZREM命令可以移除指定成员,基本语法如下:
ZREM key member [member ...]
示例 - 移除rank集合中google.com元素。
- redis> ZREM rank google.com
执行成功,google.com元素将从rank集合中移除,如果google.com不存在,将被忽略。
如果 rank 集合存在但不是有序集类型时,返回一个错误。
ZSCORE
redis中使用ZSCORE命令来获取成员评分,基本语法:
ZSCORE key member
示例 - 获取集合salary中元素peter的评分。
- redis> ZSCORE salary peter # 注意返回值是字符串
如果 peter 是集合 salary 的成员,则返回成员 peter 的评分值。
如果 peter 元素不是有序集 salary 的成员,或 salary 不存在,则返回 nil 。
ZRANGE
如果想要获取集合成员,可以使用ZRANGE命令,基本语法:
ZRANGE key start stop [WITHSCORES]
示例 - 获取salary集合的全部成员。
- redis > ZRANGE salary 0 -1 WITHSCORES 大写 # 显示整个有序集成员
- 1) "jack"
- 2) "3500"
- 3) "tom"
- 4) "5000"
- 5) "boss"
- 6) "10086"
返回的成员的位置按 score 值递增(从小到大)来排序。
ZCARD
如果需要查看集合成员的数量,那么我们需要使用到ZCARD命令,基本语法如下:
ZCARD key
示例 - 查看salary集合的成员数量。
- redis > ZCARD salary
- (integer) 2
执行成功,将返回有序集 salary 的成员总数。
ZCOUNT
除了ZCARD命令以外,ZCOUNT命令也可以查看成员的数量,和前者不同的是,ZCOUNT命令可以设定评分的最小和最大值:
ZCOUNT key min max
示例 - 查看薪水在2000-5000之间的人数。
- redis> ZRANGE salary 0 -1 WITHSCORES # 测试数据
- 1) "jack"
- 2) "2000"
- 3) "peter"
- 4) "3500"
- 5) "tom"
- 6) "5000"
- redis> ZCOUNT salary 2000 5000
- (integer) 3
执行成功,将返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。
ZRANK
ZRANK命令可以获取到给定元素在集合中的排名,排名依据 评分(score) 值递增(从小到大)顺序排列,语法格式:
ZRANK key member
示例 - 显示 tom 的薪水排名。
- redis> ZRANGE salary 0 -1 WITHSCORES # 显示所有成员及其 score 值
- 1) "peter"
- 2) "3500"
- 3) "tom"
- 4) "4000"
- 5) "jack"
- 6) "5000"
- redis> ZRANK salary tom
- (integer) 1
排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
使用 ZREVRANK 命令可以获得成员按 score 值递减(从大到小)排列的排名。
ZINCRBY
ZINCRBY命令可以为给定的成员评分值加上增量,语法格式:
ZINCRBY key increment member
示例 - 为salary集合中的tom加薪500。
- redis> ZSCORE salary tom
- "2000"
- redis> ZINCRBY salary 500 tom # tom 加薪啦!
- "2500"
可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
当 key 不是有序集类型时,返回一个错误。
score 值可以是整数值或双精度浮点数。
KEYS
Redis 的keys命令用于管理键。使用 Redis 的keys命令,语法格式:
KEYS pattern
查找所有符合给定模式 pattern 的 key 。
示例 - 查找包含o的键。
- redis> MSET one 1 two 2 three 3 four 4 # 一次设置 4 个 key
- OK
- redis> KEYS *o*
- 1) "four"
- 2) "two"
- 3) "one"
KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
特殊符号用 \ 隔开。
EXISTS
EXISTS命令的作用是判断指定key是否存在,语法格式如下:
EXISTS key
示例 - 判断db是否存在。
- redis> SET db "redis"
- OK
- redis> EXISTS db
- (integer) 1
- redis> DEL db
- (integer) 1
- redis> EXISTS db
- (integer) 0
若 key 存在,返回 1 ,否则返回 0 。
RENAME
RENAME命令可以将原有的 key 修改为新的key名称,语法如下:
RENAME key newkey
示例 - 重名message。
- redis> SET message "hello world"
- OK
- redis> RENAME message greeting
- OK
- redis> EXISTS message # message 不复存在
- (integer) 0
- redis> EXISTS greeting # greeting 取而代之
- (integer) 1
当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。
当 newkey 已经存在时, RENAME 命令将覆盖旧值。
SORT
排序是很常见的需求,在 redis 中可以使用SORT命令来实现排序,语法格式如下:
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
示例
- # 开销金额列表
- redis> LPUSH cost 30 1.5 10 8
- (integer) 4
- # 排序
- redis> SORT cost
- 1) "1.5"
- 2) "8"
- 3) "10"
- 4) "30"
使用SORT命令,可以返回或保存给定列表、集合、有序集合 key 中经过排序的元素。
排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。
DUMP
redis 支持序列化,使用DUMP命令来序列化给定key的值,语法如下:
DUMP key
示例 - 序列化say。
- redis> SET say "hello world!"
- OK
- redis> DUMP say
- "\x00\x15hello world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
- redis> DUMP not-exists-key
- (nil)
执行DUMP命令序列化成功后,将返回被序列化的值,若key不存在,则返回 nil 。
EXPIRE
为key设置生存时间需要使用EXPIRE命令,语法格式:
EXPIRE key seconds
示例 - 设置rank的过期时间为30秒。
- redis> EXPIRE rank 30 # 设置过期时间为 30 秒
- (integer) 1
为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
在 Redis 中,带有生存时间的 key 被称为『易失的』(volatile)。
生存时间可以通过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆写(overwrite),这意味着,如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话,那么生存时间不会被改变。
TTL
TTL命令的作用是获取给定 key 剩余生存时间(TTL, time to live),语法格式如下:
TTL key
示例 - 查看key剩余生存时间。
- # 有剩余生存时间的 key
- redis> EXPIRE key 10086
- (integer) 1
- redis> TTL key
- (integer) 10084
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。