redis(jedis)相关API ,实现与关系型数据库相似的功能

本文简单介绍了在使用jedis操作redis这个nosql数据库过程中,总结的一些问题,例如使用jedis实现形如关系型数据库的数据关联关系处理。

分三个层面:

1:单表数据处理,新增一行数据到数据库中,如果存在主键id是自增情况的条件下,如何新增数据集合到数据库行数据;

2:一对多关联关系,本文举例形如---学生&&成绩; 一个学生包含多个学科的成绩,某一个学科的的成绩属于某个学生;

3:多对多关联关系,本文举例例如---文章&&标签; 一篇文章可以添加多个标签,某一个标签可以被包含于多个文章中;

整体代码链接已经上传git,可以在git上查看:

http://git.oschina.net/alexgaoyh/MutiModule-parent/blob/master/MutiModule-service/src/test/java/com/alexgaoyh/MutiModule/service/unJunit/redis/test2/TestCase.java

1:单表数据处理

/**
	 * [向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的长度。

	 *
	 * 形如关系型数据库的单表一行数据(主键id为自增)
	 * 自定义一个自增的id ,	jedis.incr(key),这个key可以形如mysql这种关系型数据库的自增主键id
	 * 形如关系型数据库的一行数据,自增主键id:jedis.incr(key) 他对应的数据内容:jedis.get("ad:adinfo:" + adInfoId + ":title") jedis.get("ad:adinfo:" + adInfoId + ":url")
	 * 这样,在查询这张‘表’结构下的所有数据时,可以匹配查询即可
	 */
	public static void testListStrUsage() {
		String title = "alexgaoyh";
		String url = "http://git.oschina.net/alexgaoyh";
		Jedis jedis = RedisUtil.getJedis(IP, PORT);

		long adInfoId = jedis.incr("ad:adinfo:next.id");
		jedis.set("ad:adinfo:" + adInfoId + ":title", title);
		jedis.set("ad:adinfo:" + adInfoId + ":url", url);
		jedis.lpush("ad:adinfo", String.valueOf(adInfoId));

		String resultTitle = jedis.get("ad:adinfo:" + adInfoId + ":title");
		String resultUrl = jedis.get("ad:adinfo:" + adInfoId + ":url");
		List<String> ids = jedis.lrange("ad:adinfo", 0, -1);
		System.out.println(resultTitle);
		System.out.println(resultUrl);
		System.out.println(ids);

		/**
		 * dbsize返回的是所有key的数目,包括已经过期的, 而redis-cli keys "*"查询得到的是有效的key数目
		 */
		System.out.println(jedis.dbSize());

		//清空所有的key
		jedis.flushAll();
	}

2:一对多关联关系

/**
	 * sort list
	 * LIST结合hash的排序
	 * 根据指定的SortingParams排序方式,将符合条件的数据格式进行返回
	 * 关联关系处理,
	 * 可以理解为studentlist代表学生的整体数据集合
	 * hset方法,可以将某个学生user:id下的某个域(学科)的成绩(value)进行数据保存
	 * 根据匹配条件,将相对应的成绩进行输出
	 */
	public static void testSort2() {
		Jedis jedis = RedisUtil.getJedis(IP, PORT);
		jedis.del("user:66", "user:55", "user:33", "user:22", "user:11", "userlist");
		jedis.lpush("studentlist", "33");
		jedis.lpush("studentlist", "22");
		jedis.lpush("studentlist", "55");
		jedis.lpush("studentlist", "11");

		//将哈希表 key 中的域 field 的值设为 value 。 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。 如果域 field 已经存在于哈希表中,旧值将被覆盖。
		jedis.hset("user:66", "math", "66");
		jedis.hset("user:55", "math", "55");
		jedis.hset("user:33", "math", "33");
		jedis.hset("user:22", "math", "22");
		jedis.hset("user:11", "math", "11");//学生user:编号,在field域(某个学科-数学/英语)上的成绩(value)
		jedis.hset("user:11", "english", "110");
		jedis.hset("user:22", "english", "220");
		jedis.hset("user:33", "english", "330");
		jedis.hset("user:55", "english", "550");
		jedis.hset("user:66", "english", "660");

		SortingParams sortingParameters = new SortingParams();
		// 符号 "->" 用于分割哈希表的键名(key name)和索引域(hash field),格式为 "key->field" 。
		sortingParameters.desc();
		sortingParameters.get("user:*->math");
		sortingParameters.get("user:*->english");
		List<String> result = jedis.sort("studentlist", sortingParameters);
		for (String item : result) {
			System.out.println("item...." + item);
		}
		/**
		 * 对应的redis客户端命令是:sort ml get user*->name sort ml get user:*->name get
		 * user:*->add
		 */
	}
/**
        * sort set
        * SET结合String的排序
        * REL关系相关处理操作   好友列表 好友信息 好友成绩数据信息添加即相应的数据输出
        * 输出好友id,好友的详细信息,好友的对应成绩
        */
        public static void testSort3() {
              Jedis jedis = RedisUtil. getJedis( IP, PORT);
              jedis.del( "tom:friend:list" , "score:uid:123" , "score:uid:456" ,
                            "score:uid:789" , "score:uid:101" , "uid:123" , "uid:456" ,
                            "uid:789" , "uid:101" );

              jedis.sadd( "tom:friend:list" , "123" ); // tom的好友列表
              jedis.sadd( "tom:friend:list" , "456" );
              jedis.sadd( "tom:friend:list" , "789" );
              jedis.sadd( "tom:friend:list" , "101" );

              jedis.set( "score:uid:123" , "1000" ); // 好友对应的成绩
              jedis.set( "score:uid:456" , "6000" );
              jedis.set( "score:uid:789" , "100" );
              jedis.set( "score:uid:101" , "5999" );

              jedis.set( "uid:123" , "{‘uid‘:123,‘name‘:‘lucy‘}" ); // 好友的详细信息
              jedis.set( "uid:456" , "{‘uid‘:456,‘name‘:‘jack‘}" );
              jedis.set( "uid:789" , "{‘uid‘:789,‘name‘:‘jay‘}" );
              jedis.set( "uid:101" , "{‘uid‘:101,‘name‘:‘jolin‘}" );

              SortingParams sortingParameters = new SortingParams();

              sortingParameters.desc();
               // sortingParameters.limit(0, 2);
               // 注意GET操作是有序的,GET user_name_* GET user_password_*
               // 和 GET user_password_* GET user_name_*返回的结果位置不同
              sortingParameters.get( "#" );// GET 还有一个特殊的规则—— "GET #"
                                                               // ,用于获取被排序对象(tom:friend:list)(我们这里的例子是 user_id )的当前元素。
              sortingParameters.get( "uid:*" );
              sortingParameters.get( "score:uid:*" );
              sortingParameters.by( "score:uid:*" );
               // 对应的 redis 命令是./redis -cli sort tom:friend:list by score:uid:* get # get
               // uid :* get score:uid:*
              List<String> result = jedis.sort( "tom:friend:list" , sortingParameters);
               for (String item : result) {
                     System. out .println("item..." + item);
              }

       }

其中需要注意 sortingParameters.get("#");

GET 还有一个特殊的规则—— "GET #" 用于获取被排序对象(tom:friend:list)(我们这里的例子是 user_id )的当前元素。

3:多对多关联关系

/**
	 * 下面是一个简单的方案:对每个想加标签的对象,用一个标签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都是可排序的。
	 *
	 * 关系型数据库双向关联操作  一个文章对应多个标签,一个标签可以被多个文章关联
	 * 多对多的数据库表结构
	 */

	public static void testSetUsage() {
		Jedis jedis = RedisUtil.getJedis(IP, PORT);

		//某个文章包含的标签
		jedis.sadd("zhongsou:news:1000:tags", "1");
		jedis.sadd("zhongsou:news:1000:tags", "2");
		jedis.sadd("zhongsou:news:1000:tags", "5");
		jedis.sadd("zhongsou:news:1000:tags", "77");
		jedis.sadd("zhongsou:news:2000:tags", "1");
		jedis.sadd("zhongsou:news:2000:tags", "2");
		jedis.sadd("zhongsou:news:2000:tags", "5");
		jedis.sadd("zhongsou:news:2000:tags", "77");
		jedis.sadd("zhongsou:news:3000:tags", "2");
		jedis.sadd("zhongsou:news:4000:tags", "77");
		jedis.sadd("zhongsou:news:5000:tags", "1");
		jedis.sadd("zhongsou:news:6000:tags", "5");

		//某个标签包含的对应的文章id
		jedis.sadd("zhongsou:tag:1:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:2:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:5:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:77:objects", 1000 + "");

		jedis.sadd("zhongsou:tag:1:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:2:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:5:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:77:objects", 2000 + "");

		//返回一个集合的全部成员,该集合是所有给定集合的交集
		//这四个标签全部都被包含的文章id集合
		Set<String> sets = jedis.sinter("zhongsou:tag:1:objects",
				"zhongsou:tag:2:objects", "zhongsou:tag:5:objects",
				"zhongsou:tag:77:objects");
		System.out.println(sets);
		jedis.flushAll();
	}
时间: 2024-10-10 11:48:55

redis(jedis)相关API ,实现与关系型数据库相似的功能的相关文章

spark2.x由浅入深深到底系列六之RDD java api用JdbcRDD读取关系型数据库

学习任何的spark技术之前,请先正确理解spark,可以参考:正确理解spark 以下是用spark RDD java api实现从关系型数据库中读取数据,这里使用的是derby本地数据库,当然可以是mysql或者oracle等关系型数据库: package com.twq.javaapi.java7; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaSparkContext; imp

非关系型数据库之redis

redis是什么? redis是基于内存的非关系型数据库,数据是以key-value的形式来存储的.redis的读写效率非常高,处理并发访问能力很强.主要应用场景是分布式缓存 redis中的key只有string类型.但是value有五种数据类型:字符串string,散列hash,列表list,集合set,有序集合sorted set. redis操作都是原子性的,线程安全,保证数据完整性. 为什么使用redis? 一个Tomcat同一时刻能够处理的请求大约200-300,当同一时刻有多个请求访

非关系型数据库(NoSQL)——Redis安装及部署详解

在现在的互联网大潮中,NoSQL可谓是家喻户晓,Redis作为NoSQL中及其重要的一员,使我们走向架构道路的一条必经之路.作为运维工程师来说,是必须要掌握的! 既然提到了Redis数据库是非关系型数据,并且需要掌握Redis数据库.那么关于关系型数据库与非关系型数据库的基本概念是必须要了解的. 一.关系型数据库与非关系型数据库的基本概念: 数据库按照其结构可以分为关系型数据库与其他数据库,而这些其他数据库,我们统称为非关系型数据库. 1.关系型数据库 关系型数据库是一个结构化的数据库,创建在关

Redis 非关系型数据库 ( Nosql )

简介: Redis 是一个开源的,高性能的 key-value 系统,可以用来缓存或存储数据. Redis 数据可以持久化,并且支持多种数据类型:字符串(string),列表(list),哈希(hash),集合(set)和有序集合(sorted set). 能够对关系型数据库起到很好的补充作用.它还提供了多种客户端 Python .Ruby .Erlang .PHP ,可以方便调用. 持久化: Redis 是一种内存数据库(跟 memcache 类似),在数据存取效率方面很优秀,由于内存中的数据

非关系型数据库Redis学习(1)

NoSQL 泛指非关系型数据库 特点:1.处理超大量的数据 2.运行在便宜的pc服务器集群上  3.击碎了性能的瓶颈 Redis是一个高性能的key-value数据库,存储的value类型包括string字符串.list链表.set(集合).zset(有序集合).数据缓存在内存中,也可以周期性的把更新的数据写入磁盘,或把修改的操作写入追加的记录文件中 Redis使用场合 1. application -> Redis 2. 应用程序直接访问Redis,只有当Redis访问失败时,才访问mysql

python 之操作redis数据库(非关系型数据库,k-v)

数据库: 1. 关系型数据库 表结构 2. 非关系型数据库 nosql (k - v 速度快),常用的时以下三种: memcache 存在内存里 redis 存在内存里 mangodb 数据还是存在磁盘上 Redis里的数据类型有String 和hash类型,下面主要是对Redis 的一些操作. 一.String类型 r = redis.Redis(host='localhost',port=6379,db=3) r.set('nancy2','201801211505') #set数据 pri

redis相对关系型数据库的优势

它是键值数据库(非关系),数据查询比关系型数据库快. ps:redis是树状结构,查询快 redis是基于内存的一个数据库,I/O的效率影响较小. ps: 备份数据同步是才进行I/O操作.这个数据同步是通过异步完成的 1.启动redis server sudo service redis start 停止 sudo service redis stop 重启 sudo service redis restart 2.启动客户端 redis-cli 原文地址:https://www.cnblogs

redis非关系型数据库的基本语法

导入并连接数据库: import redis # 导入redis模块,通过python操作redis 也可以直接在redis主机的服务端操作缓存数据库 import time # host是redis主机,需要redis服务端和客户端都起着 redis默认端口是6379 pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=po

Redis非关系型数据库

关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据.主流的 oracle.DB2.MS SQL Server和mysql都属于这类传统数据库. NoSQL数据库,全称为Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储如KV存储.主要分为临时性键值存储(memcached.Redis).永久性键值存储(ROMA.Redis).面向文档的数据库(Mo