ITKeyword,专注技术干货聚合推荐

注册 | 登录

redis: sorted set数据类型与操作

shamohua 2011-11-28

相关推荐:NoSQL之Redis对set(集合)数据类型的操作之二

7.sinter setkey1 setkey2 setkey3...:返回setkey1和setkey2的交集 127.0.0.1:6379> smembers setkey1 1) "world" 2) "hello" 3) "2000" 127.0.0.1:6379> smemb

    redis支持有序集合,即sorted sets数据类型。基本格式为:

key --> member -- score

    |  --> member -- score


    sorted set类型的实现采用了两个数据结构:hash table 和 skip list(跳跃表),其中hash table是具体使用redis中的dict来实现的,主要是为了保证查询效率为O(1) ,而skip list(跳跃表)主要是保证元素有序并能够保证INSERT和REMOVE操作是O(logn)的复杂度。


    sorted set的基本操作详见:http://redis.readthedocs.org/en/2.4/sorted_set.html

    利用redis c++接口,验证zset的基本操作:

#include "redisclient.h"

#include "tests/functions.h"

#include <iostream>

#include <boost/date_time.hpp>

#define OUT(x) std::cout<<#x<<" = "<<x<<std::endl;

boost::shared_ptr<redis::client> init_non_cluster_client();

void output_set(redis::client::string_set & sset);
void output_sort_set(redis::client & c, std::string & key);

void test_sorted_set(redis::client & c);

int main(int argv, char* argc[]) 
{
	boost::shared_ptr<redis::client> shared_c;

	shared_c = init_non_cluster_client();

	redis::client& c = *shared_c;

	test_sorted_set(c);

	return 0;
}

void test_sorted_set(redis::client & c)
{
	test("test sorted set:");

	std::string key = "page_rank";
	test("zadd");
	{
		c.zadd(key, 10, "taobao.com");
		c.zadd(key, 9, "tmall.com");
		c.zadd(key, make_pair("tmall.com", 11.1) );
		output_sort_set(c, key);
	}
	
	test("zrem");
	{
		c.zrem(key, "taobao.com");
		output_sort_set(c, key);
	}

	test("zcount");
	{
		OUT(c.zcount(key, 0, 5));
		c.zadd(key, 3.6, "etao.com");
		OUT(c.zcount(key, 0, 5));
	}

	test("zincrby");
	{
		c.zincrby(key,"etao.com", 3);
		c.zincrby(key,"koubei.com", 5);
		output_sort_set(c, key);
	}

	test("zrevrange");
	{
		redis::client::string_vector out;
		c.zrevrange(key, 0, -1, out);
		for(size_t i=0; i<out.size(); ++i) {
			OUT(out[i]);
		}
	}

	test("zrangebyscore");
	{
		redis::client::string_score_vector out;
		c.zrangebyscore(key, 0, 20, out, 0, 2);
		for(size_t i=0; i<out.size(); i++) {
			OUT(out[i].first);
			OUT(out[i].second);
		}
	}

	test("zrank & zrevrank");
	{
		OUT(c.zrank(key, "etao.com"));
		OUT(c.zrevrank(key, "etao.com"));
	}

	test("zremrangebyrank & zremrangebyscore");
	{
		c.zremrangebyrank(key, 0, 0);
		c.zremrangebyscore(key, 0, 10);
		output_sort_set(c, key);
	}

	test("zinterstore & zunionstore");
	{
		c.zadd("website", 10, "taobao.com");
		c.zadd("website", 8, "google.com");
		c.zadd("website", 0, "baidu.com");
		c.zadd("website", 7, "tmall.com");

		redis::client::string_vector keys;
		keys.push_back(key);
		keys.push_back("website");
	
		std::string sinter("inter");
		std::string sunion("union");
		c.zinterstore(sinter, keys);
		c.zunionstore(sunion, keys);

		std::cout<<"inter :"<<std::endl;
		output_sort_set(c, sinter);
		std::cout<<"union :"<<std::endl;
		output_sort_set(c, sunion);
	}
}

void output_sort_set(redis::client & c, std::string & key)
{
	OUT( c.zcard(key) );
	redis::client::string_vector out;
	c.zrange(key, 0, -1, out);
	for(size_t i=0; i<out.size(); ++i) {
		OUT(out[i]);
		OUT( c.zscore(key, out[i]) );
	}
}

PS:

redis c++接口在实现zset操作时,有两个小bug:

相关推荐:Redis学习手册(Set数据类型)

一、概述:       在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存

1. void recv_int_ok_reply_(int socket)

原来实现,当recv_int_reply_(socket) != 1时,就认为有错误,从而抛出异常:throw protocol_error("expecting int reply of 1");

但实际上,如zadd操作:

如果某个member已经是有序集的成员,那么更新这个member的score值,并通过重新插入这个member元素,来保证该member在正确的位置上,并返回0; add成功返回1;如果key不存在,则创建一个空的有序集并执行zadd操作;当key存在但不是有序集类型时,返回一个错误。

修改:

    void recv_int_ok_reply_(int socket)
    {    
      if (recv_int_reply_(socket) < 0) 
        throw protocol_error("expecting int reply of <0");
    } 

2.  void zrangebyscore(const string_type & key, double min, double max, string_score_vector & out, int_type offset = 0, int_type      max_count = -1, int range_modification = 0)

调用,zrangebyscore_base(true, key, min, max, res, offset, max_count, range_modification);

第一个参数值等于true表明,需要返回score值。但是,zrangebyscore_base在实现时并未考虑这一参数。

修改:在zrangebyscore_base函数实现时,加上

      if(withscores) {
        m << "WITHSCORES";
      }


相关推荐:Redis数据类型之SET类型

Web程序猿博客:http://blog.csdn.net/thinkercode set类型-特点 set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差

    redis支持有序集合,即sorted sets数据类型。基本格式为:key --> member -- score    |  --> member -- score    sorted set类型的实现采用了两个数据结构:hash table 和 skip

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。