概述
简介
NoSQL : Not only SQL,泛指一切非关系型数据库
关系型数据库:指以表的形式来保存数据库,以键/表的形式维护数据库之前的关系。如 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
非关系型数据库:泛指 关系型数据库之外其它类型的数据库 。如 NoSql、Cloudant等
关系型数据库的缺点
- 高并发问题:海量的请求同时访问数据库
- 高性能问题:数据量越来越大,需要从海量的数据量瞬间访问/操作某一些数据
- 高扩展问题:数据库的集群,数据的迁移和移植
非关系型数据库的优点
- 实现高性能要求:数据之间没有关系,所以数据的存取效率是非常高
- 数据结构非常灵活:不以表的形式保存数据,可以以任何适合的格式来保存数据
- 高扩展的优点:可以非常灵活进行数据移植
web 应用开发中非关系型数据库的使用
仍然是以关系型数据库来持久化报错数据,可以维护数据之间的业务关系。非关系型数据库作为补充。可以用来提升数据库的存取效率。
通常把 Redis 数据库与作为数据缓存,缓存了一些经常读取,但不经常修改的数据。列如:商品的分类信息,可以放在在缓存里。页面需要显示分类的时候,从缓存里读取,速度或比较快,可以有效提高 web 应用的访问性能。
Redis
C编写的免费开源,以 key-value 存取数据的非关系型数据库,把数据存储到内存中,而不是磁盘中,有非常高的读写性能。
Redis 的端口:6379 merz
操作Redis
Redis 的数据类型
以 key-value 保存数据
key:始终是字符串。通常来说,key的长度不要超过1024个字节,否则会影响数据的读写性能。
value:数据类型是五种 :
- string:字符串类型,一个string可以保存512M数据
- hash:哈希列表,类似于 HashMap,一个hash可以保存 2^23-1个数据
- List:列表类型,类似于 LinkedList, 2^23-1
- set:无序不重复的数据集合,类似于Set, 2^23-1
- zset:(sorted set)有序不重复的数据集合, 2^23-1
Redis 的数据操作
-
操作 string
设置数据:set key value 比如: set username zhangsan 获取数据: get key 比如: get username 删除数据: del key 比如: del username
-
操作 hash
添加数据: hset key field value 比如: hset user username coco 获取数据: hget key field 比如: hget user username 删除数据: hdel key field 比如: hdel user username 获取所有: hgetall key 比如: hgetall user
-
操作 List
添加数据: 从左边压入数据: lpush key value1 value2... 从右边压入数据:rpush key value1 value2... 弹出数据: 从左边弹出数据:lpop key 从右边弹出数据:rpop key 查看数据: lrange key 0 -1 其中:-1表示最后一个数据
-
操作 Set
添加数据: sadd key value 随机取出一个数据: srandmember key 查看数据: smembers key 删除数据: srem key member 多集合之间的运算: 交集: sinter key1 key2 并集: sunion key1 key2 差集: sdiff key1 key2
-
通用的 key 操作
查询key: keys表达式 比如:keys *, keys myset? 删除key: del key 判断key是否存在: exists key 获取key的类型: type key
Jedis
Redis 在 web 应用开发中,是作为缓存来使用的,通过 Java 程序来操作 Redis 数据。
Jedis 操作 Redis 数据库需要的 jar 包:
Jedis-*.jar
-
common-pool*.jar u
连接池使用的
操作步骤:
- 获取连接 Jedis 对象
- 操作 Jedis
- 释放资源,关闭 Jedis
Jedis 的 API
构造方法: Jedis(String host,int port)
常用方法: 方法名和命令名称一致
设置string数据: set(String key,String value)
获取string数据: get(String key)
删除string数据: del(String key)
从左边向list添加一个数据: lpush(String key,String value)
关闭连接: jedis.close();
Jedis 操作示例
@Test
public void demo1(){
//1. 创建 Jedis 连接对象
Jedis jedis = new Jedis("localhost",6379);
//2. 操作 Redis 数据库
//jedis.set("username","zhangsan");
String username = jedis.get("username");
System.out.println(username);
//3. 关闭连接对象
jedis.close();
}
Jedis 连接池的 API
连接池的构造方法:
JedisPool(String host,int port) 使用默认配置的连接池
JedisPool(JedisPoolConfig config,String host,int port) 使用自定义的连接池
连接池配置信息对象
无参构造: JedisPoolConfig()
常用方法:
setMaxTotal(int maxTotal) 设置最大连接数
setMaxIdle(int maxIdle) 设置最大空闲连接数
从连接池 JedisPool 里获取连接:
Jedis jedis = pool.getResource()
Jedis 连接池示例
//1. 创建一个连接池配置信息对象,设置连接池的参数信息
//2. 使用配置信息对象,创建连接池对象
//3. 从连接池里获取连接
@Test
public void demo2() {
// 创建一个连接池的配置对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(30); //设置连接池里最多有30个连接
jedisPoolConfig.setMaxIdle(10); //设置连接池里最多有10个空闲连接
// 使用配置信息对象,创建连接池对象
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "localhost", 6379);
//从连接池获取连接对象
Jedis jedis = jedisPool.getResource();
//操作 Redis 数据库
String username = jedis.get("username");
System.out.println(username);
//关闭连接对象
jedis.close();
}
封装 jedis 工具类 : JedisUtils
//1.JedisUtils
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ResourceBundle;
public class JedisUtils {
private static JedisPool pool;
private static String host;
private static int port;
private static int maxTotal;
private static int maxIdle;
static{
//加载资源文件
ResourceBundle bundle = ResourceBundle.getBundle("jedis");
host = bundle.getString("host");
port = Integer.parseInt(bundle.getString("port"));
maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
maxIdle = Integer.parseInt(bundle.getString("maxIdle"));
//创建连接池配置信息
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
//创建连接池对象
pool = new JedisPool(config, host, port);
}
/**
* 获取Jedis连接
* @return Jedis对象
*/
public static Jedis getJedis(){
return pool.getResource();
}
/**
* 关闭Jedis连接
* @param jedis 要关闭的Jedis连接对象
*/
public static void close(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
/**
* 设置缓存
* @param key 缓存的key
* @param value 缓存的value
*/
public static void setCache(String key, String value){
Jedis jedis = null;
try {
jedis = getJedis();
jedis.set(key, value);
} catch (Exception e) {
System.out.println("设置缓存数据失败:["+key+":"+value+"]");
} finally {
//关闭连接
if (jedis != null) {
jedis.close();
}
}
}
/**
* 获取缓存
* @param key 缓存的key
* @return 缓存的value
*/
public static String getCache(String key) {
Jedis jedis = null;
try {
jedis = getJedis();
return jedis.get(key);
} catch (Exception e) {
System.out.println("获取缓存失败:" + key);
} finally {
//关闭连接
if (jedis != null) {
jedis.close();
}
}
return null;
}
}
//2. 配置文件 jedis.properties
host=localhost
port=6379
maxTotal=30
maxIdle=10
//3.test
@Test
public void demo2() {
JedisUtils.setCache("username", "coco1");
}
@Test
public void demo3() {
String username = JedisUtils.getCache("username");
System.out.println(username);
}
持久化机制
Redis数据库是把数据保存在了内存当中,那么如果Redis服务关闭,就需要把内存里的数据进行持久化保存,所以Redis本身提供了持久化机制:在某些时候把内存里的数据保存到磁盘文件上。
Redis提供了两种持久化机制:RDB模式 和 AOF模式。
RDB 模式
RDB 模式:快照模式,默认是开启状态的。
定期把 Redis 内存中的数据,生成快照文件,保存到磁盘文件上。默认生成的文件:dump.rdb,默认保存在 Redis 安装目录中
RDB 模式的相关配置,在 redis.conf里
save 900 1 表示:如果数据变更1次,那么900秒生成一次快照文件
save 300 10 表示:如果数据变更10次,那么300秒生成一次快照文件
save 60 10000 表示:如果数据变更1000次,那么10000秒生成一次快照文件
dbfilename dump.rdb 默认生成的快照文件名称
dir ./ 表示生成的快照文件,保存到redis-server的当前目录
AOF 模式
AOF模式:append only file模式,默认是关闭的。
如果我们在Redis里执行数据的变更,那么每次变量,Redis都会把执行的命令追加到一个文件里。等Redis重启、需要恢复数据的时候,读取文件里所有的命令,按顺序重新构建Redis的数据。
如果开启了AOF模式,Redis会把数据变更的命令保存到了appendonly.aof,默认在Redis的安装目录里。这些信息可以通过修改redis.conf更改配置:
appendonly no AOF模式的开关,默认是关闭状态,如果要使用,需要手动更改成yes。需要重新Redis
appendfilename "appendonly.aof" 默认生成的文件名称appendonly.aof
# appendfsync always 每次数据变更,都保存变更的命令到aof文件里
appendfsync everysec 每秒保存一次
# appendfsync no 不保存
RDB模式和AOF模式的优缺点
RDB模式:默认开启,性能高;但是可能会丢失数据
AOF模式:默认关闭,比较安全,丢失数据的可能性小;影响性能。
Redis在web应用里的使用方式
web应用里的数据最终还是必须要保存到关系型数据库里,Redis作为数据的缓存使用。