MySQL——分库分表
1.为什么分库分表1.1为什么分库
磁盘存储
业务量剧增,MySQL单机磁盘容量会撑爆,拆成多个数据库,磁盘使用率大大降低。
并发连接支撑
我们知道数据库连接数是有限的。在高并发的场景下,大量请求访问数据库,MySQL单机是扛不住的!高并发场景下,会出现too many connections报错。
当前非常火的微服务架构出现,就是为了应对高并发。它把订单、用户、商品等不同模块,拆分成多个应用,并且把单个数据库也拆分成多个不同功能模块的数据库(订单库、用户库、商品库),以分担读写压力。
1.2为什么分表假如你的单表数据量非常大,存储和查询的性能就会遇到瓶颈了,如果你做了很多优化之后还是无法提升效率的时候,就需要考虑做分表了。一般千万级别数据量,就需要分表。
这是因为即使SQL命中了索引,如果表的数据量超过一千万的话,查询也是会明显变慢的。这是因为索引一般是B+树结构,数据千万级别的话,B+树的高度会增高,查询就变慢啦。MySQL的B+树的高度怎么计算的呢?跟大家复习一下:
InnoDB存储引擎最小储存单元是页,一页大小就是16k。B+树叶子存的是数据,内部节点存的是键值+指针。索 ...
无题
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
设计模式分为三种类型,共23种:
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式。
这些设计模式特别关注对象之间的通信。
创建型模式1.单例模式(Singleton Pattern)提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
意 ...
MyBatis——使用配置文档1
MyBatis 框架第一章 框架的概述1.三层架构mvc:web开发中,使用mvc架构模式。 m:数据, v:视图, c:控制器。
c控制器: 接收请求,调用service对象,显示请求的处理结果。 当前使用servlet作为控制器
v视图: 现在使用jsp, html,css,js。 显示请求的处理结果,把m中数据显示出来。
m数据: 来自数据库mysql, 来自文件,来自网络
mvc作用:
1)实现解耦合。
2)让mvc 各负其职。
3)使的系统扩展更好。更容易维护。
三层架构:
1.界面层(视图层):接收用户的请求,调用service, 显示请求的处理结果的。 包含了jsp,html,servlet等对象。 对应的包controller,
2.业务逻辑层:处理业务逻辑, 使用算法处理数据的。 把数据返回给界面层。 对应的是service包,和包中的很多的XXXService类。 例如: StudentService , OrderService, ShopServic ...
MySQL——Explain语句(select_type)
名称
描述
SIMPLE
Simple SELECT (not using UNION or subqueries)
PRIMARY
Outermost SELECT
UNION
Second or later SELECT statement in a UNION
UNION RESULT
Result of a UNION
SUBQUERY
First SELECT in subquery
DEPENDENT SUBQUERY
First SELECT in subquery, dependent on outer query
DEPENDENT UNION
Second or later SELECT statement in a UNION, dependent on outer query
DERIVED
Derived table
MATERIALIZED
Materialized subquery
UNCACHEABLE SUBQUERY
A subquery for which the result cannot be c ...
MySQL——连接原理
用到的表结构
mysql> SELECT * FROM t1;
+------+------+
| m1 | n1 |
+------+------+
| 1 | a |
| 2 | b |
| 3 | c |
+------+------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM t2;
+------+------+
| m2 | n2 |
+------+------+
| 2 | b |
| 3 | c |
| 4 | d |
+------+------+
3 rows in set (0.00 sec)
1.嵌套循环连接(Nested-Loop Join) 对于两表连接来说,驱动表只会被访问一遍,但被驱动表却要被访问到好多遍,具体访问几遍取决于对驱动表执行单表查询后的结果集中的记录条数。对于内连接来说,选取哪个表为驱动表都没关系,而外连接的驱动表是固定的,也就是说左(外)连接的驱动表就是左边的那个表,右(外)连接的 ...
MySQL——子查询优化
子查询语法注意事项
子查询必须用小括号扩起来。
不扩起来的子查询是非法的,比如这样:
mysql> SELECT SELECT m1 FROM t1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT m1 FROM t1' at line 1
在SELECT子句中的子查询必须是标量子查询。
如果子查询结果集中有多个列或者多个行,都不允许放在SELECT子句中,也就是查询列表中,比如这样就是非法的:
mysql> SELECT (SELECT m1, n1 FROM t1);
ERROR 1241 (21000): Operand should contain 1 column(s)
在想要得到标量子查询或者行子查询,但又不能保证子查询的结果集只有一条记录时,应该使用LIMIT 1语句来限 ...
Redis——RDB快照
Redis为数据的持久化提供了两个技术——「 AOF 日志和 RDB 快照」。
这两种技术都会用各用一个日志文件来记录信息,但是记录的内容是不同的。
AOF 文件的内容是操作命令;
RDB 文件的内容是二进制数据。
常用指令及配置Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave,他们的区别就在于是否在「主线程」里执行:
执行了 save 命令,就会在主线程生成 RDB 文件,由于和执行操作命令在同一个线程,所以如果写入 RDB 文件的时间太长,会阻塞主线程;
执行了 bgsave 命令,会创建一个子进程来生成 RDB 文件,这样可以避免主线程的阻塞;
RDB 文件的加载工作是在服务器启动时自动执行的,Redis 并没有提供专门用于加载 RDB 文件的命令。
Redis 还可以通过配置文件的选项来实现每隔一段时间自动执行一次 bgsave 命令,默认会提供以下配置:
save 900 1 # 900 秒之内,对数据库进行了至少 1 次修改;
save 300 10 # 300 秒之内,对数据库进行了至少 10 次修改;
save 60 10000 ...
Redis——AOF持久化
AOF持久化就是保存写操作命令到日志的持久化方式,只会记录写操作命令,读操作命令是不会被记录的
先执行写操作再进行持久化
优点:
避免额外的检查开销(能写入到日志的内容一定可执行,恢复时一定无错)
不会阻塞当前写操作的执行
缺点:
有丢失风险
可能会给「下一个」命令带来阻塞风险
三种写回策略
Redis 执行完写操作命令后,会将命令追加到 server.aof_buf 缓冲区;
然后通过 write() 系统调用,将 aof_buf 缓冲区的数据写入到 AOF 文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区 page cache,等待内核将数据写入硬盘;
具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。
Redis 提供了 3 种写回硬盘的策略,控制的就是上面说的第三步的过程。
在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填:
三种策略只是在控制 fsync() 函数的调用时机
AOF重写机制Redis 为了避免 AOF 文件越写越大,提供了 AOF 重写机制,当 AOF 文件的大小超过所设定的阈值后 ...
MySQL——访问方法合集
执行查询语句的方式称之为访问方法或者访问类型。可以通过explain语句在执行计划的type列查看。
完整的访问方法如下:system,const,eq_ref,ref,fulltext,ref_or_null,index_merge,unique_subquery,index_subquery,range,index,ALL。
除了All这个访问方法外,其余的访问方法都能用到索引,除了index_merge访问方法外,其余的访问方法都最多只能用到一个索引
建表语句:
CREATE TABLE single_table (
id INT NOT NULL AUTO_INCREMENT,
key1 VARCHAR(100),
key2 INT,
key3 VARCHAR(100),
key_part1 VARCHAR(100),
key_part2 VARCHAR(100),
key_part3 VARCHAR(100),
common_field VARCHAR(100),
PRIMARY KEY (id),
...
一些单例模式的对比
结论先行
Lazy初始化
多线程安全
优点
缺点
饿汉式
是
是
没有加锁,执行效率会提高
类加载时就初始化,浪费内存
懒汉式
否
是
第一次调用才初始化,避免内存浪费
必须加锁 synchronized 才能保证单例,但加锁会影响效率
双重校验锁的懒汉式
是
是
安全且在多线程情况下能保持高性能
getInstance() 的性能对应用程序很关键
静态内部类
是
是
-达到 lazy loading 效果-只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance
可以被反射破坏
枚举类
否
是
-支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化-不能被反射破坏
实现代码:饿汉式/**
* 饿汉式实现单例模式
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
publ ...