NoSQL概述

Not Only SQL 非关系型数据库

为什么需要NoSQL

  1. 高并发读写 High Performance
  2. 海量数据的高效率存储和访问 Huge Storage
  3. 高可扩展性和高可用性 High Scalability && High Availability

NoSQL数据库的四大分类

  1. 键值存储 key-value
    1. 快速查询
    2. 数据缺少结构化
  2. 列存储
    1. 查找速度快,扩展方便
    2. 功能局限
  3. 文档数据库
    1. 数据结构要求不是很严格
    2. 查询性能不好,缺乏统一的查询语法
  4. 图形数据库
    1. 利用图结构相关算法
    2. 需要对整个图做计算才能得出结果,不易做分布式集群方案

NoSQL特点

  1. 易扩展
  2. 灵活的数据模型
  3. 大数据量,高性能
  4. 高可用

Redis的概述

高性能键值对数据库。

支持的键值数据类型:

  1. 字符串类型
  2. 列表类型
  3. 有序集合类型
  4. 散列类型
  5. 集合类型

Redis应用场景

  1. 缓存
  2. 任务队列
  3. 网站访问统计
  4. 数据过期处理
  5. 分布式集群架构中的session分离
  6. 应用排行榜
  7. ...

Redis的安装和使用

常用操作

新增 set name chaoji

获取 get name

删除 del name

查询所有key keys *

Jedis的入门

jedis是Redis官方推荐的java客户端开发包
package com.xuchaoji.jedisdemo;

import org.junit.Test;

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

public class JedisDemo1 {

    @Test
    public void demo1() {
        //设置ip和端口
        Jedis jedis = new Jedis("us1.xuchaoji.com",6379);
        //保存数据
        jedis.set("name", "chaoji");
        //获取数据
        String value=jedis.get("name");
        System.out.println(value);
        //释放资源
        jedis.close();
    }
    /**
     * 使用连接池方式连接
     */
    @Test
    public void demo2() {
        //获得连接池对象
        JedisPoolConfig config = new JedisPoolConfig();
        //设置最大连接数
        config.setMaxTotal(30);
        //设置最大空闲连接数
        config.setMaxIdle(10);
        //获得连接池
        JedisPool jedisPool = new JedisPool(config,"us1.xuchaoji.com",6379);
        //获得核心对象
        Jedis jedis = null;
        try {
            //通过连接池获得连接
            jedis = jedisPool.getResource();
            jedis.set("age", "25");
            System.out.println(jedis.get("age"));
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            if(jedis !=null ) {
                jedis.close();
            }
            if(jedisPool != null ) {
                jedisPool.close();
            }

        }

    }
}

Redis的数据类型

Redis的数据结构

五种数据类型:

  1. 字符串(String)
  2. 哈希(hash)
  3. 字符串列表(list)
  4. 字符串集合(set)
  5. 有序字符串集合(sorted set)

key定义注意点

  1. 不要过长或过短
  2. 最好有统一的命名规范

存储String

  • 二进制安全,存入和获取的数据相同
  • value最多可以容纳的数据长度是512M

    存储String常用命令

  1. 赋值

    1. set key value
    2. getset key value //先获取、再赋值
  2. 取值

    1. get key
  3. 删除

    1. del key
  4. 数值增减

    1. incr number //将值+1,若类型不能转换为int,会报错。若不存在对应的key,会创建,key,value默认为0,然后+1
    2. decr number //-1
  5. 扩展命令

    1. incrby num 5 //增加5
    2. decrby num 5 //减少5
    3. append key 1234 //在key后追加1234字符串

存储Hash

String key 和String value的map容器。每一个hash可以存储4294967295个键值对

存储Hash常用命令

  1. 赋值
    1. hset myhash name chaoji
    2. hset myhash age 25
    3. hmset myhash2 name chaoji age 25
  2. 取值
    1. hget myhash name
    2. hmget myhash2 name age
    3. hgetall myhash //获取全部
  3. 删除
    1. hdel myhash2 name age
    2. del myhash2 //删除整个hash
  4. 增加数字
    1. hincrby myhash age 5 //将myhash中的age增加5
  5. 其它命令
    1. hexist myhash name //判断myhash中是否有name
    2. hgetall myhash //获取myhash中所有的key value
    3. hlen myhash //获取key的个数
    4. hkeys myhash //获取所有的key
    5. hvals myhash //获取所有的value

      存储list

  • ArrayList数组方式
  • LinkedList双向链接方式
  • 双向链表中增加数据
  • 双向链表中删除数据

存储list常用命令

  1. 两端添加
    1. lpush mylist a b c //左侧添加
    2. rpush mulist2 1 2 3 //右侧添加
  2. 查看列表
    1. lrange mylist start end //start 和end是起始位置(0是第一个,-1是最后一个)
  3. 两端弹出
    1. lpop mylist 弹出左侧第一个元素(返回元素并从列表删除)
    2. rpop
  4. 获取列表元素个数
    1. llen mylist
  5. 扩展命令
    1. lpushx mylist //当mylist存在的时候才从左侧插入数据
    2. rpushx ...
    3. lrem mylist count value //从左侧遍历,删除count个等于value的值,count小于0,从尾部遍历,count等于0,删除所有等于value的值
    4. lset mylist 3 mmmm //设置index为3的元素为mmmm
    5. linsert mylist before b 11 在左侧第一个b之前插入11
    6. rpoplpush mylist1 mylist2 将mylist1右侧第一个值弹出,并添加到mylist2的第一个

存储set

和set不同,不允许重复

存储set常用命令

  1. 添加、删除元素
    1. sadd myset a b c
    2. srem myset a b
  2. 获得集合中的元素
    1. smembers myset //获取全部元素
    2. sismember myset a //判断a是否在set中,返回1表示存在,0表示不存在
  3. 集合中的差集运算
    1. sdiff myset1 myset2
  4. 集合中的交集运算
    1. sinter myset1 myset2
  5. 集合中的合并集运算
    1. suni myset1 myset2
  6. 扩展命令
    1. scard myset //获取元素数量
    2. srandmember myset //随机返回
    3. sdiffstore my1 mya1 myb1 //将mya1、myb1的差集存储到my1
    4. sinterstore my1 mya1 myb1 //...
    5. sunistore my1 mya1 myb1 //...

存储sorted-set

sorted-set中的成员在集合中的位置是有序的,即使获取中间的值,效率也很高

存储sorted-set常用命令

  1. 添加元素
    1. zadd mysort 70 zs 80 ls 90 ww //存进去3个值
    2. 若再次添加相同元素 zadd mysort 100 zs 会对原有的进行替换
  2. 获得元素
    1. zscore mysort zs //获得zs的分数
    2. zcard mysort //获得元素个数
  3. 删除元素
    1. zrem mysort zs ls //删除元素
  4. 范围查询
    1. zrange mysort 0 -1 查询从第一个到最后一个所有元素
    2. zrange mysort 0 -1 withscores 带分数(默认顺序由小到大)
    3. zrevrange mysort 0 -1 (withscores) 从大到小查询
    4. zremrangebyrank mysort 0 4 按照范围删除
    5. zremrangebyscore mysort 80 100 按照分数范围删除
  5. 扩展命令
    1. zrangebyscore mysort 0 100 (withsocres) 查询分数范围在0到100之间的元素,可以带分数一起显示
    2. zrangebyscore mysort 0 100 withsocres limit 0 2 只显示2个
    3. zincrby mysort 3 ls 将ls分数增加3
    4. zcount mysort 80 90 显示分数在80到90之间元素的个数

Keys的通用操作

  1. keys * 显示所有key
  2. keys my? 显示所有my开头的key
  3. del my1 my2 my3 删除key
  4. exists my1 判断key是否存在
  5. get key 获取key的值
  6. rename oldkey newkey 重命名
  7. expire key 1000 1000秒后过期
  8. ttl key 查看key所剩的时间
  9. type key 获取key的类型

Redis的特性

  1. 多数据库
    1. 一个Redis可以提供16个数据库,index从0到15,默认连接0
    2. select 1 选择1号数据库
    3. move myset 1 将myset移动到1号数据库
  2. 支持事务
    1. multi 开启事务
    2. exec 提交
    3. discard 回滚

Redis的持久化

两种持久化方式:

  1. RDB方式
    1. 在指定时间内将数据存储到硬盘
  2. AOF方式
    1. 以日志的方式读取每一次操作,重新开启后读取日志恢复所有数据
  3. 无持久化
    1. 作为缓存
  4. 同时使用RDB和AOF

RDB

  • 优势:每小时或者每分钟归档一次,如果aof的数据集过大,rdb的启动方式很快。

  • 劣势:如果持久化以前,宕机,也就是30s持久化一次,25s的时候宕机,这25s的数据了还没写到硬盘就没了。

    配置:

    redis.conf中:

    save 900 1
    save 300 10
    save 60 10000
    save n m 每n秒,至少有m个key发生变化,会持久化一次
    dbfilename dump.rdb #保存的文件名
    dir ./ #保存的目录

AOF

  • 优势:

    1. 数据安全(每秒同步,每修改同步,步同步)
  • 劣势:

    • 如果宕机 这1s的数据就没了。
    • 每修改同步,安全,但是效率慢。
    • 对于日志的写入方式采用append模式,在写的过程中发生宕机,写了一半,宕机,下次启动前工具会解决数据一致性问题。如果日志过大,redis会启动重写日

      配置:

      redis.conf中:

    appendonly no #默认不采用AOF
    appendfsync always #每修改一次同步一次
    appendfsync everysec #每秒同步
    appendfsync no #不同步

flushall:清空数据库

String Hash