朋友圈数据缓存在手机内存,视频大量弹幕即海量数据先缓存再写入关系型数据库。如下两个存储文件第一次用是没有的。如下蓝横线是上一行的快捷方式,右击属性最后加上空格。。.conf文件路径。Mysql默认3306端口,tomcat默认8080端口。
Nosql产品如下:Redis(c写的)劣势是value类型有5种,没有固定结构。HBase数据库分布式像二叉树查询效率高,数据不断添加,所以扩展性强。MongoDB像杂物袋,分门别类没必要。
redis-cli.exe命令行客户端不好用,用图形化客户端redis-desktop-manager-0.7.6.15.exe:链接:https://pan.baidu.com/s/1iJZcnSbRsejUgTlfxu_EKQ 提取码:f8ym 。Add New Connection如下:
redis服务器软件关了, 没有reload就不会保存。redis安装后默认有16个仓库,默认使用db0,用select换数据库。
如下list重索序,不需要知道集合长度,遍历只要0到-1索引。
如下理解score是分数可重复。
RDB(粗略)
:每次都保存全部数据,所以保存慢,因为是二进制,所以读取快。如0-15分钟操作2次,拍1次照保存硬盘。但15-27分钟又操作2次(只符合save 900 1策略),这时redis崩溃了,15-30分钟才拍照保存,所以丢失了2条数据。所以不频繁操作会丢数据。
AOF(细)
:写日志不是把整张照记录起来,而是记录一步(保存快),读取慢因为要从头看到尾
才能把整个过程联系起来。AOF只能三者选其一,不像RDB三个策略都在线(默认开启),AOF是RDB(会丢数据)的补丁
。在redis_windows.conf修改appendonly为yes,所以之前将redis_windows.conf文件名添加到快捷方式的目标中。
如下场景:一分钟6*2000=12000次(此时RDB符合save 60 10000,拍一次照,剩下20秒来不及拍,因为太频繁拍照会卡)。为什么先用RDB?因为读取快。
如下放入web/WEB-INF/lib并右击add as library。
package com.itheima01.jedis;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisDemo {
@Test
public void method01(){
String host = "127.0.0.1";
int port = 6379;
Jedis jedis = new Jedis(host, port); // 1. 创建连接,不用连接池
jedis.set("book","thinking"); // 2. 访问redis
jedis.hset("student","name","zs");
jedis.close(); // 3. 关闭连接
System.out.println("测试");
}
@Test
public void method02(){
String host = "127.0.0.1";
int port = 6379;
JedisPoolConfig config = new JedisPoolConfig(); //连接池
config.setMaxTotal(5); //最大连接数
config.setMaxWaitMillis(2000); // 最长等待时间
config.setMaxIdle(2); // 最大空闲数:最多允许两个连接不干活,超过两个会被回收掉,达到释放内存目的
JedisPool pool = new JedisPool(config, host, port); //1. 初始化连接池
Jedis jedis = pool.getResource(); //2. 获取连接
String book = jedis.get("book"); //3. 访问redis
System.out.println(book); //thinking
jedis.close(); //4. 将连接还给连接池
pool.close(); // 销毁连接池,一般只有应用关闭时才用,释放内存
}
@Test
public void method03(){ //测试封装的框架
Jedis jedis = JedisUtil.getResource();
String book = jedis.get("book");
System.out.println(book + "-------");
jedis.close();
}
}
package com.itheima01.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;
public class JedisUtil {
private static JedisPool pool;
/* static{
String host = "127.0.0.1";
int port = 6379;
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(5); //最大连接数
config.setMaxWaitMillis(2000); // 最长等待时间
config.setMaxIdle(2); // 最大空闲数
pool = new JedisPool(config, host, port);
}*/
//如下用jedis.properties替代如上
/*static{
Properties p = new Properties();
InputStream is = JedisUtil.class.getClassLoader().getResourceAsStream("jedis.properties");
try {
p.load(is);
String host = p.getProperty("host");
Integer port = Integer.parseInt(p.getProperty("port"));
Integer maxTotal = Integer.parseInt(p.getProperty("maxTotal"));
Integer maxWaitMillis = Integer.parseInt(p.getProperty("maxWaitMillis"));
Integer maxIdle = Integer.parseInt(p.getProperty("maxIdle"));
//如下同上面
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal); //最大连接数
config.setMaxWaitMillis(maxWaitMillis); // 最长等待时间
config.setMaxIdle(maxIdle); // 最大空闲数
pool = new JedisPool(config, host, port);
} catch (IOException e) { //输入流有异常
e.printStackTrace();
}
}*/
//如下可替代如上
static{
/*
* ResourceBundle : 资源堆,用来替代Properties成为properties文件专属解析类
* 1. 底层: 类加载器 -> 文件必须放在src下
* 2. 只能加载properties文件 -> 文件的后缀名.properties不要写。
*/
ResourceBundle bundle = ResourceBundle.getBundle("jedis");
String host = bundle.getString("host");
Integer port = Integer.parseInt(bundle.getString("port"));
Integer maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
Integer maxWaitMillis = Integer.parseInt(bundle.getString("maxWaitMillis"));
Integer maxIdle = Integer.parseInt(bundle.getString("maxIdle"));
//如下同上面
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal); //最大连接数
config.setMaxWaitMillis(maxWaitMillis); // 最长等待时间
config.setMaxIdle(maxIdle); // 最大空闲数
pool = new JedisPool(config, host, port);
}
public static Jedis getResource(){
Jedis jedis = pool.getResource();
return jedis;
}
}
//jedis.properties文件
host = 127.0.0.1
port = 6379
maxTotal = 5
maxWaitMillis = 2000
maxIdle = 2
//index.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="js/jquery-3.3.1.min.js">script>
<script>
$(function () { //页面加载事件
$.get("/FriendServlet","",function (data) { //data
// console.log(data)
var content = ""
$(data).each(function (index,element) {
content += "- "
+ element.name + ""
})
$("#myid").html(content) //因为- 是html
},"json")
})
script>
head>
<body>
<ul id="myid">
ul>
body>
html>
如下就是index.html效果。
package com.heima.example.web;
import com.heima.example.service.FriendService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/FriendServlet")
public class FriendServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FriendService service = new FriendService(); //调用service层代码
String json = service.findAllFriend();
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(json);
}
}
package com.heima.example.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.example.bean.Friend;
import com.heima.example.dao.FriendDao;
import com.itheima01.jedis.JedisUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;
import redis.clients.jedis.Jedis;
import java.util.List;
/*
* service层: 业务逻辑 + 缓存 cache
* 缓存弊端: 数据不更新 (查询走缓存,如果执行增删改, 重新查询数据库,更新缓存)
* 如上括号里的更新缓存也会存在缓存延迟的情况(如朋友圈删除动态有时也能看见)
* 朋友圈不是实时同步,如果实时同步对服务器来说压力大。好友列表的在线状态是实时同步的,用心跳长连接。
*/
public class FriendService { //service文件夹下
//选中再ctrl + shift + u转为大写,"example_friend_list"变量改了,全局FRIEND_LIST_CACHE常量不用改
public static final String FRIEND_LIST_CACHE = "example_friend_list";
public String findAllFriend() throws JsonProcessingException {
Jedis jedis = JedisUtil.getResource();
String json = jedis.get(FRIEND_LIST_CACHE); //直接从缓存里取
if(json == null){ //就从mysql数据库中取
FriendDao dao = new FriendDao();
List<Friend> list = dao.findAll();
ObjectMapper om = new ObjectMapper();
json = om.writeValueAsString(list); //list转换为json
jedis.set(FRIEND_LIST_CACHE,json); //记得往缓存里放一份json即字符串
System.out.println("从mysql中查");
}else{
System.out.println("从redis中查");
}
jedis.close(); //记得还给连接池,不然5个用完就崩了
return json;
}
}
package com.heima.example.dao;
import com.heima.example.bean.Friend;
import com.heima.example.utils.JdbcUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class FriendDao { //Dao文件夹下
public List<Friend> findAll() {
String sql = "select * from user";
JdbcTemplate template = JdbcUtil.getTemplate();
List<Friend> list = template.query(sql, new BeanPropertyRowMapper<>(Friend.class));
return list;
}
}
package com.heima.example.bean;
public class Friend { //bean文件夹下
private Integer id;
private String name;
private String password;
@Override
public String toString() {
return "Friend{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
如下刷新浏览器index.html页面。
1.
数据库开启缓存,还要避免缓存失效如下第一行:
3.
小结果集适合建索引。如果占表超过50%不适合建索引,因为数据量达到一定量后会走全表扫描:原因是mysql内部有一个优化器进行最优策略即聚集索引和非聚集索引
查询原理,数据量太大会先走非聚集索引,然后才走聚集索引获取数据。太频繁加个redis。
4.
有limit 1,查到一行就不继续往下走。
5.
数据库创建完一次连接后会永久处于连接状态,已经永久连接了,apache还给数据库不断发连接,给数据库增加了压力,大公司会解决这个。
6.
myISAM适合大数据量查询,因为进行update时会进行表锁,这时候读表都是无效的,必须等插入操作完成。innoDB与myISAM相反,且支持B树索引,ACID(事务原子性,一致性,,,),行锁。
7.
大量insert或delete时会把表整个锁起来,导致大量web服务器请求过来进不去表,导致宕机,所以用limit进行拆分。
8.
不同数据类型占用硬盘空间不一样,如果占用硬盘空间小且紧凑,这样硬盘数据读写快。
9.
字段长度统一,数据库计算偏移量轻松。从前端查出来的数据会多出来一些空格,用trim去除空格
再封装进对象。
10.
报错:该对象属性不为null或mysql查询数据为null…,用’空格’。数据库一字段查出赋值到java对象上,如果字段为null会报空指针异常。
11.
enum速度比varchar快。
12.
不管任何方式查询表,最终都会通过主键定位到数据,建立主键会有效提高性能。id主键多用int速度比varchar快。
14.
避免使用rand(),order by rand()把数据库累死。
15.
两个字段类型不一致,索引建不上。
1.冷备份
:适用于myisam引擎,不适用于innoDB引擎:关闭mysql,如下或可以点进book文件夹里将.frm(表结构)和.MYD(表数据)和.MYI(表索引)文件拷贝出来,这三个组合到一起就是一张表,恢复的时候只需把你copy出来的这些文件再重新粘贴回去即可。
2.热备份
:执行mysql安装目录下的bin/里面的这个mysqldump.exe工具。mysqldump是工具 -u是用户名 -p是密码 -A是全部的意思 -d是表结构 -t是表数据 >
是重定向的意思 >
右边是需要输出的路径和文件名。
2.1 全备份
:mysqldump -uroot -p123456 -A > /back/backdb.sql
2.2 备份指定库命令
:mysqldump -uroot -p123456 db1,db2 > /back/backdb.sql
2.3 备份指定表命令
:mysqldump -uroot -p123456 db1 tb1 tb2, db2 tb2> /back/backdb.sql
2.4 备份表结构命令
:mysqldump -uroot -p123456 -A -d > /back/backdb.sql
2.5 备份表数据命令
:mysqldump -uroot -p123456 -A -t > /back/backdb.sql
2.6 恢复
:source命令在执行时会显示详细信息,能看到执行到哪出错了:source /back/backdb.sql
数据库界面化工具(sqlyog navicat)也可以备份,但是从来没用过,数据量太大用增量备份xtrabackup。
float(8,6)小数点前面占2位,小数点后面占6位。
如下同理RIGHT。
如下同理小写LOWER 。
如下右边先显示,后得到记录数。
如上精确到日,需要将它格式化到月如下。
现在可以拿表中字段(datetime shijian)数据进行比较,shijian字段精确到秒需要格式到月份如下。
返回1为true,返回0为false。
如下只需要月份,所以用curdate()。
如下采用period_diff函数,也就是这个月跟字段shijian的间隔为1。