NoSQL和关系型数据库区别
NoSQL非关系型数据库:Redis、MongoDB、HBase等,基于Key-Value存储,采用命令操作
关系型数据库:Oracle、MySQL、DB2、SQLServer等,基于表结构存储,采用SQL操作
Redis简介
Reidis是由意大利人 Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis 全称为: Remote Dictionary Server(远程数据服务),该软件使用 C 语言编写,典型的 NoSQL 数据库服务器,Redis是一 个 key-value 存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。
Redis特点
优点:
- 性能极高,Redis能支持每秒10万读写频率。
- 支持丰富的数据类型–Redis支持 string、list、set、zset(sorted set)、hash等多种数据类型。
- 原子性–Redis所有操作都是原子性的(一起成功,或者一起失败)。
- Redis支持持久化操作,将内存数据同步到数据文件中。
- Redis还提供了事务、消息传递等功能。
缺点:
- 由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然 redis 本身有 key 过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
- 如果进行完整重同步,由于需要生成 rdb 文件,并进行传输,会占用主机的 CPU,并会消耗现网的带宽。不过 redis2.8 版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。比如,新上线的备机。
- 修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,redis 不能提供服务。
在系统中,通常使用Redis做数据缓存使用。
查询缓存:第一次从数据库取出放入缓存,然后后续都从缓存取出数据。
添加/更新缓存:将用户数据通过检测后放入缓存,然后给用户响应,后台开启线程取数据处理。
Redis常用数据类型:
redis常用五种数据类型:string,hash,list,set,zset(sorted set).
Redis 的数据结构有五种,分别是:
- String——字符串
String 数据结构是简单的 key-value 类型,value 不仅可以是String,也可以是数字(当数字类型用 Long 可 以表示的时候 encoding 就是整型,其他都存储在 sdshdr 当做字符串)。
在list、set和zset中包含的独立的元素类型都是Redis String类型。
String类型的数据最大512MB。- Hash——字典
hash是最接近关系数据库结构的数据类型,可以将数据库一条记录或程序中一个对象转换成hashmap存放在redis中。
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值 (一般是 JSON
格式),比如用户的昵称、年龄、性别、积分等。- List——列表
List 说白了就是链表(redis 使用双端链表实现的 List)。
链表类型,主要功能是push、pop、获取一个范围的所有值等。其中的key可以理解为链表的名字。
在Redis中,list就是Redis String的列表,按照插入顺序排序。比如使用LPUSH命令在list头插入一个元素,使用RPUSH命令在list的尾插入一个元素。当这两个命令之一作用于一个空的key时,一个新的list就创建出来了。
List的最大长度是2^32-1个元素。- Set——集合
Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set
数据结构,可以存储一些集合性的数据。 在Redis中,set就是Redis String的无序集合,不允许有重复元素。
Set的最大元素数是2^32-1。
Redis中对set的操作还有交集、并集、差集等。- ZSet(Sorted Set)——有序集合
和 Sets 相比,Sorted Sets 是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进 行有序排列,
对于已经有序的zset,仍然可以使用SORT命令,通过指定ASC|DESC参数对其进行排序。
Zset的最大元素数是2^32-1
应用:带有权重的元素,比如一个游戏的用户得分排行榜
- Redis操作命令
- 字符串操作
set key value //设置value值
get key //获取value值
strlen key //获取value长度
incr key //将value加1
incrby key i //将value加i
decr key //将value减1
decrby key i //将value减i
append key value //将原有key的值拼接上value值
- key操作
keys pattern //查看key
del key //删除key
expire key time //设置有效时间(秒)
type key //判断value值类型
rename key newkey //修改key名称
- 哈希操作(Java中的Map)
hset key 字段名 字段值 //设置一组
hmset key 字段名 字段值 字段名 字段值 //设置多组
hget key 字段名 //获取一个字段值
hmget key 字段名1 字段名2 //获取多个字段值
hlen key //获取字段数量
hkeys key //查看字段名
hdel key 字段名 //删除字段名
- 列表操作(Java中List)
lpush key value //从头部放入值(key列表存在插入,不存在创建列表插入)
rpush key value //从尾部放入值
lpop key //从头部删除一个元素
rpop key //从尾部删除一个元素
lrem key count value //删除多少个值等于value的元素
lindex key index //获取index位置的value值
lrange key start end //获取指定范围的元素
linsert key before|after 元素 要插入的值 //插入元素
lset key index value //更新index位置的value值
llen key //获取列表元素数
- 集合操作(Java中Set)
sadd key value value //向集合添加元素
srem key value //删除value元素
scard key //获取集合元素数量
smembers key //查看所有元素
srandmember key count //获取count个随机数
sinter key1 key2 //两个集合交集,key1和key2都有
sunion key1 key2 //两个集合并集,去重复合并
sdiff key1 key2 //差集,key1有,key2没有
- 有序集合
zadd key score value //向集合添加元素
zrem key value //删除元素
zcard key //元素数量
zrange key start end //获取指定范围的元素(小到大)
zrevrange key start end //获取指定范围的元素(大到小)
zrevrank key value //获取value索引(大到小)
zrank key value 获取value索引(小到大)
4. Java对Redis操作
- 引入驱动包jedis.jar
- 之后建立连接,对Redis操作
- 释放连接资源
**示例代码**
public void test2(){
Jedis jedis = new Jedis("localhost");
jedis.set("msg", "java msg");//set key value
String str = jedis.get("msg");//get key
System.out.println(str);
jedis.close();//有些版本jar包没有该方法
}
5. 对象存取操作(基于JSON字符串存取)
- 将Java对象转成JSON字符串写入Redis
public void test1(){
Emp emp = new Emp();
emp.setEmpno(100);
emp.setEname("ROSE");
emp.setSal(20000.0);
emp.setJob("Programming");
emp.setDeptno(10);
//将emp转成json字符串
Gson gson = new Gson();
String jsonStr = gson.toJson(emp);
Jedis jedis = new Jedis("localhost");
jedis.set("emp_100", jsonStr);
jedis.close();
}
- 将JSON字符串从Redis取出转成Java对象
public void test2(){
Jedis jedis = new Jedis("localhost");
String jsonStr = jedis.get("emp_100");
//将json字符串转成emp
Gson gson = new Gson();
Emp emp = gson.fromJson(jsonStr, Emp.class);
System.out.println(emp.getEmpno()+" "+emp.getEname()+" "+emp.getJob());
jedis.close();
}
6. 对象存取操作(基于序列化存取)
- 将对象序列化存储
public void test1_1(){
Emp emp = new Emp();
emp.setEmpno(101);
emp.setEname("JACK");
emp.setSal(20000.0);
emp.setJob("Programming");
emp.setDeptno(10);
//将emp对象序列化成byte[]
byte[] bts = SerializeUtil.serialize(emp);
Jedis jedis = new Jedis("localhost");
jedis.set("emp_101".getBytes(), bts);
jedis.close();
}
- 反序列化获取
public void test2_1(){
Jedis jedis = new Jedis("localhost");
byte[] bts = jedis.get("emp_101".getBytes());
//将byte数组转成emp对象
Emp emp = (Emp)SerializeUtil.unserialize(bts);
System.out.println(emp.getEmpno()+" "+emp.getEname()+" "+emp.getJob());
jedis.close();
}
7. 分页缓存
思路:将每一个页记录使用Redis列表存储。为了保持同步性增删改操作需要做如下处理
- 删除:需要清除Redis中当前页,后续页缓存
- 更新:需要清除Redis中当前页缓存
- 添加:需要清除所有页缓存
redis常用五种数据类型:string,hash,list,set,zset(sorted set).
String:是最简单的类型,一个key对应一个value List类型:链表类型,主要功能是push、pop、获取一个范围的所有值等。
Set类型:集合,和数学中的集合概念相似。ZSet(Sorted Set)类型
在set的基础上增加了一个顺序属性,这一属性在添加修改元素时可以指定,每次指定后zset会自动安装指定值重新调整顺序。可以理解为一张表,一列存value,一列存顺序。操作中的key理解为zset的名字。hash类型 hash是最接近关系数据库结构的数据类型,可以将数据库一条记录或程序中一个对象转换成hashmap存放在redis中。
Redis 最适合的场景有哪些?
(1)、会话缓存(Session Cache)
(2)、全页缓存(FPC)
(3)、队列
(4)、排行榜/计数器
(5)、发布/订阅
Redis文件格式
redis使用了两种文件格式:全量数据和增量请求。
全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载;
增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行replay得到数据,序列化的操作包括SET、RPUSH、SADD、ZADD。
redis的存储分为内存存储、磁盘存储和log文件三部分,配置文件中有三个参数对其进行配置。