【个人博客 hexo】一个小时就搭好属于自己的博客

RECOMMEND

概述 *`Maven`是`Apache`基金组织的一个开源项目,它是一个软件项目管理和综合工具。* 我的整个的后台就是使用`maven`来管理的,在使用之后,可以说是非常方便的。 ---- 安装与配置 安装 第一步:下载镜像 [apache镜像](http://mirrors.hust.edu.cn/apache/maven/)(我下载的是3.3.9) ![镜像](https://img-blog.csdnimg.cn/20200228180943541.png) 第二步:解压缩 我的解压缩目录是`E:\LOMTOM_STU\ecplise\apache-maven-3.3.9` ![路径](https://img-blog.csdnimg.cn/202002281803245.png) 第四步:测试 打开cmd,输入mvn -v 配置 第五步:配置jdk版本与仓库配置(为了更快去下载插件) 打开配置 `apache-maven-3.5.9\conf\ settings.xml` ```xml <profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> <mirrors> <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>central</id> <name>Maven Repository Switchboard</name> <url>http://repo1.maven.org/maven2/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>repo2</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://repo2.maven.org/maven2/</url> </mirror> <mirror> <id>ibiblio</id> <mirrorOf>central</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url> </mirror> <mirror> <id>jboss-public-repository-group</id> <mirrorOf>central</mirrorOf> <name>JBoss Public Repository Group</name> <url>http://repository.jboss.org/nexus/content/groups/public</url> </mirror> <mirror> <id>google-maven-central</id> <name>Google Maven Central</name> <url>https://maven-central.storage.googleapis.com </url> <mirrorOf>central</mirrorOf> </mirror> <!-- 中央仓库在中国的镜像 --> <mirror> <id>maven.net.cn</id> <name>oneof the central mirrors in china</name> <url>http://maven.net.cn/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> ``` 第六步:配置idea 打开idea,点击配置,再点击setting,(如果打开了项目,关闭项目就会出现这个界面,或者直接点击setting)![配置idea](https://img-blog.csdnimg.cn/20200228180458155.png) 配置你的`maven`环境,最后一个仓库地址没有,自己新建一个文件夹就好了![配置idea](https://img-blog.csdnimg.cn/20200228180543357.png) 至此,你的`maven`已经安装好了,并且可以使用了,接下来就是创建你的第一个程序了。 ---- 作者有话 在使用过程中,`maven`给我的最大的感觉就是非常的方便,在引入依赖的时候直接在项目中的`pom`文件写依赖就可以,而不是像我以前一样还要自己在网上下载相应的`jar`包,而且还可能在配置引入`jar`包的时候各种问题。当一次引入依赖的时候他就会下载到你自己配置的仓库,后再引入的时候就不需要再次下载了。可以看到,我的已经有300多M了。 ![](https://img-blog.csdnimg.cn/20200228181812584.png) ---- 作者 > 1、[作者个人网站](https://www.lomtom.top) > 2、[作者CSDN](https://blog.csdn.net/qq_41929184) > 3、[作者博客园](https://www.cnblogs.com/lomtom/) > 4、[作者简书](https://www.jianshu.com/u/fb248de41d92)
2020-02-28
概述 **系列**: [【个人博客设计】](https://blog.csdn.net/qq_41929184/article/details/104441736) [【个人博客设计】框架与插件篇](https://blog.csdn.net/qq_41929184/article/details/104442321) [【个人博客设计】开发工具篇](https://blog.csdn.net/qq_41929184/article/details/104442338) **开发工具**:`IDEA`+`Navicat`+`tomcat`+`Hbuilder`+`微信开发者工具` 1.1、IntelliJ IDEA 对于`java`的开发人员来说,`eclipse`和`IDEA`都是非常不错的ide工具,虽然说IDEA的占用内存多并且不免费,让很多人望而止步,但是不得不说IDEA是我用过最好的java开发工具。等你放弃eclipse去用惯IDEA后,除了刚开始的不适应外,你可能会真的觉得IDEA是真的不错。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222151310235.pngpic_center) > [Intellij IDEA和EclipsE之间的的全面对比](https://blog.csdn.net/github_38885296/article/details/78942657) 1.2、Navicat Premium Navicat是一套快速、可靠并价格相当便宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。 `Navicat Premium` 是一套数据库开发工具,让你从单一应用程序中同时连接 MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL 和 SQLite 数据库。它与 Amazon RDS、Amazon Aurora、Amazon Redshift、Microsoft Azure、Oracle Cloud、MongoDB Atlas、阿里云、腾讯云和华为云等云数据库兼容。你可以快速轻松地创建、管理和维护数据库。 尤其在我们出于学生时代,可能会接触各种不同的数据库,Navicat Premium 是一个非常不错的选择。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222151935930.png) 1.3、tomcat Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。 虽然说springboot有内嵌的服务器,不过我最终的部署还是会用到外置的tomcat,因为我的网站以及微信小程序的接口都是在tomcat的基础上运行的。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222152139958.png) 1.4、Hbuilder `HBuilder`是DCloud(数字天堂)推出的一款支持HTML5的Web开发IDE。 [1] HBuilder的编写用到了Java、C、Web和Ruby。HBuilder本身主体是由Java编写。 快,是HBuilder的最大优势,通过完整的语法提示和代码输入法、代码块等,大幅提升HTML、js、css的开发效率。 前后端分离的前端项目可用hbuilder。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222154253421.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxOTI5MTg0,size_16,color_FFFFFF,t_70) 1.5、微信开发者工具 微信开发者工具是微信官方推出的开发工具,而小程序端我用hbuilder写的,这个只用于最后的调试、预览以及上传 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222154444836.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxOTI5MTg0,size_16,color_FFFFFF,t_70) ---- 作者 > 1、[作者个人网站](https://www.lomtom.top) > 2、[作者CSDN](https://blog.csdn.net/qq_41929184) > 3、[作者博客园](https://www.cnblogs.com/lomtom/) > 4、[作者简书](https://www.jianshu.com/u/fb248de41d92)
2020-02-23
概述 **系列**: [【个人博客设计】](https://blog.csdn.net/qq_41929184/article/details/104441736) [【个人博客设计】框架与插件篇](https://blog.csdn.net/qq_41929184/article/details/104442321) [【个人博客设计】开发工具篇](https://blog.csdn.net/qq_41929184/article/details/104442338) **后端**:`Maven`+`Springboot`+`springsecurity`+`mybatis`+`jpa`+`redis`+`druid`+`lombok`+`pagehelper` **前端**:`editor.md`+`amazeui`+`thymeleaf`+`uni-app`+`colorui` 1、后端框架 1.1、Maven Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法,许多 Apache Jakarta 项目发文时使用 Maven,而且公司项目采用 Maven 的比例在持续增长。--------百度词条 总的来说,maven是 Apache 下的一个纯 Java 开发的开源项目,更是是一个管理工具,用于管理我们的项目,可以对我们所写的 Java 项目进行构建、依赖管理。在一个java项目尤其是springboot项目使用maven可以大大提高我们的开发效率。 1.2、springboot 说起springboot就要从spring的框架说起了,Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。 > spring: > ◆目的:解决企业应用开发的复杂性 > ◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能 > ◆范围:任何Java应用 > 而`springboot`,它的目标是简化了`spring`应用和服务的创建,开发与部署,简化了配置文件,使用嵌入式的web服务器,含有诸多开箱即用的微服务功能,可以和`spring cloud`联合部署。 `spring boot`的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式,用过`springboot`的都知道,`springboot`绝大多数都是自动配置的,而我们要做的就是配置其中的某一个小部分,就可以实现我们需要实现的功能了。 1.3、springsecurity 在项目中,我们难免会用到安全组件,而对于spring与springboot项目来说,springsecurity是一个非常不错的选择。 `Spring Security`,这是一种基于 `Spring AOP` 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。本教程对 Spring Security 的使用进行一个比较全面的简要介绍。 `spring security` 的核心功能主要包括:认证 、授权 、攻击防护 如果你需要用到以上就去使用springsecurity吧。 > > 值得注意的是,在前端使用`thymeleaf`引擎模板的时候我们可以使用`thymeleaf-extras-springsecurity5`来进行前端的显示。 1.4、mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。------百度词条 MyBatis 是一款优秀的基于Java的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 > [MyBatis与JPA的区别](https://www.jianshu.com/p/32ce87c163d6) 1.5、jpa JPA与mybatis一样都是java的持久化框架。相比于mybatis来说,jpa有自己的数据库操作方法,所以sql语句不需要自己写。当然一些复杂的查询还是需要自己来写的。 > [MyBatis与JPA的区别](https://www.jianshu.com/p/32ce87c163d6) 1.6、redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。一般来说我们经常用redis来作为缓存,而其他的功能并不是经常用。 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。 2、前端框架 2.1、editor.md与towxml editor.md是国内开源的一款在线Markdown编辑器,可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。 在这个项目里,我用它来作为MD与html的转换。 > pc端显示使用[editor.md](http://editor.md.ipandao.com/) > 微信小程序端使用[towxml](https://github.com/sbfkcel/towxml) 2.2、amazeui与colorui Amaze UI 是一个轻量级(所有 CSS 和 JS gzip 后 100 kB 左右)、 Mobile first 的前端框架, 基于开源社区流行前端框架编写(使用、参考的项目列表)。 > Amaze是pc端使用的主要ui。 > 小程序端使用的是colorui 2.3、thymeleaf Thymeleaf是一个现代的服务器端Java模板引擎的web和独立的环境。 Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板- HTML,可以正确地显示在浏览器,也可以作为静态原型,允许在开发团队更强大的协作。 一句话描述:thymeleaf;语法简单,功能强大。 2.4、uni-app uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。 ---- 作者 > 1、[作者个人网站](https://www.lomtom.top) > 2、[作者CSDN](https://blog.csdn.net/qq_41929184) > 3、[作者博客园](https://www.cnblogs.com/lomtom/) > 4、[作者简书](https://www.jianshu.com/u/fb248de41d92)
2020-02-23
一、题目描述: 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。 一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点; 如果找到了,删除它。 说明: 要求算法时间复杂度为 O(h),h 为树的高度。 示例: >root = [5,3,6,2,4,null,7] > key = 3 >![](https://img-blog.csdnimg.cn/20210115133530614.png) >给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 > >一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 > ![](https://img-blog.csdnimg.cn/20210115133552237.png) >另一个正确答案是 [5,2,6,null,4,null,7]。 > ![](https://img-blog.csdnimg.cn/20210115133608480.png) 二、解答 分析 解题思路: 首先,这个题目可以根据删除的节点的左右节点来判断。 而找到该节点是非常简单的,因为这棵树是二叉搜索树,而二叉搜索树的特性,左节点的值一定小于该节点值,右节点的值一定大于该节点的值,所以直接搜索就可以找到该值。 所以重点在于怎么判断该节点的左右节点的情况。 大致可以分为四种: 1. 该节点没有左节点,也没有右节点 2. 该节点没有左节点,但有右节点 3. 该节点有左节点,但没有右节点 4. 该节点有左节点,也有右节点 第一种:对于第一种情况,直接将该节点删除即可。 第二种:对于第二种情况,直接删除节点,将左节点代替该节点。 第三种:对于第三种情况:直接删除节点,将右节点代替该节点。 第四种:对于第四种情况,又可以分为三种情况: 1. 该节点的左节点没有右节点,将左节点代替该节点。 2. 该节点的右节点没有左节点,将右节点代替该节点。 3. 对于都有的情况,为了保证二叉搜索树的结构,我们 ① :可以用该节点的左节点最右节点的值代替该节点;②:也可以用该节点的右节点的最左节点的值代替该节点。 >而对于最后的情况,也就是第四种情况的第三种情况, >需要注意 >①中,如果最右节点还有左节点,我们可以用最右节点的左节点的值代替最右节点所在的位置; >②中,如果最左节点还有右节点,我们可以用最左节点的右节点的值代替最左节点所在的位置。 **再一次总结归纳:** 其实,最后第四种情况的第三种就包括了前面所有的方面, 在找到该节点后: 1. 如果该节点的左节点不为空,我们用该节点的左节点最右节点的值代替该节点; 2. 否则,如果该节点的右节点不为空,我们可以用该节点的右节点的最左节点的值代替该节点。 3. 否则,将该节点置空。 找到该节点,非常容易,因为左节点的值一定小于该节点值,右节点的值一定大于该节点的值。 所以,从根节点开始遍历 1. 如果遍历到的节点的值大于该值,该值一定处于该节点的右子树,往右遍历即可。 2. 否则,如果遍历到的节点的值小于该值,该值一定处于该节点的左子树,往左遍历即可。 3. 否则,就是找到了该值,在进行上述操作即可。 >时间复杂度:O(h),其中 n 为树的高度。 代码 ```java /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public TreeNode deleteNode(TreeNode root, int key) { if(root!=null){ if(root.val == key){ if(root.left != null){ root.val = leftMax(root); root.left = deleteNode(root.left, root.val); } else if(root.right != null){ root.val = rightMin(root); root.right = deleteNode(root.right, root.val); } else { root = null; } }else if(root.val>key){ root.left = deleteNode(root.left,key); }else{ root.right = deleteNode(root.right,key); } return root; } return null; } public int rightMin(TreeNode root) { root = root.right; while (root.left != null) root = root.left; return root.val; } public int leftMax(TreeNode root) { root = root.left; while (root.right != null) root = root.right; return root.val; } } ``` > 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户 内存消耗:39.2 MB, 在所有 Java 提交中击败了8.92%的用户 三、官方解答 ```java class Solution { /* One step right and then always left */ public int successor(TreeNode root) { root = root.right; while (root.left != null) root = root.left; return root.val; } /* One step left and then always right */ public int predecessor(TreeNode root) { root = root.left; while (root.right != null) root = root.right; return root.val; } public TreeNode deleteNode(TreeNode root, int key) { if (root == null) return null; // delete from the right subtree if (key > root.val) root.right = deleteNode(root.right, key); // delete from the left subtree else if (key < root.val) root.left = deleteNode(root.left, key); // delete the current node else { // the node is a leaf if (root.left == null && root.right == null) root = null; // the node is not a leaf and has a right child else if (root.right != null) { root.val = successor(root); root.right = deleteNode(root.right, root.val); } // the node is not a leaf, has no right child, and has a left child else { root.val = predecessor(root); root.left = deleteNode(root.left, root.val); } } return root; } } ``` > 参考: > 1、[题目](https://leetcode-cn.com/problems/delete-node-in-a-bst/) > 2、[官方解答](https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/shan-chu-er-cha-sou-suo-shu-zhong-de-jie-dian-by-l/) >本文首发于CSDN,作者:lomtom >原文链接:**[https://blog.csdn.net/qq_41929184/article/details/112662236](https://blog.csdn.net/qq_41929184/article/details/112662236)** >个人网站:**[https://lomtom.top](https://lomtom.top)**,公众号:**博思奥园**,同步更新。 > > **你的支持就是我最大的动力。** ![](https://img-blog.csdnimg.cn/20200405094243147.png)
2021-01-17
一、题目描述: 给定一个无重复元素的有序整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b] 应该按如下格式输出: - "a->b" ,如果 a != b - "a" ,如果 a == b 示例 示例 1: >输入:nums = [0,1,2,4,5,7] 输出:["0->2","4->5","7"] 解释:区间范围是: [0,2] --> "0->2" [4,5] --> "4->5" [7,7] --> "7" 示例 2: >输入:nums = [0,2,3,4,6,8,9] 输出:["0","2->4","6","8->9"] 解释:区间范围是: [0,0] --> "0" [2,4] --> "2->4" [6,6] --> "6" [8,9] --> "8->9" 示例 3: >输入:nums = [] 输出:[] 示例 4: >输入:nums = [-1] 输出:["-1"] 示例 5: >输入:nums = [0] 输出:["0"] 提示: >0 <= nums.length <= 20 -231 <= nums[i] <= 231 - 1 nums 中的所有值都 互不相同 nums 按升序排列 二、解答 分析 解题思路: 1. 遍历整个数组,当相邻的数只相差1时,构成一个区间。 2. 当相邻的数相差大于1时,开始一个新的区间。 3. 当判断开始一个新的区间时,我们需要保存前面的区间。 4. 保存一个区间需要两个值分别记录区间开始的值,当前数的前一个数的值。 5. 唯一值得注意的是处理边界问题。 >时间复杂度:O(n),其中 n 为数组的长度。我们只需要遍历一次数组即可。 空间复杂度:O(1)。只需要常数空间存放若干变量。 代码 ```cpp class Solution { public List<String> summaryRanges(int[] nums) { int length = nums.length; List<String> result = new ArrayList<>(); if(length == 0){ return result; } int start = nums[0]; int now = nums[0]; int i = 1; for(;i < length;i++){ if(now + 1 == nums[i]){ now++; } else{ result.add(start == now?String.valueOf(start):start+"->"+now); start = now = nums[i]; } } result.add(start == now?String.valueOf(start):start+"->"+now); return result; } } ``` > 执行用时:7 ms, 在所有 Java 提交中击败了82.54%的用户 内存消耗:36.9 MB, 在所有 Java 提交中击败了53.76%的用户 改进 1. 因为当前数的前一个数的值,我可以通过当前的下标来获取,所以该值完全没有必要记录,所以可以省略该值 2. 省略该值之后,我只要通过下标来判断即可,所以在循环里,我只要判断前一个数加一与当前值不相等即可 ```java public List<String> summaryRanges(int[] nums) { int length = nums.length; List<String> result = new ArrayList<>(); if(length == 0){ return result; } int start = nums[0]; int i = 1; for(;i < length;i++){ if(nums[i - 1] + 1 != nums[i]){ result.add(start == nums[i - 1]?String.valueOf(start):start+"->"+nums[i - 1]); start = nums[i]; } } result.add(start == nums[i - 1]?String.valueOf(start):start+"->"+nums[i - 1]); return result; } ``` 这样做的好处就是节省了一定的空间。 三、官方解答 官方给出的题解也是一次遍历,但是是用双指针的方法,也就是使用维护下标low 和 high 分别记录区间的起点和终点,和我的大致思想也差不多。 ```cpp class Solution { public List<String> summaryRanges(int[] nums) { List<String> ret = new ArrayList<String>(); int i = 0; int n = nums.length; while (i < n) { int low = i; i++; while (i < n && nums[i] == nums[i - 1] + 1) { i++; } int high = i - 1; StringBuffer temp = new StringBuffer(Integer.toString(nums[low])); if (low < high) { temp.append("->"); temp.append(Integer.toString(nums[high])); } ret.add(temp.toString()); } return ret; } } ``` > 参考: > 1、[题目](https://leetcode-cn.com/problems/summary-ranges/) > 2、[官方解答](https://leetcode-cn.com/problems/summary-ranges/solution/hui-zong-qu-jian-by-leetcode-solution-6zrs/) >本文首发于CSDN,作者:lomtom 原文链接:**[https://blog.csdn.net/lomtom/article/details/112306554](https://blog.csdn.net/lomtom/article/details/112306554)** 个人网站:**[https://lomtom.top](https://lomtom.top)**,公众号:**博思奥园**,同步更新。 你的支持就是我最大的动力。 ![](https://img-blog.csdnimg.cn/20200405094243147.png)
2021-01-10
一、场景引入 前提背景 在某些场景下,例如淘宝京东这样海量的数据,高访问量的场景,无疑对数据库造成了相当大的负载,同时对于系统的稳定性和扩展性提出很高的要求。 而单个服务器所能够提供的服务以及负载都是有限的。 所以,为了系统的问题,以及较快的响应速度或处理能力,在数据库方面就有了集中解决方案,**分库分表,读写分离**,这些都能在一定程度上有效地减小单台数据库的压力。 而本文就是从读写分离角度来一探究竟。 实现原理 主要理解以下三个点就差不多了: **1、主机负责写操作** **2、从机负责读操作** **3、从机自动从主机中同步数据** 然而,我们对于一个新的东西,我们就要提出我们的哲学三问: ~~我是谁?我在那?我要干嘛?~~ **是什么?为什么?怎么做?** 1、什么是读写分离 读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。 2、为什么要读写分离呢? 因为数据库的“写”(写10000条数据到oracle可能要3分钟)操作是比较耗时的。 但是数据库的“读”(从oracle读10000条数据可能只要5秒钟)。 所以读写分离,解决的是,数据库的写入,影响了查询的效率。 3、什么时候要读写分离? 数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用,利用数据库 主从同步 。可以减少数据库压力,提高性能。当然,数据库也有其它优化方案。memcache 或是 表折分,或是搜索引擎。都是解决方法。 4.主从复制、读写分离的基本设计 在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。 > 取自:[读写分离的实现原理及使用场景](https://blog.csdn.net/belalds/article/details/82655786) **这里使用docker进行数据库的安装,docker的优势以及就怎么安装docker就不多做赘述了,感兴趣的可以去翻一下我以前的文章。** 一、安装mysql 这里只安装了一个主机(master),一个从机(slave) ``` docker run --name mysql-master -p 33061:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci docker run --name mysql-salve -p 33062:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ``` 二、配置同步 为什么? 如果不进行同步的配置,那么从机无法获取主机的数据,最终就会导致同步失败。 1、配置主机用户 ``` grant replication slave on *.* to 'lomtom'@'%' identified by '123456' ``` 2、修改配置文件 在从机中的配置文件加入以下参数。 1. 主机 ``` log-bin = /var/lib/mysql/binlog server-id =1 binlog-do-db =lomtomdb ``` 2. 从机 ``` server-id =2 ``` 1、修改配置文件(以master为例) ``` Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA The MySQL Server configuration file. For explanations see http://dev.mysql.com/doc/mysql/en/server-system-variables.html [mysqld] log-bin = /var/lib/mysql/binlog server-id =1 binlog-do-db =lomtomdb pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql log-error = /var/log/mysql/error.log By default we only accept connections from localhost bind-address = 127.0.0.1 Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 ``` 2、拷贝(主从都需要拷贝,以master为例) 如果服务器有vi编辑器,直接使用vi编辑器即可。 ``` docker cp mysql.cnf mysql-master:/etc/mysql/mysql.conf.d/ ``` 3、重启mysql ``` docker restart mysql-master ``` 4、查看是否配置成功 ``` show master status; ``` 如果出现以下数据即为成功。 ![](https://img-blog.csdnimg.cn/20210107122208680.png) 5、在从机(slave)中配置主机(master) ``` 1、配置主机信息 change master to master_host='192.168.43.236',master_port=33061,master_user='lomtom',master_password='123456',master_log_file='binlog.000001',master_log_pos=154; 2、查看从机状态 show slave status; SLAVE_IO_RUNNING ,SLAVE_MYSQL_RUNNING两个值为YES即为正确启动,否则自己根据下方的错误提示修改配置 ``` 三、测试 在第一个数据库(master)创建我们配置的数据库,然后随意修改该数据库的数据,刷新slave,数据同步成功。 四、注意 1、因为在配置当中指定了数据库(lomtomdb),也就是`binlog-do-db`参数,所以从机只会同步主机中的lomtomdb数据库,其他数据库不同步。 2、修改配置文件时,`log-bin`参数所指定的目录一定是要mysql能够操作的文件,也就是说,如果你指定了其他目录,请给予mysql操作权限。 >参考: >[读写分离的实现原理及使用场景](https://blog.csdn.net/belalds/article/details/82655786) >[江南一点雨](https://mp.weixin.qq.com/s/R89aCCFvCvudLp6FUn2JjQ) >本文首发于CSDN,作者:lomtom 原文链接:**[https://blog.csdn.net/qq_41929184/article/details/112306554](https://blog.csdn.net/qq_41929184/article/details/112306554)** 个人网站:**[https://lomtom.top](https://lomtom.top)**,公众号:**博思奥园**,同步更新。 你的支持就是我最大的动力。
2021-01-07

CONTACT ME

You can contact me in the following ways

Copyright © 2019-2020 Made with love By LomTom | 湘ICP备19023870号 | 经历风雨 666 天 6 小时 6 分 6 秒