关系型数据和非关系型数据库(NO SQL)的区别
关系型数据库:
- RSDB/RDB:以二维表的形式存储数据
什么是NoSql
- 为了解决高并发、高可扩展(集群)、高可用(不能宕机)、大数据存储问题而产生的数据库解决方案,就是NoSql数据库。
NoSql :全称 not only sql ,非关系型数据库。可以作为关系型数据库的一个很好的补充。不能替代。
非关系数据库:
- 以键值对的形式(KV):JSON
常见非关系型数据库:
-
1.缓存数据库(内存数据库)
-
Redis:
秒杀:精确到毫秒
支持高并发,大规模读写
是一种HA高可用的缓存数据库 -
Memcached
redis单核性能更好(redis性能更好),Memcached支持数据类型更丰富:音频、视频
-
-
2.硬盘
- mongodb:适用存储大文本数据,用户评价,商品描述
- HBASE:分布式文件存储数据库 海量数据快速检索
- HDFS:分布式文件存储系统
-
Redis缺点:
不能存储海量数据,数据不能持久化保存。 -
优点,应用场景:
- 1.适用于并发请求较大的数据
减轻了关系型数据库压力 - 2.修改频率较低的数据
CMS—>更新数据库
CMS—>rest:更新redis数据 - 3.秒杀:限时抢购 原子性
redis可以设置失效时间 - 4.在分布式项目中使用redis统计点击量
- 5.在分布式部署、tomcat集群中解决session共享问题。
- 6.网站数据排名
- 1.适用于并发请求较大的数据
redis常用数据类型:value的数据类型
- Redis是以key-value对数据进行存储
- 字符串类型(string)
- 散列类型(hash)
- 列表类型(list)队列
- 集合类型(set)
- 有序集合类型(zset)
如何通过java代码操作redis:
jedis:redis的Java客户端
缓存数据库使用原则
- 不能影响正常逻辑
JedisDemo
package demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
/**
* @author shifengyuan
* Redis是以key-value对数据进行存储
* 字符串类型(string)
* 散列类型(hash)
* 列表类型(list)
* 集合类型(set)
* 有序集合类型(zset)
*/
public class JedisDemo {
private Jedis jedis;
@Before
public void init(){
//连接Redis服务器,redis默认端口号6379
jedis = new Jedis("127.0.0.1",6379);
//查看服务是否运行
System.out.println("服务正在运行: "+jedis.ping());
}
/**
* String
*/
@Test
public void testString(){
//jedis.set(键)
jedis.set("LM", "落幕");
//jedis.get(键):值
System.out.println("LM:" + jedis.get("LM"));
//jedis.append(键):对值进行拼接
jedis.append("LM", "VS. 宗");
System.out.println("LM:" + jedis.get("LM"));
//jedis.del(键):删除键值
jedis.del("LM");
System.out.println("删除LM后:" + jedis.get("LM"));
//value必须是String类型
//一次设置一个或多个KV,redis中无该key则添加,有则覆盖
jedis.mset("actress","小花","age","18");
//jedis.incr(键):对键值进行自增
// jedis.incr("age");
jedis.decr("age");
System.out.println(jedis.get("actress") + ":" + jedis.get("age"));
//设置缓存失效时间
jedis.expire("xxoo", 1);
}
/**
* 散列
*/
@Test
public void testMap(){
//注意:key-value都必须是String类型
Map<String, String> map = new HashMap<String,String>();
map.put("小花", "18");
map.put("骚宗", "19");
map.put("狂震", "20");
jedis.hmset("ages", map);
//jedis.hmget("map的名","key1","key2"...)
List<String> values = jedis.hmget("ages","小花","骚宗");
System.out.println(values);
//删除map中的某个键值:删除ages中的小花
jedis.hdel("ages", "小花");
//jedis.hlen("map名"):获取map的长度
System.out.println("The length of ages:" + jedis.hlen("ages"));
System.out.println("Ages exsits or not:" + jedis.exists("ages"));
//jedis.hkeys("map名"):获取该map的所有key,返回值为Set
System.out.println("keys:" + jedis.hkeys("ages"));
//jedis.hvals("map名"):获取该map的所有value
System.out.println("values:" + jedis.hvals("ages"));
//遍历Redis中的map
System.out.println("------RedisMap遍历-------");
Iterator<String> it = jedis.hkeys("ages").iterator();
String key = null;
while(it.hasNext()){
key = it.next();
//jedis.hmget("map名",key):取出该map中该key的value,返回值为一个list
System.out.println(key + ":" + jedis.hmget("ages", key));
}
}
/**
* list
*/
@Test
public void testList(){
jedis.del("NBA");
//Redis里的List是双向链表,相当于LinkedList:可以在头尾添加删除元素
//jedis.lpush("list名",值):从队列头往redis里添加List,并且该元素添加到list的头部
jedis.lpush("NBA", "Houston Rockets");
jedis.lpush("NBA", "LA Laker");
jedis.lpush("NBA", "Chicago Bull");
//jedis.lrange("list名",起始下标,结束下标):按下标查找元素,-1表示查询所有元素
System.out.println("删除前:" + jedis.lrange("NBA", 0, -1));
//jedis.lpop("list名"):删除头部元素
//jedis.rpop("list名"):删除尾部元素
jedis.lpop("NBA");
System.out.println("删除后:" + jedis.lrange("NBA", 0, -1));
jedis.del("NBA");
//jedis.rpush("list名",值):往redis里添加List,并且该元素添加到list的尾部
jedis.rpush("NBA", "Houston Rockets");
jedis.rpush("NBA", "LA Laker");
jedis.rpush("NBA", "Chicago Bull");
//jedis.lset("list名",下标,值):修改该下标的元素,如果该下标不存在会抛出index of range
jedis.lset("NBA", 0, "China Rockets");
System.out.println(jedis.lrange("NBA", 0, -1));
}
/**
* set
*/
@Test
public void testSet(){
//jedis.sadd("set名",值):往Redis里添加set元素
jedis.sadd("CBA", "SanAntonio Spus");
jedis.sadd("CBA", "OCK Thuder");
jedis.sadd("CBA", "Miami Heat");
System.out.println("删除前:" + jedis.smembers("CBA"));
//jedis.srem("set名","要移除的value")
jedis.srem("CBA", "OCK Thuder");
System.out.println("删除后:" + jedis.smembers("CBA"));
//jedis.sismember("set名","value"):判断该set中是否有该值
System.out.println("Is there this value or not:"
+ jedis.sismember("CBA", "SanAntonio Spus"));
//jedis.srandmember("set名"):随机取出set中的一个值
System.out.println(jedis.srandmember("CBA"));
//jedis.scard("set名"):获取该set的元素个数
System.out.println("The length of set is " + jedis.scard("CBA"));
}
/**
* Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。
* Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。
* 如果某个成员已经是有序集的成员,那么更新这个成员的分数值,
* 并通过重新插入这个成员元素,来保证该成员在正确的位置上。
* 分数值可以是整数值或双精度浮点数。
* 如果有序集合 key不存在,则创建一个空的有序集并执行 ZADD 操作
*/
@Test
public void testZset(){
jedis.zadd("height", 100, "a");
jedis.zadd("height", 1, "b");
jedis.zadd("height", 10, "c");
jedis.zrange("height", 0, -1);
Map<String,Double> map = new HashMap<String,Double>();
map.put("v1",20.0);
map.put("v2",30.0);
map.put("v3",10.0);
Long myzset = jedis.zadd("myzset", map);
System.out.println("myzset = " + myzset);
//zrange zset的key 起始索引 终止索引 (withscore)
Set<String> zrange = jedis.zrange("myzset", 0, -1);
System.out.println("zrange = " + zrange);
}
@Test
public void testSort(){
jedis.del("nums");
jedis.lpush("nums", "10");
jedis.lpush("nums", "1");
jedis.lpush("nums", "6");
System.out.println("排序前:" + jedis.lrange("nums", 0 , -1));
//注意jedis.sort("list名"):list的元素必须是数值类型
System.out.println("sort后:" + jedis.sort("nums"));
//注意sort只是排一次序
System.out.println("排序后:" + jedis.lrange("nums", 0 , -1));
}
}