Redis数据库学习简记

============================开题:redis简介============================

       redis是 Nosql数据库中使用较为广泛的 非关系型 内存数据库,redis内部是一个 key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型,类似于Java中的map)。Redis基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为 数据结构服务器。
2、 互联网时代背景下大机遇,什么要使用Nosql?
1) 当数据量的总大小一个机器放不下时。
2) 数据索引一个机器的内存放不下时。

3) 访问量(读写混合)一个实例放不下时。单机时代模型

详见:redis介绍

========================================================================

1.redis安装:下载压缩包,解压,然后cmd终端中进入redis安装根路径

       1.1启动redis服务器:redis-server.exe  【redis.windowws.conf】--【】括号内可以不加

       1.2(需要另打开一个cmd终端)redis客户端链接上数据库: redis-cli.exe  -h  数据库服务IP地址  -p  端口 【-a  password】

           实例:redis-cli.exe  -h  127.0.0.1  -p  6379 

redis服务启动成功:


redis数据库链接成功:

=================================题外话=================================

redis的配置:配置:config set 配置名  配置值  ——  查看配置:config  get  配置名

举例:

127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "notice"

redis安全:设置密码后,客户端连接 redis 服务就需要密码验证,否则无法执行命令。

config set requirepass "pass"

config set requirepass "pass"

验证密码:

AUTH "pass"

======================

其中Redis默认配置文件中提供了三个条件:

    save 900 1 (表示900s(15分钟)内有1个更改,redis服务器就存储到disk硬盘中)

    save 300 10  (300s(5分钟)内有10个更改,redis服务器就存储到disk硬盘中)

    save 60 10000  (60s内有10000个更改,redis服务器就存储到disk硬盘中)

redis的存储在内存中,所以读写很快。但却数据不安全!!的,如果在执行过程中断电,则内存中数据将会丢失!!

所以,redis配置save指令,指定时间内去存储进disk硬盘中。同时redis根目录下创建一个dump.rdb文件

每执行一次save指令,就更新一次(本地硬盘中redis根目录下的)dump.rdb文件.

1.save: 服务端做的硬盘存储

2.bgsave:该命令在后台客户端执行,做硬盘存储。

====>恢复数据

如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。获取 redis 目录可以使用 CONFIG 命令,如下所示

===========================================================================


2.Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

string类型是Redis最基本的数据类型,一个key最大能存储512MB。

增加<==>读取 数据:

String类型: 增加一个:set Key名 value值  —— 取:get key名

                    增加多个:mset  key1 value1 key2 value2   ..............   —— 取:mget  key1  key2  ...........

127.0.0.1:6379> mset "s1" "1" "s2" "2"  "s3" "3"
OK
127.0.0.1:6379> mget s1 s2 s3
1) "1"
2) "2"
3) "3"

====>拓展指令:incr  -- 加1操作

举例:s1:0 —— incr s1 之后 ——>s1:1

127.0.0.1:6379> set s1 0
OK
127.0.0.1:6379> get s1
"0"
127.0.0.1:6379> incr s1
(integer) 1
127.0.0.1:6379> get s1
"1"
127.0.0.1:6379>

hash(哈希)类型:增加一个:hset    key名     value   ——  取:hget     key名

                                增加多个:hmset     key名    value(字段    字段值)

                                                ——  取一个:hget     key名   字段值,取全部:hgetall     key名

                                删除hash中某个字段值:hdel    key名  字段名

                                给hash里某一个字段加上指定值:hincrby   hash名  字段名    指定值 

                                                                                -- 例:hincyby userinfo age 10  (在原来age上追加+10)

举例:userInfo类的属性有:name,age,sex

127.0.0.1:6379> hmset userinfo name "tom" age 12 sex "man"
OK
127.0.0.1:6379> hget userinfo name
"tom"
127.0.0.1:6379> hgetall userinfo
1) "name"
2) "tom"
3) "age"
4) "12"
5) "sex"
6) "man"

删除hash中某一字段值:

127.0.0.1:6379> hgetall userinfo
1) "name"
2) "tom"
3) "age"
4) "12"
5) "sex"
6) "man"
127.0.0.1:6379> hdel userinfo sex
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379> hgetall userinfo
1) "name"
2) "tom"
3) "age"
4) "12"

list(列表)类型:(取出时,按照进入时的逆序排列)增加逆序:

                                lpush    key名     value   ——  取:lrange     key名  下标起始index(0开始)    下标结束index

                            (取出时,按照进入时的正序排列)增加:

                               rpush    key名     value   ——  取:lrange     key名  下标起始index(0开始)    下标结束index

127.0.0.1:6379> lpush list1 1
(integer) 1
127.0.0.1:6379> lpush list1 2
(integer) 2
127.0.0.1:6379> lpush list1 3
(integer) 3
127.0.0.1:6379> lrange list1 0 2
1) "3"
2) "2"
3) "1"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> rpush list2 a
(integer) 1
127.0.0.1:6379> rpush list2 b
(integer) 2
127.0.0.1:6379> rpush list2 c
(integer) 3
127.0.0.1:6379> lrange list2 0 2
1) "a"
2) "b"
3) "c"
127.0.0.1:6379>

set(列表)类型:无序

增加一个:sadd    key名     member名   ——  取:smembers     key名

增加多个:sadd    key名     member1名    member2名    member3名   ...........   ——  取:smembers     key名

(注意:sadd set1 aa  bb  cc  aa  bb,成员有重复时,已添加过的aa,bb自动不再添加!!!)

举例:

127.0.0.1:6379> sadd set1 aa bb cc dd aa bb
(integer) 4
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> smembers set1
1) "aa"
2) "bb"
3) "cc"
4) "dd"
127.0.0.1:6379>

注意:以上实例中 aa,bb 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。


zset(sorted set:有序集合)Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

(比如一个学生的分数75分,这个学生不可能再有别的分数了,这个学生唯一的。

然而得75分的学生有好几个。所以分数:75分是可以重复)

zadd 命令:

增加一个:zadd    key名   score分  成员名   ——  取:smembers     key名

增加多个:zadd    key名   (score1分  成员1名)    (score2分  成员2名)   (score3分  成员3名)   ........... 

——  第1种取:zrangebyscore  stuscore   0 100 (这个理的0-100指的是分数score,50分,60分....)

——  第2种取:zrange stuscore  0  2 【withscores--指结果带上分数展示】(这个理的0-2指的是下标index,从0开始....)

注意:并且zset取出时是有排序的。

增加时:stu1 60分,stu2 50分,stu3 90分,取出时顺序:stu2 50分,stu1 60分,stu3 90分

127.0.0.1:6379> zadd stuscore 60 stu1
(integer) 1
127.0.0.1:6379> zadd stuscore 50 stu2
(integer) 1
127.0.0.1:6379> zadd stuscore 90 stu3
(integer) 1
127.0.0.1:6379> zrangebyscore stuscore 0 100
1) "stu2"
2) "stu1"
3) "stu3"
127.0.0.1:6379> zrange stuscore 0 2
1) "stu2"
2) "stu1"
3) "stu3"
127.0.0.1:6379> zrange stuscore 0 2 withscores
1) "stu2"
2) "50"
3) "stu1"
4) "60"
5) "stu3"
6) "90"
127.0.0.1:6379> zadd stuscore 80 stu4 75 stu5 88 stu6
(integer) 3

===========================================================================

指令集锦:

删除key:   del   key名

验证是否存在指定key:exists  key名(返回:1--存在   0--不存在)

获取当前所有的key名 :key * ,

获取当前所有的good开头的key名 :key  good* ,

取hash中key  的所有字段名/字段值:hkeys  key名    /   hvals  key名

127.0.0.1:6379> hkeys user
1) "name"
2) "age"
127.0.0.1:6379> hvals user
1) "tom"
2) "12"

incr   ---  加1操作(递增1)

decr   ---  减1操作(递减1)

append   key名  “字符b”-- 在key名的value后面拼接上字符b

move key  例子:1【0......16】 ----   把key名的键值对 移动到 1库,2库,3库.....等(如移入的库有同名key则不移动)

flushdb  --  清空当前库里所有键值对!



=====================================

3.redis终端中指令学习参见:

http://www.runoob.com/redis/redis-keys.html

更多命令请参考:https://redis.io/commands


4.redis的事务执行(命令模板:1.multi开启事务     2................一系列指令操作     3.exec开始执行该事务  )

以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务一并执行事务中的所有命令:

(收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行)

redis 127.0.0.1:6379> MULTI
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"
注意:Redis 事务的执行并 不是原子性的。(要么一起成功,要么一起失败  的操作叫 原子性操作。)

           Redis 事务执行中,某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。


5.Java使用Redis:

package controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import redis.clients.jedis.Jedis;

public class TestConnetRedis {

	public static void main(String[] args) {
		//连接本地的 Redis服务
		//写法一:Jedis jedis = new Jedis("localhost");
		//写法二:
		Jedis jedis = new Jedis("127.0.0.1", 6379);
		//若设置了密码,则需验证密码
		jedis.auth("pass");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+jedis.ping());
//<=======================至此,java链接redis数据库成功======================>
        System.out.println("<=============至此,java链接redis数据库成功============>");
        
        /**
         * 开始应用redis数据库:
         */
        //Java应用Redis的  String类型(字符串) 实例
        javaUseRedisByString(jedis);
        
        //Java应用Redis的  Hash类型(hash) 实例
        javaUseRedisByHash(jedis);
        
        //Java应用Redis的  List(列表) 实例
        javaUseRedisByList(jedis);
        
        //Java应用Redis的  Set类型(set) 实例
	    javaUseRedisBySet(jedis);
        
        //Java应用Redis的 all Keys 实例
        javaUseRedisGetKeys(jedis);
        
	}
	
	/**
	 * Java应用Redis的  String类型(字符串) 实例
	 */
	public static void javaUseRedisByString(Jedis jedis) {
		//设置 redis 字符串数据===>对应cmd终端中指令:set  str1(key名)  "111"(value名)
		jedis.set("str1", "111");
		jedis.set("str2", "222");
		jedis.set("str3", "333");
	
		//获取存储的数据并输出===>对应cmd终端中指令:get  str1(key名)
		System.out.println("redis 存储的字符串str1为: "+ jedis.get("str1"));
		System.out.println("redis 存储的字符串str2为: "+ jedis.get("str2"));
		System.out.println("redis 存储的字符串str3为: "+ jedis.get("str3"));
		
	}
	
	/**
	 * Java应用Redis的  Hash类型(hash) 实例
	 */
	private static void javaUseRedisByHash(Jedis jedis) {
//设置 redis hash数据===>对应cmd终端中指令:hset user(key名) "name" "tom"(value名)
		jedis.hset("user", "name", "tom");
		jedis.hset("user", "age","12");
		jedis.hset("user", "sex","boy");
	
		//获取存储的数据并输出===>对应cmd终端中指令:hgetall  user(key名) 或者:hget user(key名) name字段名
		System.out.println("redis 存储的hash数据全部得出hgetall:user为: "+ jedis.hgetAll("user"));
		/*打印:redis 存储的hash数据全部得出hgetall:user为: {sex=boy, age=12, name=tom}*/
		System.out.println("redis 存储的hash数据:user的name为: "+ jedis.hget("user", "name"));
		System.out.println("redis 存储的hash数据:user的age为: "+ jedis.hget("user", "age"));
		System.out.println("redis 存储的hash数据:user的sex为: "+ jedis.hget("user", "sex"));

//====hmset一次增加多个字段======================================>		
		System.out.println("====hmset一次增加多个字段======================================>");
		//设置 redis hash数据===>对应cmd终端中指令:hset user(key名) value:(name "tom" age 12 sex "boy")
		Map<String, String> hashmap = new HashMap<String, String>();
		hashmap.put("name","Lucy");
		hashmap.put("age","13");
		hashmap.put("sex","girl");
		jedis.hmset("user2", hashmap);
		//获取存储的数据并输出===>对应cmd终端中指令:hgetall  user(key名) 或者:hget user(key名) name字段名
		System.out.println("redis 存储的hash数据全部得出hgetall:user2为: "+ jedis.hgetAll("user2"));
		/*打印:redis 存储的hash数据全部得出hgetall:user2为: {sex=girl, age=13, name=Lucy}*/
		List<String> rsmap = jedis.hmget("user", "name", "age", "sex");
		System.out.println("redis 存储的hash数据全部得出hmget:user2为: "+rsmap); 
		/*打印:redis 存储的hash数据全部得出hmget:user2为: [tom, 12, boy]*/
	}
	
	/**
	 * Java应用Redis的  List(列表) 实例
	 */
	public static void javaUseRedisByList(Jedis jedis) {
		System.out.println("====逆序(先进后出)排序:====================================>");
		//存储数据到列表中===>对应cmd终端中指令:lpush  llist1(key名)  "1"(value名)
		jedis.lpush("llist1", "1");
		jedis.lpush("llist1", "2");
		jedis.lpush("llist1", "3");
	
		//获取存储的数据并输出===>对应cmd终端中指令:lrange  llist1(key名)
		List<String> llist1 = jedis.lrange("llist1", 0, 2);//index范围:0,1,2全部取出
		for(int i = 0 ;i < llist1.size();i++){
			System.out.println("redis 列表项llist1为: "+ llist1.get(i));
		}
		
//====正序排序:====================================>	
		System.out.println("====正序(先进先出)排序:====================================>");
		
		//存储数据到列表中===>对应cmd终端中指令:rpush  rlist2(key名)  "1"(value名)
		jedis.rpush("rlist2", "a");
		jedis.rpush("rlist2", "b");
		jedis.rpush("rlist2", "c");
	
		//获取存储的数据并输出===>对应cmd终端中指令:lrange  rlist2(key名)
		List<String> rlist2 = jedis.lrange("rlist2", 0, 2);//index范围:0,1,2全部取出
		for(int i = 0 ;i < rlist2.size();i++){
			System.out.println("redis 列表项rlist2为: "+ rlist2.get(i));
		}
		
	}
	
	/**
	 * Java应用Redis的  Set类型(set) 实例
	 */
	private static void javaUseRedisBySet(Jedis jedis) {
		//设置 redis set数据===>对应cmd终端中指令:sadd  set1(key名)  "s1"(value名)...."s3"(value3名)
		jedis.sadd("set1", "s1","s2","s3");
		//获取存储的数据并输出===>对应cmd终端中指令:smembers  set1(key名)
		System.out.println("redis 存储的set1为: "+ jedis.smembers("set1"));
		/*打印无序:redis 存储的set1为: [s3, s2, s1]*/
	}
	
	/**
	 * Java应用Redis的 all Keys 实例
	 */
	public static void javaUseRedisGetKeys(Jedis jedis) {
		// 获取数据并输出
        Set<String> keys = jedis.keys("*"); 
        Iterator<String> it=keys.iterator() ;   
        while(it.hasNext()){   
            String key = it.next();   
            System.out.println("redis key名为: "+key);   
        }
		
	}
}

更为详尽的多种写法参见:Java中使用Jedis操作Redis

6.Redis连接池:

package com.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public final class RedisUtil {
    
    //Redis服务器IP
    private static String ADDR = "192.168.0.100";
    
    //Redis的端口号
    private static int PORT = 6379;
    
    //访问密码
    private static String AUTH = "admin";
    
    //可用连接实例的最大数目,默认值为8;
    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = 1024;
    
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
    private static int MAX_IDLE = 200;
    
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
    private static int MAX_WAIT = 10000;
    
    private static int TIMEOUT = 10000;
    
    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
    private static boolean TEST_ON_BORROW = true;
    
    private static JedisPool jedisPool = null;
    
    /**
     * 初始化Redis连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxActive(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWait(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取Jedis实例
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedisPool.returnResource(jedis);
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值