From e7a988f110c66510de7eb10d3eccc2ea3e9c2b5e Mon Sep 17 00:00:00 2001 From: dongzl Date: Wed, 24 Apr 2019 11:54:58 +0800 Subject: [PATCH] Fix document error with MySQL part --- docs/database/MySQL Index.md | 10 +++++----- docs/database/MySQL.md | 8 ++++---- ...\276\346\226\207\350\257\246\350\247\243).md" | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/database/MySQL Index.md b/docs/database/MySQL Index.md index f18b4a07..e2e9dc53 100644 --- a/docs/database/MySQL Index.md +++ b/docs/database/MySQL Index.md @@ -28,8 +28,8 @@ MySQL的基本存储结构是页(记录都存在页里边): 所以说,如果我们写select * from user where indexname = 'xxx'这样没有进行任何优化的sql语句,默认会这样做: -1. **定位到记录所在的页:需要遍历双向链表,找到所在的页** -2. **从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了** +1. **定位到记录所在的页:需要遍历双向链表,找到所在的页** +2. **从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了** 很明显,在数据量很大的情况下这样查找会很慢!这样的时间复杂度为O(n)。 @@ -60,11 +60,11 @@ MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索 ``` select * from user where name=xx and city=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子句也遵循此规则。 ### 注意避免冗余索引 diff --git a/docs/database/MySQL.md b/docs/database/MySQL.md index 44eb02aa..2351f825 100644 --- a/docs/database/MySQL.md +++ b/docs/database/MySQL.md @@ -134,7 +134,7 @@ Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下: - 1. **限定数据的范围:** 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内。; + 1. **限定数据的范围:** 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内; 2. **读/写分离:** 经典的数据库拆分方案,主库负责写,从库负责读; 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) - **垂直拆分的优点:** 可以使得行数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简化表的结构,易于维护。 + **垂直拆分的优点:** 可以使得列数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简化表的结构,易于维护。 **垂直拆分的缺点:** 主键会出现冗余,需要管理冗余列,并会引起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) - 水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以 **水平拆分最好分库** 。 + 水平拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以 **水平拆分最好分库** 。 - 水平拆分能够 **支持非常大的数据量存储,应用端改造也少**,但 **分片事务难以解决** ,跨界点Join性能较差,逻辑复杂。《Java工程师修炼之道》的作者推荐 **尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度** ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。 + 水平拆分能够 **支持非常大的数据量存储,应用端改造也少**,但 **分片事务难以解决** ,跨节点Join性能较差,逻辑复杂。《Java工程师修炼之道》的作者推荐 **尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度** ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。 **下面补充一下数据库分片的两种常见方案:** - **客户端代理:** **分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。** 当当网的 **Sharding-JDBC** 、阿里的TDDL是两种比较常用的实现。 diff --git "a/docs/database/\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253(\345\233\276\346\226\207\350\257\246\350\247\243).md" "b/docs/database/\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253(\345\233\276\346\226\207\350\257\246\350\247\243).md" index 800534d7..4cd950d5 100644 --- "a/docs/database/\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253(\345\233\276\346\226\207\350\257\246\350\247\243).md" +++ "b/docs/database/\344\272\213\345\212\241\351\232\224\347\246\273\347\272\247\345\210\253(\345\233\276\346\226\207\350\257\246\350\247\243).md" @@ -33,7 +33,7 @@ 1. **原子性:** 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; 2. **一致性:** 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的; 3. **隔离性:** 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的; -4. **持久性:** 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 +4. **持久性:** 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 ### 并发事务带来的问题 @@ -56,10 +56,10 @@ **SQL 标准定义了四个隔离级别:** -- **READ-UNCOMMITTED(读取未提交):** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** -- **READ-COMMITTED(读取已提交):** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** -- **REPEATABLE-READ(可重复读):** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** -- **SERIALIZABLE(可串行化):** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。 +- **READ-UNCOMMITTED(读取未提交):** 最低的隔离级别,允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读**。 +- **READ-COMMITTED(读取已提交):** 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生**。 +- **REPEATABLE-READ(可重复读):** 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生**。 +- **SERIALIZABLE(可串行化):** 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。 ---- @@ -101,9 +101,9 @@ SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTE 我们再来看一下我们在下面实际操作中使用到的一些并发控制语句: -- `START TARNSACTION` |`BEGIN`:显式地开启一个事务。 -- `COMMIT`:提交事务,使得对数据库做的所有修改成为永久性。 -- `ROLLBACK` 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。 +- `START TARNSACTION` |`BEGIN`:显式地开启一个事务。 +- `COMMIT`:提交事务,使得对数据库做的所有修改成为永久性。 +- `ROLLBACK`:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。 #### 脏读(读未提交) -- GitLab