本文译自 Redis tutorial
欢迎来到Try Redis,这是一个Redis数据库的示范!
Redis是一个通常被叫做键值存储(key-value store)的NoSQL数据库。键值存储的本质是在一个键(key)中保存某种被叫做值的数据。一个数据,只有当我们知道用于保存它的那个确切的键时,我们才能检索它。我们能用SET命令把值“fido”保存到一个被称为“server:name”的键中:
SET server:name "fido"
Redis将持久的保存我们的数据,我们可以在之后询问“键server:name中保存的值是什么”,Redis将回答是“fido”:
GET server:name //返回 "fido"
其他由键值存储提供的常用操作有:删除一个给定的键和它关联的值的DEL,仅在键还不存在时才设置它的SET-if-not-exists(在Redis中叫SETNX),和自动把一个给定键中的值增加一个数的INCR:
SET connections 10
INCR connections //返回 11
INCR connections //返回 12
DEL connections
INCR connections //返回 1
INCR有一些特别。为什么要提供一个“就像下面这样,用一点代码就能自己做”的操作呢?:
x = GET count
x = x + 1
SET count x
问题在于,这样的增加方式仅在单独客户使用该键时才能工作。看看如果有两个客户同时访问该键时会怎样:
客户A读出count的值10。
客户B读出count的值10。
客户A为值10做增加,把count设置成11。
客户B为值10做增加,把count设置成11。
我们希望值是12,但它实际上是11!这是因为以这种方式增加值不是一个原子性的操作。在Redis中调用INCR可以防止这种情况的发生,因为它是一个原子性的操作。Redis在不同的数据类型上提供很多这类原子性操作。
可以告诉Redis:一个键仅应该在一个特定的时间长度中存在。这用EXPIRE和TTL命令来实现。
SET resource:lock "Redis Demo"
EXPIRE resource:lock 120
这导致键resource:lock在120秒之后被删除。您可以用TTL命令测试一个键还能存在多久。它返回键被删除之前还剩的秒数:
TTL resource:lock //返回 113,也就是键还能再存在113秒
TTL resource:lock //返回 -2
键的TTL返回值是-2的意思是该键已经不存在。键的TTL返回值是-1指示该键永远不会过期。注意,如果您SET一个键,它的TTL就将被重置。
SET resource:lock "Redis Demo 1"
EXPIRE resource:lock 120
TTL resource:lock //返回 119
SET resource:lock "Redis Demo 2"
TTL resource:lock //返回 -1
Redis也支持几种更复杂的数据结构。我们首先看列表(list)。一个列表是一系列有序的值。与列表交互的一些最重要命令是RPUSH、LPUSH、LLEN、LRANGE、LPOP、和RPOP。您可以立刻把一个键当成一个列表来开始工作,只要它还没有以另一种类型存在。
RPUSH把新值放到列表的末尾。
RPUSH friends "Alice"
RPUSH friends "Bob"
LPUSH把新值放到列表的开头。
LPUSH friends "Sam"
LRANGE给出一个列表的子集。它把您希望检索的首个元素的索引作为首个参数,和把您希望提取的最后一个元素的索引作为它的第二个参数给出。把-1作为第二个参数的意思是“提取元素,直到列表的末尾”。
LRANGE friends 0 -1 //依序返回 "Sam", "Alice", "Bob"
LRANGE friends 0 1 //依序返回 "Sam", "Alice"
LRANGE friends 1 2 //依序返回 "Alice", "Bob"
LLEN返回列表的当前长度。
LLEN friends //返回 3
LPOP移除列表的首个元素,并返回它。
LPOP friends //返回 "Sam"
RPOP移除列表的最后一个元素,并返回它。
RPOP friends //返回 "Bob"
注意,此时列表就只有一个元素了:
LLEN friends //返回 1
LRANGE friends 0 -1 //仅返回一个 "Alice"
接下来我们要看的数据结构是集合(set)。集合类似于列表,但它没有特定的顺序,且每个元素都只能出现一次。在集合上工作的一些重要命令是SADD、SREM、SISMEMBER、SMEMBERS、和SUNION。
SADD把给定的值添加到集合。
SADD superpowers "flight"
SADD superpowers "x-ray vision"
SADD superpowers "reflexes"
SREM从集合中移除给定的值。
SREM superpowers "reflexes"
SISMEMBER测试给定的值是否在集合中。如果该值存在就返回1,如果不存在就返回0。
SISMEMBER superpowers "flight" //返回 1
SISMEMBER superpowers "reflexes" //返回 0
SMEMBERS返回集合中所有成员的清单。
SMEMBERS superpowers //依序返回 "flight", "x-ray vision"
SUNION把两个或更多集合合并起来,并返回所有元素的清单。
SADD birdpowers "pecking"
SADD birdpowers "flight"
SUNION superpowers birdpowers //依序返回 "pecking", "x-ray vision", "flight"
集合是非常有用的数据类型,但由于它们是无序的,所以它们在一些程序下工作得不好。因此Redis 1.2引入了有序集合(sorted set)。
有序集合类似于正则集合(regular set),但每个值都有一个与其关联的分数。这个分数被用于对集合中的元素排序。
ZADD hackers 1940 "Alan Kay"
ZADD hackers 1906 "Grace Hopper"
ZADD hackers 1953 "Richard Stallman"
ZADD hackers 1965 "Yukihiro Matsumoto"
ZADD hackers 1916 "Claude Shannon"
ZADD hackers 1969 "Linus Torvalds"
ZADD hackers 1957 "Sophie Wilson"
ZADD hackers 1912 "Alan Turing"
在这个例子中,分数是出生年份,值是著名黑客的名字。
ZRANGE hackers 2 4 //依序返回 "Claude Shannon", "Alan Kay", "Richard Stallman"
简单字符串、集合、和有序集合已经能做很多事情,但Redis还能处理另一种数据类型:哈希(hash)。
哈希是字符串域和字符串值之间的映射,因此它们是表示对象的出色数据类型(例如:一个具有诸如名字、姓、年龄等一系列域的用户):
HSET user:1000 name "John Smith"
HSET user:1000 email "john.smith@example.com"
HSET user:1000 password "s3cret"
要取回被保存的数据,就用HGETALL:
HGETALL user:1000
您也可以一次性的设置多个域:
HMSET user:1001 name "Mary Jones" password "hidden" email "mjones@example.com"
如果您只需要一个域的值,这也是可能的:
HGET user:1001 name //返回 "Mary Jones"
如同处理简单字符串一样,哈希域中的数字值也能以同样的方式被处理,有原子性的增加这种值的操作:
HSET user:1000 visits 10
HINCRBY user:1000 visits 1 //返回 11
HINCRBY user:1000 visits 10 //返回 21
HDEL user:1000 visits
HINCRBY user:1000 visits 1 //返回 1
检查哈希命令的完整列表,以了解更多信息。
根据下面的链接继续学习Redis。
Redis Documentation(http://redis.io/documentation)
Command Reference(http://redis.io/commands)
Implement a Twitter Clone in Redis(http://redis.io/topics/twitter-clone)
Introduction to Redis Data Types(http://redis.io/topics/data-types-intro)