技术开发 频道

NoSQL初学者:15分钟学会Redis数据结构

  Redis lists入门

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

  $ redis-cli rpush messages "Hello how are you?"

  OK

  $ redis
-cli rpush messages "Fine thanks. I‘m having fun with Redis"

  OK

  $ redis
-cli rpush messages "I should look into this NOSQL thing ASAP"

  OK

  $ redis
-cli lrange messages 0 2

  
1. Hello how are you?

  
2. Fine thanks. I‘m having fun with Redis

  
3. I should look into this NOSQL thing ASAP

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

  As you can guess from the example above, lists can be used, for instance, in order to implement a chat system. Another use is as queues in order to route messages between different processes. But the key point is that you can use Redis lists every time you require to access data in the same order they are added. This will not require any SQL ORDER BY operation, will be very fast, and will scale to millions of elements even with a toy Linux box.

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

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

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

  向Redis list压入ID而不是实际的数据

  在上面的例子里 ,我们将“对象”(此例中是简单消息)直接压入Redis list,但通常不应这么做,由于对象可能被多次引用:例如在一个list中维护其时间顺序,在一个集合中保存它的类别,只要有必要,它还会出现在其他list中,等等。

  让我们回到reddit.com的例子,将用户提交的链接(新闻)添加到list中,有更可靠的方法如下所示:

  $ redis-cli incr next.news.id

  (
integer) 1

  $ redis
-cli set news:1:title "Redis is simple"

  OK

  $ redis
-cli set news:1:url "http://code.google.com/p/redis"

  OK

  $ redis
-cli lpush submitted.news 1

  OK

  我们自增一个key,很容易得到一个少有的自增ID,然后通过此ID创建对象–为对象的每个字段设置一个key。最后将新对象的ID压入submitted.news list。

  这只是牛刀小试。在命令参考文档中可以读到所有和list有关的命令。你可以删除元素,旋转list,根据索引获取和设置元素,当然也可以用LLEN得到list的长度。

  Redis集合

  Redis集合是未排序的集合,其元素是二进制安全的字符串。SADD命令可以向集合添加一个新元素。和sets相关的操作也有许多,比如检测某个元素是否存在,以及实现交集,并集,差集等等。一例胜千言:

  $ redis-cli sadd myset 1

  (
integer) 1

  $ redis
-cli sadd myset 2

  (
integer) 1

  $ redis
-cli sadd myset 3

  (
integer) 1

  $ redis
-cli smembers myset

  
1. 3

  
2. 1

  
3. 2

  我向集合中添加了三个元素,并让Redis返回所有元素。如你所见它们是无序的。

  现在让我们检查某个元素是否存在:

  $ redis-cli sismember myset 3

  (
integer) 1

  $ redis
-cli sismember myset 30

  (
integer) 0

  “3″是这个集合的成员,而“30”不是。集合特别适合表现对象之间的关系。例如用Redis集合可以很容易实现标签功能。

  下面是一个简单的方案:对每个想加标签的对象,用一个标签ID集合与之关联,并且对每个已有的标签,一组对象ID与之关联。

  例如假设我们的新闻ID 1000被加了三个标签tag 1,2,5和77,就可以设置下面两个集合:

  $ redis-cli sadd news:1000:tags 1

  (
integer) 1

  $ redis
-cli sadd news:1000:tags 2

  (
integer) 1

  $ redis
-cli sadd news:1000:tags 5

  (
integer) 1

  $ redis
-cli sadd news:1000:tags 77

  (
integer) 1

  $ redis
-cli sadd tag:1:objects 1000

  (
integer) 1

  $ redis
-cli sadd tag:2:objects 1000

  (
integer) 1

  $ redis
-cli sadd tag:5:objects 1000

  (
integer) 1

  $ redis
-cli sadd tag:77:objects 1000

  (
integer) 1

  要获取一个对象的所有标签,如此简单:

  $ redis-cli smembers news:1000:tags

  
1. 5

  
2. 1

  
3. 77

  
4. 2

  而有些看上去并不简单的操作仍然能使用相应的Redis命令轻松实现。例如我们也许想获得一份同时拥有标签1, 2, 10和27的对象列表。这可以用SINTER命令来做,他可以在不同集合之间取出交集。因此为达目的我们只需:

  $ redis-cli sinter tag:1:objects tag:2:objects tag:10:objects tag:27:objects

  ... no result
in our dataset composed of just one object ;) ...

  在命令参考文档中可以找到和集合相关的其他命令,令人感兴趣的一抓一大把。一定要留意SORT命令,Redis集合和list都是可排序的。

0
相关文章