1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-25 02:27:10 +08:00

Fix document error with MySQL part

This commit is contained in:
dongzl 2019-04-24 11:54:58 +08:00
parent cb1ce67475
commit e7a988f110
3 changed files with 17 additions and 17 deletions

View File

@ -28,8 +28,8 @@ MySQL的基本存储结构是页(记录都存在页里边)
所以说如果我们写select * from user where indexname = 'xxx'这样没有进行任何优化的sql语句默认会这样做 所以说如果我们写select * from user where indexname = 'xxx'这样没有进行任何优化的sql语句默认会这样做
1. **定位到记录所在的页:需要遍历双向链表,找到所在的页** 1. **定位到记录所在的页需要遍历双向链表,找到所在的页**
2. **从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了** 2. **从所在的页内中查找相应的记录由于不是根据主键查询,只能遍历所在页的单链表了**
很明显在数据量很大的情况下这样查找会很慢这样的时间复杂度为On 很明显在数据量很大的情况下这样查找会很慢这样的时间复杂度为On
@ -60,11 +60,11 @@ MySQL中的索引可以以一定顺序引用多列这种索引叫作联合索
``` ```
select * from user where name=xx and city=xx ; //可以命中索引 select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引 select * from user where name=xx ; // 可以命中索引
select * from user where city=xx; // 无法命中索引 select * from user where city=xx ; // 无法命中索引
``` ```
这里需要注意的是,查询的时候如果两个条件都用上了,但是顺序不同,如 `city= xx and name xx`,那么现在的查询引擎会自动优化为匹配联合索引的顺序,这样是能够命中索引的. 这里需要注意的是,查询的时候如果两个条件都用上了,但是顺序不同,如 `city= xx and name xx`,那么现在的查询引擎会自动优化为匹配联合索引的顺序,这样是能够命中索引的
由于最左前缀原则在创建联合索引时索引字段的顺序需要考虑字段值去重之后的个数较多的放前面。ORDERBY子句也遵循此规则。 由于最左前缀原则在创建联合索引时索引字段的顺序需要考虑字段值去重之后的个数较多的放前面。ORDER BY子句也遵循此规则。
### 注意避免冗余索引 ### 注意避免冗余索引

View File

@ -134,7 +134,7 @@ Java面试通关手册Java学习指南欢迎Star会一直完善下去
当MySQL单表记录数过大时数据库的CRUD性能会明显下降一些常见的优化措施如下 当MySQL单表记录数过大时数据库的CRUD性能会明显下降一些常见的优化措施如下
1. **限定数据的范围:** 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内 1. **限定数据的范围:** 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内;
2. **读/写分离:** 经典的数据库拆分方案,主库负责写,从库负责读; 2. **读/写分离:** 经典的数据库拆分方案,主库负责写,从库负责读;
3 . **垂直分区:** 3 . **垂直分区:**
@ -143,7 +143,7 @@ Java面试通关手册Java学习指南欢迎Star会一直完善下去
**简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。** 如下图所示,这样来说大家应该就更容易理解了。 **简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。** 如下图所示,这样来说大家应该就更容易理解了。
![](https://user-gold-cdn.xitu.io/2018/6/16/164084354ba2e0fd?w=950&h=279&f=jpeg&s=26015) ![](https://user-gold-cdn.xitu.io/2018/6/16/164084354ba2e0fd?w=950&h=279&f=jpeg&s=26015)
**垂直拆分的优点:** 可以使得数据变小在查询时减少读取的Block数减少I/O次数。此外垂直分区可以简化表的结构易于维护。 **垂直拆分的优点:** 可以使得数据变小在查询时减少读取的Block数减少I/O次数。此外垂直分区可以简化表的结构易于维护。
**垂直拆分的缺点:** 主键会出现冗余需要管理冗余列并会引起Join操作可以通过在应用层进行Join来解决。此外垂直分区会让事务变得更加复杂 **垂直拆分的缺点:** 主键会出现冗余需要管理冗余列并会引起Join操作可以通过在应用层进行Join来解决。此外垂直分区会让事务变得更加复杂
@ -156,9 +156,9 @@ Java面试通关手册Java学习指南欢迎Star会一直完善下去
![数据库水平拆分](https://user-gold-cdn.xitu.io/2018/6/16/164084b7e9e423e3?w=690&h=271&f=jpeg&s=23119) ![数据库水平拆分](https://user-gold-cdn.xitu.io/2018/6/16/164084b7e9e423e3?w=690&h=271&f=jpeg&s=23119)
水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题但由于表的数据还是在同一台机器上其实对于提升MySQL并发能力没有什么意义所以 **水平拆分最好分库** 水平拆分可以支持非常大的数据量。需要注意的一点是分表仅仅是解决了单一表数据过大的问题但由于表的数据还是在同一台机器上其实对于提升MySQL并发能力没有什么意义所以 **水平拆分最好分库**
水平拆分能够 **支持非常大的数据量存储,应用端改造也少**,但 **分片事务难以解决** ,跨点Join性能较差逻辑复杂。《Java工程师修炼之道》的作者推荐 **尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度** 一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片尽量选择客户端分片架构这样可以减少一次和中间件的网络I/O。 水平拆分能够 **支持非常大的数据量存储,应用端改造也少**,但 **分片事务难以解决** ,跨点Join性能较差逻辑复杂。《Java工程师修炼之道》的作者推荐 **尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度** 一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片尽量选择客户端分片架构这样可以减少一次和中间件的网络I/O。
**下面补充一下数据库分片的两种常见方案:** **下面补充一下数据库分片的两种常见方案:**
- **客户端代理:** **分片逻辑在应用端封装在jar包中通过修改或者封装JDBC层来实现。** 当当网的 **Sharding-JDBC** 、阿里的TDDL是两种比较常用的实现。 - **客户端代理:** **分片逻辑在应用端封装在jar包中通过修改或者封装JDBC层来实现。** 当当网的 **Sharding-JDBC** 、阿里的TDDL是两种比较常用的实现。

View File

@ -33,7 +33,7 @@
1. **原子性:** 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; 1. **原子性:** 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
2. **一致性:** 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的; 2. **一致性:** 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
3. **隔离性:** 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的; 3. **隔离性:** 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
4. **持久性:** 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 4. **持久性** 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
### 并发事务带来的问题 ### 并发事务带来的问题
@ -56,10 +56,10 @@
**SQL 标准定义了四个隔离级别:** **SQL 标准定义了四个隔离级别:**
- **READ-UNCOMMITTED(读取未提交)** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** - **READ-UNCOMMITTED(读取未提交)** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读**
- **READ-COMMITTED(读取已提交):** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** - **READ-COMMITTED(读取已提交)** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生**
- **REPEATABLE-READ(可重复读):** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生** - **REPEATABLE-READ(可重复读)** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生**
- **SERIALIZABLE(可串行化):** 最高的隔离级别完全服从ACID的隔离级别。所有的事务依次逐个执行这样事务之间就完全不可能产生干扰也就是说**该级别可以防止脏读、不可重复读以及幻读**。 - **SERIALIZABLE(可串行化)** 最高的隔离级别完全服从ACID的隔离级别。所有的事务依次逐个执行这样事务之间就完全不可能产生干扰也就是说**该级别可以防止脏读、不可重复读以及幻读**。
---- ----
@ -101,9 +101,9 @@ SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTE
我们再来看一下我们在下面实际操作中使用到的一些并发控制语句: 我们再来看一下我们在下面实际操作中使用到的一些并发控制语句:
- `START TARNSACTION` |`BEGIN`:显式地开启一个事务。 - `START TARNSACTION` |`BEGIN`显式地开启一个事务。
- `COMMIT`:提交事务,使得对数据库做的所有修改成为永久性。 - `COMMIT`提交事务,使得对数据库做的所有修改成为永久性。
- `ROLLBACK` 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。 - `ROLLBACK`回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
#### 脏读(读未提交) #### 脏读(读未提交)