轻松掌握非关系型数据库Redis
关系型数据库与nosql数据库区别
关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织
优点:
易于维护:都是使用表结构,格式一致;
使用方便:SQL语言通用,可用于复杂查询;
复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点:
- 读写性能比较差,尤其是海量数据的高效率读写;
- 固定的表结构,灵活度稍欠;
- 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等
优点:
- 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
- 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
- 高扩展性;
- 成本低:nosql数据库部署简单,基本都是开源软件。
缺点:
- 不提供sql支持,学习和使用成本较高;
- 无事务处理;
- 数据结构相对复杂,复杂查询方面稍欠。
redis概述
是以key-value形式存储,是跨平台的
优点:
- 可以对数据进行高并发读写(在内存中进行读写,基于内存)
- 对海量数据的高效率存储和访问
- 对数据的可拓展性和高可用性.
- **单线程操作,**每个操作都是原子操作,没有并发相关问题(redis 6以下)
总:
redis的定位是缓存, 提高数据读写速度, 减轻对数据库存储与读取访问压力
常用命令
incr key
:创建一个指定名称的key,并且值默认是1
String类型
(k,v)
set key value 存入键值对
set username "yoona"
get key 根据键取出值
get username
incr key 把值递增1,如果不存在就创建,初始值为1
set price 18 incr price
decr key 把值递减1
set price 18 decr price
del key 根据键删除对应的值
del username
setex key timeout value 存入键值对,timeout表示失效时间,单位s
setex age 6 20 //存入age=20,6秒后自动删除
ttl key 可以查询出当前的key还剩余多长时间过期
ttl age
setnx key value 如果key已经存在,不做操作, 如果key不存在,直接添加
setnx username hkj
应用情景:
计数器:许多运用都会使用redis作为计数的基础工具,他可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他的数据源。
如:视频播放数系统就是使用redis作为视频播放数计数的基础组件。
共享session:出于负载均衡的考虑,分布式服务会将用户信息的访问均衡到不同服务器上,用户刷新一次访问可能会需要重新登录,为避免这个问题可以用redis将用户session集中管理,在这种模式下只要保证redis的高可用和扩展性的,每次获取用户更新或查询登录信息都直接从redis中集中获取
hash类型
(k:{k:v,k:v})
hset key hashkey hashvalue 存入一个hash对象
hset user name hkj
hget key hashkey 根据hash对象的键取值
hget user name
**hexists key hashkey ** 判断hash对象是含有某个键
hexists user name
hdel key hashkey 根据hashkey删除hash对象键值对
hdel user name
hlen key 获取hash对象键的数量
hlen user
hkeys key 获取hash对象的所有键
hkeys user
hvals key 获取hash对象的所有值
hvals user
hgetall key 获取hash对象的所有数据
hgetall user
应用情景:
常常用于用户信息等管理,如共享session:
list类型
(k:{v,v,v,v})
rpush key value 往列表右边添加数据
rpush hobby java
lrange key start end 范围显示列表数据,要全显示则设置0 -1
lrange hobby 0 -1
lpush key value 往列表左边添加数据
lpush hobby springboot
lpop key 弹出列表最左边的数据
lpop hobby
rpop key 弹出列表最右边的数据
rpop hobby
**llen key ** 获取列表长度
llen hobby
应用情景:
用户收藏文章列表:xxxx_user_articles:uid [aid1, aid2, aid3…]
set类型
(k:{v,v,v,v})
sadd key value… 往set集合中添加value元素
sadd myset a b c d
smembers key 查询set集合中的所有元素
smembers myset
srem key value 删除set集合中的value元素
srem myset a
spop key count 随机弹出集合中的元素
spop myset 2 //随机弹出集合中的两个元素
sdiff key1 key2 返回key1中特有元素(差集)
sadd set1 a b c d sadd set2 c d e f sdiff set1 set2
sinter key1 key2 返回两个set集合的交集
sinter set1 set2
sunion key1 key2 返回两个set集合的并集
sunion set1 set2
scard key 返回set集合中元素个数
scard set1
应用情景
去重,抽奖
sorted_set类型
zadd key score column 存入分数和名称
zadd players 2000 A
zincrby key score column 增加名称对应的分数
zincrby players 1000 C
zrange key start end[withscores] 按照分数升序输出名称
zrange players 0 -1
zrevrange key start end[withscores] 按照分数降序输出名称
zrevrange players 0 -1 withscores
zrank key name 升序返回排名
zrank players E
zrevrank key name 降序返回排名
zrevrank players E
zcard key 返回元素个数
zcard players
zrem key name 根据名称删除对应的名称和分数
zrem players B
zremrangebyrank key start end 根据排名删除所有元素
zremrangebyrank players 0 -1
zcount key min max 按照分数范围统计个数
zcount players 1000 5000
应用情景
排行榜:例如视频网站需要对用户上传的视频做排行榜,榜单维护,也可能是多方面:按照时间、按照播放量、按照获得的赞数等
类型和key设计选用
- 如果要排序选用sorted_set
- 如果数据是多个且允许重复选用list
- 如果数据是多个且不允许重复选用set
- 剩下的使用string
- 如果是对象类型也可使用hash
注:有些公司除了排序选用sorted_set,剩下的都使用string
key的设计需符合唯一性,可读性,灵活性,时效性
例:article_view_num:id,film_click_num:id
高级命令
keys * 查询所有键
keys *
exists 是否存在指定key
exists user
expire 设置某个key的过期时间.使用ttl查看剩余时间
expire user 2 //2秒后将user这个key和对应的value删除
persist 取消过期时间
persist user //当user这个key设置了过期时间,通过该命令在过期时间内可进行取消
redis安全性
由于在没有给redis设置密码时,如果外界知道了redis所在的ip和端口,容易出现安全问题,可以对**redis.windows-service.conf
文件进行编辑,找到requirepass foobared
**,可以对密码foobared进行自定义修改
重启服务器 pkill redis-server,由于进行命令窗口每次都需要输入密码,还有种简单的方式:·redis-cli -a [密码]
redis事务
- redis中的事务并不是真正意义上的事务,因为单条redis命令的执行是原子性的,但redis并没有在事务上增加任何维持原子性的机制,所以redis事务的执行并不是原子性的
- redis中的事务可以理解为就是对命令进行打包的批处理执行脚本,批处理操作在发送exec命令前会被放入队列缓存中,如果某条命令执行失败并不会对其他命令造成影响
- 在事务执行过程中,其他客户端提交的命令请求只有等到事务中的所有命令都执行完成后才可以插入执行
redis持久化机制
redis的持久化机制有两种方式:RDB和AOF
redis默认采用RDB方式
快照简单的理解就是将内存中的数据全部复制一份写入到二进制文件中,默认在dump.rdb文件中,可以配置设置自动做快照持久化方式、配置redis在n秒内如果超过m个key就自动发起快照保存
Snapshotting设置:
save 900 1 #900秒内如果超过1个Key被修改则发起快照保存
save 300 10 #300秒内如果超过10个key被修改,则发起快照保存
save 60 10000
AOF方式
由于快照方式是在一定时间间隔做一次,所以可能发生reids意外down掉的情况就会丢失最后一次快照后的所有修改的数据.aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的命令都通过write函数追加到命令中,当redis重新启动时会重新执行文件中保存的这些命令在内存中重建这个数据库中的内容
aof不是立即写到硬盘中,可以通过配置文件修改强制写到硬盘中
appendonly yes //启动aof持久化方式有三种修改方式
#appendfsync always//收到命令就立即写到磁盘,效率最慢.但是能保证完全的持久化
#appendfsync everysec//每秒写入磁盘一次,在性能和持久化方面做了很好的折中
#appendfsync no //完全以依赖os 性能最好,持久化没保证
在关于选用配置的问题上需要关注三个点进行考虑:
- 数据量大小
- 数据的重要性
- 数据量增长频率
Redis内存淘汰机制及过期Key处理
最常使用的两种内存淘汰机制:
LRU(Least recently used)
:从数据库中删除最近最少访问的数据LFU(Least Frequently Used)
:从数据库中删除使用次数最少的数据
通过maxmemroy-policy可以配置具体的淘汰机制(8种)
例:volatile-lru、volatile-lfu…
清理过期key有三种清除策略:
惰性:当访问Key时,才去判断它是否过期,如果过期,直接干掉,但是一个key如果长期不用,一直存在内存里,会造成内存资源浪费
定时:设置键的过期时间的同时,创建一个定时器,当到达过期时间点,立即执行对Key的删除操作
定期:隔一段时间,对数据进行一次检查,删除里面的过期Key,检查的数据量由算法决定
开发中通常推荐使用惰性删除和定期删除两种策略
java操作redis
使用jedis
JedisPool pool = new JedisPool("localhost", 6379);
Jedis jedis = pool.getResource();xxxxxxxxxxxxjedis.close();
pool.close();
pool.destroy();
String类型
/存入键值对/
jedis.set(“username”,“yoona”);
/根据键取出值/
System.out.println(jedis.get(“username”));
/把值递增1/
jedis.set(“age”,“18”);
Long age = jedis.incr(“age”);
System.out.println(age);
/* 把值递减1*/
System.out.println(jedis.decr(“age”));
/根据键删除对应的值/
jedis.del(“username”);
/存入键值对,timeout表示失效时间,单位s/
jedis.setex(“name”,6,“hkj”);
/可以查询出当前的key还剩余多长时间过期/
Long time = jedis.ttl(“name”);
System.out.println(time);
/如果key已经存在,不做操作, 如果key不存在,直接添加/
jedis.setnx(“score”, “100”);
System.out.println(jedis.get(“score”));
hash类型
/存入一个hash对象/
jedis.hset(“user”,“name”,“hkj”);
jedis.hset(“user”,“hobby”,“java”);
/根据hash对象的键取值/
System.out.println(jedis.hget(“user”,“name”));
/判断hash对象是含有某个键/
System.out.println(jedis.hexists(“user”, “name”));
System.out.println(jedis.hexists(“user”, “age”));
/获取hash对象键的数量/
System.out.println(jedis.hlen(“user”));
/根据hashkey删除hash对象键值对/
jedis.hdel(“user”, “name”);
System.out.println(jedis.hget(“user”, “name”));
jedis.hset(“user”,“tall”,“179”);
jedis.hset(“user”,“tall”,“180”);
jedis.hset(“user”,“size”,“20”);
jedis.hset(“user”,“weight”,“50”);/获取hash对象的所有键/
System.out.println(jedis.hkeys(“user”));
/获取hash对象的所有值/
System.out.println(jedis.hvals(“user”));
/获取hash对象的所有数据/
System.out.println(jedis.hgetAll(“user”));
list类型
/往列表右边添加数据/
jedis.rpush(“hobby”,“java”,“c”,“python”);
/范围显示列表数据,要全显示则设置0 -1/
System.out.println(jedis.lrange(“hobby”, 0, -1));
/往列表左边添加数据/
jedis.lpush(“hobby”,“c++”);
System.out.println(jedis.lrange(“hobby”,0,-1));
/弹出列表最左边的数据/
System.out.println(jedis.lpop(“hobby”));
System.out.println(jedis.lrange(“hobby”,0,-1));
/弹出列表最右边的数据/
System.out.println(jedis.rpop(“hobby”));
System.out.println(jedis.lrange(“hobby”, 0, -1));
/获取列表长度/
System.out.println(jedis.llen(“hobby”));
set类型
/往set集合中添加value元素/
jedis.sadd(“myset”,“a”,“b”,“c”,“d”,“h”);
/查询set集合中的所有元素/
System.out.println(jedis.smembers(“myset”));
/删除set集合中的value元素/
jedis.srem(“myset”,“a”,“c”);
System.out.println(jedis.smembers(“myset”));
/随机弹出集合中的元素/
System.out.println(jedis.spop(“myset”, 2));
System.out.println(jedis.smembers(“myset”));
/返回key1中特有元素(差集)/
jedis.sadd(“set1”,“hkj”,“yoona”,“lisa”,“gd”);
jedis.sadd(“set2”,“jack”,“tom”,“hkj”,“yoona”);
jedis.sadd(“set3”,“yoona”,“top”,“gd”);
System.out.println(jedis.sdiff(“set1”, “set2”,“set3”));
/返回两个set集合的交集/
System.out.println(jedis.sinter(“set1”, “set2”));
/返回set集合中元素个数/
System.out.println(jedis.sunion(“set1”, “set3”));
/返回set集合中元素个数/
System.out.println(jedis.scard(“set2”));
sorted_set类型
/存入分数和名称/
jedis.zadd(“players”,2000,“A”);
Map<String,Double> map = new HashMap<>();
map.put(“B”,2000.0);
map.put(“C”,2000.0);
map.put(“D”,2000.0);
/存入分数和名称/
jedis.zadd(“players”,map);
/增加名称对应的分数/
jedis.zincrby(“players”,1000, “C”);jedis.zincrby(“players”,2000, “B”);
/按照分数升序输出名称/
System.out.println(jedis.zrange(“players”, 0, -1));//[A, B, D, C]
/按照分数降序输出名称/
System.out.println(jedis.zrevrange(“players”,0,-1));//[B, C, D, A]
/按照分数升序输出名称/
System.out.println(jedis.zrange(“players”,0, -1));//[A, D, C, B]
/升序返回排名/
System.out.println(jedis.zrank(“players”, “D”));
/降序返回排名/
System.out.println(jedis.zrevrank(“players”, “A”));
/返回元素个数/
System.out.println(jedis.zcard(“players”));
/根据名称删除对应的名称和分数/
jedis.zrem(“players”,“B”);
/按照分数范围统计个数/
System.out.println(jedis.zcount(“players”, 2000, 5000));
/根据排名删除所有元素/
System.out.println(jedis.zremrangeByRank(“players”,0,-1));
使用springboot-redis
阅读量
前端发送异步请求
<script>$(function () {$.post("/articles/info",{id:1},function (data) {$("#view").html(data);})})
</script>阅读数:<span style="color: red;" id="view"></span>
@Autowired
private StringRedisTemplate template;@Override
public Integer incr(Long id) {String key = "article_view_num:" + id.toString();//获取指定key的值Long numbers = template.opsForValue().increment(key);return numbers.intValue();
}
轻松掌握非关系型数据库Redis相关推荐
- 添加lua_非关系型数据库Redis之Lua脚本
[本文详细介绍了非关系型数据库Redis中Lua脚本的基本概念和使用方法,欢迎读者朋友们阅读.转发和收藏!] 1 Lua 简介 Lua 是一个小巧的脚本语言,其设计目的是为了嵌入应用程序中,从而为应用 ...
- python引入redis_实操演练解读非关系型数据库—Redis
在互联网发展的早期,那还是一个各路军阀混战,实战为王的时代,没有所谓正规军,搞定问题才是王道. 当然,那个时期也没有那么多问题,互联网还是个新鲜的词汇,能被称作是网民的人也都是"稀有物种&q ...
- 【机房报修管理系统】后端篇(九) 在SpringBoot配置非关系型数据库Redis
原 [机房报修管理系统]后端篇(九) 在SpringBoot配置非关系型数据库Redis 2019年01月10日 14:18:48 CheungChingYin 阅读数:15 一.前情提要 在上一篇文 ...
- 非关系型数据库-redis应用场景
关系型数据库与非关系型数据库 ----redis的应用场景: 1.redis由于数据的读取和操作都在内存当中操作,读写的效率较高,所以经常被用来做数据的缓存.把一些需要频繁访问的数据,而且在短时间之内 ...
- 介绍非关系型数据库redis
介绍非关系型数据库redis 关系型和非关系型数据库 关系型数据库 非关系型数据库 两个数据库的区别 数据存储方式不同 扩展方式不同 多事务支持性不同 非关系型数据库的产生背景 基于"三高& ...
- NOSQL 非关系型数据库(redis)
NOSQL 非关系型数据库(redis) ---------------------------------------------------------- 0. NoSQL 产品(key-valu ...
- 非关系型数据库——Redis
文章目录 前言 一.Redis是什么? 二.特点 三.应用场景 四.NoSQL 五.常用命令 1 Redis 字符串(String) 2 Redis 哈希(Hash) 3 Redis 列表(List) ...
- Redis基于内存非关系型数据库
Redis基于内存非关系型数据库 Redis:非关系型数据库介绍 特点及优点 1.开源的,使用C编写,基于内存且支持持久化,一般内存的东东关机重启就消失,但它不会. 2.高性能的Key-Value的N ...
- 1、数据库是什么?关系型数据库和非关系型数据库又是什么?
在学习数据库之前,应该先理解什么是数据.本节先介绍数据以及数据库的概念,再对关系型数据库和非关系型数据库的优缺点进行分析. 描述事物的符号称为数据.数据有多种表现形式,可以是数字,也可以是文字.图形. ...
最新文章
- 继续咸鱼——2.18
- 红黑树二叉查找树二叉排序树的理解
- 15个Google面试题以及答案~~~~你会几个?
- Linux系列开坑记(二)-神的编辑器Vim
- sql语句使用foreach报错
- 视界云:CDN{内容分发网络} 知识详解
- 《设计模式之禅》--空对象模式
- python docs库_python库之_thread
- Java版 数字金额大写转换
- 关于键盘事件对象code值
- dp 20190617
- 卸载MYSQL数据库及MYSQL的安装
- 有哪些值得实力推荐的高评分经典电影,VIP视频解析网站推荐十部
- jbox弹窗_jbox很好的弹出层 很好的弹出层 - 下载 - 搜珍网
- 35岁的程序员:第8章,魏建国
- 基于FPGA的万年历
- linux中编辑jar包的内容
- html——表单元素及个人简历实现
- 网易云信im 的聊天记录展示
- BES蓝牙耳机进入待机状态设计
热门文章
- nhibernate mysql配置_NHibernate 连接多数据库怎么配置?
- 做SEO要学会哪些代码?其实并不难
- 前端:jQuery使用eq的作用
- 激光SLAM-地图边界噪点的处理(地图的美化)--图像处理的方法
- html导航栏中加超链接,用CSS设置超链接与导航菜单.ppt
- python编译程序输入上网时间并计算上网费用 计算方法_编一应用程序根据上网时间计算上网费用,计算方法如下: 25元基数 ≤10小时 每小时2元 10且≤50小时 每小...
- 图像处理中的 “掩膜” Mask
- Jenkins Maven打包Jar,部署远程服务器
- c4droid语言游戏,c4droid手机编程软件下载
- GRBL 软件:简单解释的基础知识