MySQL知识

MySQL
事务相关
数据库的事务
事务:一组数据库操作,要么全都执行,要么都不执行;
事务特性:ACID. 原子性:事务是最小的执行单位,不可分割,保证事务要么都完成,要么都不完成。
一致性:???执行事务前后,数据保持一致。隔离性:并发访问数据库时:一个事务不被其他事务干扰。持久性:事务一 旦提交,对数据库的改变是持久的
并发事务带来的问题:
脏读:一个事务读取了另一个事务修改但未提交的数据。
丢失修改:数据被两个事务连续修改,第一个事务的修改丢失了。
不可重复读,一个事务连续读两次数据,但结果不一样。(两次读之间,数据被其他事务修改)。
幻读:一个事务连续读两次数据,读取数据量不一样。(两次读之前,数据被其他事务删除或新增)。
事务隔离级别:
1、读未提交。可以读取尚未提交的数据。能导致脏读,不可重复读,幻读。
2、读已提交。允许读取并发事务已经提交的数据。导致不可重复读,幻读。
3、可重复读。意义在哪????对同一字段,多次读取结果一致。导致幻读。
不可重复读很容易让人陷入一个思维定式那就是 我干嘛需要多次读取一个值还要保证一致
要跳出这个思维看本质:我在事务中会不会受到其他事务的影响?
举个简单的例子 数据校对(只是举个例子体现意思 不用太在意具体的业务)
我要取当前的余额 当前的账单 上个月的余额 我要检验一下数据对不对
我在事务中取了当前的账单和上个月的余额,好嘛,这时候又有新的订单提交了,我再获取余额是不是就不一致了?
4、串行化。所有事务,依次执行。没啥问题。(这个串行化是针对行锁的,不同行的事务可以并发)
设置隔离级别之后,并不是不能并发,而是并发的时候,一个事务的修改数据(绝对读到,提交的才能读到。提交不提交,更新的数据都读不到。提交不提交,增删的数据都读不到),什么时候才能被另一个事务读到。但彼此的逻辑操作没有影响。
MySQL InnoDB默认支持可重复读,但使用了Next-Key Lock算法避免了幻读的发生。完全达到了保保证事务的隔离要求。但在分布式事务下,一般可串行化。
Innodb和Myisam的区别:
1、MyISAM不支持事务,而Innodb支持事务。2、Myisam是表级锁,而Innodb是行级锁。3外键支持:mysiam表不支持外键,而InnoDB支持。4、count运算:myisam缓存有表的行数,这种缓存只是表行的总数,where筛选无效。而Innodb没有。
MyISAM适合:(1)做很多count 的计算;(2)读密集;(3)没有事务。
InnoDB适合:(1)要求事务;(2)写密集(3)高并发
锁机制
三种并发控制机制:悲观并发控制、乐观并发控制和多版本并发控制。悲观并发控制其实是最常见的并发控制机制,也就是锁;乐观并发控制其实也有另一个名字:乐观锁. MVCC多版本并发控制机制,可以与前两者中的任意一种机制结合使用,以提高数据库的读性能。
乐观锁:在访问数据之前,默认不会有其他事务对此数据进行修改,所以先访问数据,然后再查找在此期间是否有事务修改数据。这不是数据库自带的,需要我们自己去实现,一般基于版本去实现。
悲观锁:
按照锁的粒度把数据库锁分为表级锁和行级锁。
表级锁: 对当前操作的整张表加锁,实现简单,加锁快,不死锁,但并发能力低。
行级锁: 只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。
Record Lock记录锁: 锁住某一行,如果表存在索引,那么记录锁是锁在索引上的,如果表没有索引,那么 InnoDB 会创建一个隐藏的聚簇索引加锁。
Gap LocK间隙锁: 间隙锁是一种记录行与记录行之间存在空隙或在第一行记录之前或最后一行记录之后产生的锁。间隙锁可能占据的单行,多行或者是空记录。 对索引项之间的“间隙”加锁,锁定记录的范围,不包含索引项本身。其他事务不能在锁范围内插入数据,这样就防止了别的事务新增幻影行。
Next-key Lock: 锁定索引项本身和索引范围。NK 是一种记录锁和间隙锁的组合锁。既锁住行也锁住间隙。即Record Lock和Gap Lock的结合。可解决幻读问题。
根据是否独占,锁又可以分为共享锁和排他锁。
共享锁(Share Locks,简记为S)又被称为读锁,其他用户可以并发读取数据,但任何事务都不能获取数据上的排他锁,直到已释放所有共享锁。
排它锁((Exclusive lock,简记为X锁))又称为写锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。
Innodb同时支持行锁和表锁。但行锁和表锁的同时存在会发生冲突,如A申请了行共享锁,而B再申请表互斥锁。这时B不仅需要查看是否已经存在其他表锁,以及逐个查看是否存在行锁,效率太低。于是又引入了意向锁。意向锁是一种表级锁,用来指示接下来的一个事务将要获取的是什么类型的锁(共享还是独占)。意向锁分为意向共享锁(IS)和意向独占锁(IX),依次表示接下来一个事务将会获得共享锁或者独占锁。
意向共享锁(IS):事务打算给数据行加共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
在意向锁存在的情况下,事务A必须先申请表的意向共享锁,成功后再申请一行的行锁。而事务B发现表上有意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。
而且,申请意向锁的动作是数据库自动完成的,不需要我们手动申请。

MVCC多版本并发控制(Multiversion Concurrency Control),多版本控制: 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。
每一个写操作都会创建一个新版本的数据,读操作会从有限多个版本的数据中挑选一个最合适的结果直接返回;在这时,读写操作之间的冲突就不再需要被关注,而管理和快速挑选数据的版本就成了 MVCC 需要解决的主要问题。
各数据库中MVCC实现并不统一,MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作;

对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列:(trx_id事务ID、roll_pointer上个版本指针,其实还有一个row_id的隐藏列但这里用不着);
每次对记录进行改动,都会把对应的事务id赋值给trx_id隐藏列,也会把旧的版本写入到undo日志中;
所以在并发情况下,一个记录可能存在多个版本,通过roll_pointer形成一个版本链。MVCC的核心任务就是:判断一下版本链中的哪个版本是当前事务可见的。这就有了ReadView的概念,这个ReadView中主要包含当前系统中还有哪些活跃的读写事务,把它们的事务id放到一个列表中,我们把这个列表命名为为m_ids;根据ReadView的活跃事务ID列表和版本链事务ID进行比较找出可见的事务ID最大的版本:
1、如果版本的trx_id属性值小于m_ids列表中最小的事务id,表明生成该版本的事务在生成ReadView前已经提交,所以该版本可以被当前事务访问。
2、如果版本的trx_id属性值大于m_ids列表中最大的事务id,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。
3、被访问版本的trx_id属性值在m_ids列表中最大的事务id和最小事务id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。
MVCC只在读已提交和可重复读这两个隔离机制下运行。这两个隔离机制下MVCC实现方式的区别就在于:读已提交是每次读取数据前都生成一个ReadView;而可重复读,是在第一次读取数据时生成一个ReadView,后序的重复查询就不再生产ReadView了。
总结:
多版本并发控制指的就是在使用READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执行普通的SEELCT操作时访问记录的版本链的过程,这样子可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。READ COMMITTD、REPEATABLE READ这两个隔离级别的一个很大不同就是生成ReadView的时机不同,READ COMMITTD在每一次进行普通SELECT操作前都会生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复这个ReadView就好了。

Mysql死锁处理方式1、等待,直到超时,事务自动回滚。2、发起死锁检测, 回滚一个事务,让其他事务执行。

死锁检测,构建一个以事务为起点,锁为边的有向图,看是否存在环。

索引相关
索引优缺点:(1) 优点:加快检索速度(2)缺点:(a)创建索引和维护索引需要耗费时间(b)索引需要占用空间 (c)进行数据的增删改时候需要动态维护索引
索引类型:主键索引,唯一索引,全文索引,普通索引,复合索引。
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。但是有缺点。1、不能使用范围查询。2、无法利用索引的数据来避免任何排序运算;3、不支持多列联合索引的最左匹配规则;4、任何时候都不能避免表扫描。5、存在所谓的哈希碰撞问题。
所以我们都用B+树,只有叶子节点存储数据,其他的节点只是起到索引的作用。平衡,性能稳定,每次查询的次数都是树的高度。
索引是一种数据结构。索引本身很大,不可能全部存储在内存中,因此索引以索引表的形式存储在磁盘中。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。
M阶B树:

1、 树中每个结点至多有m个子结点(即M阶);
2、 若根结点不是叶子结点,则至少有2个子结点;
3、 除根结点和叶子结点外,其它每个结点至少有ceil(m/2)个子结点;即中间节点最少有ceil(m/2)个子结点。
4、 所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息;
5、 有k个子结点的非终端结点恰好包含有k-1个关键字(单节点里元素).
每个节点中元素个数n必须满足: [ceil(m / 2)-1]<= n <= m-1。(即M阶树单节点最多有M-1个元素)
每个结点中关键字从小到大排列,并且当该结点的孩子是非叶子结点时,该k-1个关键字正好是k个孩子包含的关键字的值域的分划.
B+树的不同之处:非叶子节点只存储键值信息。数据记录都存放在叶子节点中。所有叶子节点之间都有一个链指针。
B+树的优点:
1、B+树中间节点不存放数据,所以同样大小的磁盘页上可以容纳更多节点元素,IO次数更少。
2、B+树的查询必须最终找到叶子节点,而B-树只需要找到匹配的元素即可。B+树性能稳定。
3、范围查询方便。B-树只能依靠繁琐的中序遍历,而B+树只需要在链表上遍历即可。
磁盘数据地址:柱面号、盘面号、块号
因为普通的全表查询时间复杂度是O(n);如果是平衡二叉树,或者红黑树,查找时间变成O(log2N),但他们依然不适合做索引。因为索引通常比较大,存于磁盘中,无法一次将全部的索引加载到内存中,每次只能从磁盘中读取一个页到内存中,而平衡二叉树底层实现是数组,逻辑上相邻的节点在物理结构上可能相差很远,因此磁盘IO次数可能很大,平衡二叉树没能充分利用磁盘预读功能。磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理。红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
B树的每个节点可以存储多个关键字,它将节点大小设置为磁盘页的大小,充分利用了磁盘预读的功能。每次读取磁盘页时就会读取一整个节点。也正因每个节点存储着非常多个关键字,树的深度就会非常的小。进而要执行的磁盘读取操作次数就会非常少,更多的是在内存中对读取进来的数据进行查找。
logm(n+1)<= h <=log(ceil(m/2)) (n+1)/2 + 1
B+树的关键字全部存放在叶子节点中,非叶子节点用来做索引,而叶子节点中有一个指针指向一下个叶子节点。做这个优化的目的是为了提高区间访问的性能。而正是这个特性决定了B+树更适合用来存储外部数据。
二叉查找树BST:查找最好时间复杂度O(logN),最坏时间复杂度O(N)。插入删除的实现简单,时间复杂度一致。
平衡二叉查找树AVL:查找的时间复杂度维持在O(logN),不会出现最差情况 .AVL树在执行每个插入操作时最多需要1次旋转,其时间复杂度在O(logN)左右。 AVL树在执行删除时代价稍大,一次删除操作最多需要O(logN)次旋转,执行每个删除操作的时间复杂度需要O(2logN)。
查找 效率最好情况下时间复杂度为O(logN).
插入和删除操作改变树的平衡性的概率要远远小于AVL(RBT不是高度平衡的)。因此需要的旋转操作的可能性要小,而且一旦需要旋转,插入一个结点最多只需要旋转2次,删除最多只需要旋转3次(小于AVL的删除操作所需要的旋转次数)。虽然变色操作的时间复杂度在O(logN),但是实际上,这种操作由于简单所需要的代价很小。

聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序;
非聚簇索引的解释是:索引顺序与数据物理排列顺序无关;
MyISAM使用的是非聚簇索引:非聚簇索引的数据表和索引表是分开存储的。主索引和辅助索引几乎是一样的,叶子节点存储的是指向数据的物理地址。
Innodb使用的是聚簇索引。聚簇索引的主键索引的叶子结点存储的是键值对应的数据本身,辅助索引的叶子结点存储的是键值对应的数据的主键键值。
  B+树有主键索引和辅助索引两种;;主键索引就是按照表中主键的顺序构建一颗B+树,并在叶节点中存放表中的行记录数据,一个表只能有一个主键索引。而辅助索引,叶节点并不存储行记录数据,仅仅是主键。通过辅助索引查找到对应的主键,最后在聚集索引中使用主键获取对应的行记录。(这个叫回表查询???)

最左前缀原则:mysql索引可以引用多列,叫联合索引,如果查询条件精确匹配联合索引的左边连续一列或者多列,则查询命中索引。a,b,c的联合索引,(a,c)可以命中a,c不能命中。
联合索引并不是全部不中,或者全部中。可以只命中一部分,例如单单命中A.
MySQL 的查询优化器会自动调整 where 子句的条件顺序以使用适合的索引,不过建议 where 后的字段顺序和联合索引保持一致,养成好习惯。

组合索引(大于等于2小于等于3)也是建立一个B+树,只不过非叶子节点存储的是第一个列。叶子节点组合的列都有,中了第一列之后,然后安装其他的列索引搜查。
联合索引的好处:利用覆盖索引,避免回表操作。
而且对于两个单列查询返回行较多,同时查返回行较少,联合索引更高效。

Explain语句的字段:
ID: SELECT的查询序列号;
select_type:示查询中每个select子句的类型
(1) SIMPLE(简单SELECT,不使用UNION或子查询等)
(2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
(3) UNION(UNION中的第二个或后面的SELECT语句)
(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
(5) UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)
(6) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)
(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)
(8) DERIVED(派生表的SELECT, FROM子句的子查询)
(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
Table:显示这一步所访问数据库中表名称,
Type对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。
ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
All:全表扫描。index: full index scan,遍历索引树。range:只检索给定范围的行,使用一个索引来选择行
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
possible_keys:指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
Key:显示MySQL实际决定使用的键(索引),必然包含在possible_keys中
key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)
ref:列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
rows:估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数、
xtra: 含MySQL解决查询的详细信息,有以下几种情况:
Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by
Using filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”
Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Impossible where:这个值强调了where语句会导致没有符合条件的行(通过收集统计信息不可能存在结果)。
Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
No tables used:Query语句中使用from dual 或不含任何from子句

其他优化地方:
强制类型转换会全表扫描。Varchar 的 phone = ‘123344’,别用 123345数字。
使用短索引(又叫前缀索引)来优化索引。
存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。范围列可以用到索引(联合索引必须是最左前缀),但是范围列后面的列无法用到索引,索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引。
利用覆盖索引来进行查询操作,避免回表。

什么时候要使用索引?
主键自动建立唯一索引;
经常作为查询条件在WHERE或者ORDER BY 语句中出现的列要建立索引;
作为排序的列要建立索引;(单纯的order by 不会用到索引,但如果在where中出现,就可以用索引了。)
查询中与其他表关联的字段,外键关系建立索引
高并发条件下倾向组合索引;
用于聚合函数的列可以建立索引,例如使用了max(column_1)或者count(column_1)时的column_1就需要建立索引
什么时候不要使用索引?
经常增删改的列不要建立索引;
有大量重复的列不建立索引;
表记录太少不要建立索引。只有当 数据库里已经有了足够多的测试数据时,它的性能测试结果才有实际参考价值。如果在测试数据库里只有几百条数据记录,它们往往在执行完第一条查询命令之后就被全部加载到内存里,这将使后续的查询命令都执行得非常快–不管有没有使用索引。只有当数据库里的记录超过了1000条、数据总量也超过了MySQL服务器上的内存总量时,数据库的性能测试结果才有意义。

覆盖索引:
如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称 之为“覆盖索引”。我们知道在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值。最终还是要“回表”,也就是要通过主键再查找一次,这样就会比较慢。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作!InnoDB存储引擎支持覆盖索引,即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。SQL只需要通过索引就可以返回查询所需要的数据,而不必通过二级索引查到主键之后再去查询数据。
解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。

聚集索引:
聚集索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的即为整张表的行记录数据。
辅助索引:
辅助索引,也叫非聚集索引。和聚集索引相比,叶子节点中并不包含行记录的全部数据。

SQL优化的一些部分:
如何避免全表扫描?
1、where字句别用or链接,可以union all.2、in和not in也慎用,可以between and. 3.避免对字段进行null值判断。4,where字句别用!=和<>操作符5、别用以通配符开头的like的查询。6、别在where子句对字段进行表达式操作和函数操作。 7任何地方都不要使用 select * from t。8、尽量使用数字型字段。9、复合索引尽量满足最左前缀原则。10,在查找唯一一条数据的时候,使用limit 1.10、类型不一致会导致失效,例如字符串不加单引号会导致索引失效。
索引优化:
1、根据最左前缀原则,我们一般把排序分组频率最高的列放在最左边
2、模糊查询以%为开始的查询,只能使用全文索引来进行优化。
3、使用短索引。对串列进行索引,如果可能应该指定一个前缀长度。

in与exists的区别。使用上,in 后面的查询返回结果只能有一个字段。而exists没有限制。
本质上: A exists B;exists相当于遍历外面A,看A中数据是否存在于B。而in,相当于将结果集B分解开,用or相连,相当于做多次的查询。
exists相当于查询筛选,in则是多次查询;
1、如果查询的两个表大小相当,那么用in和exists差别不大。
2、如果两个表中一个表大,另一个是表小,那么IN适合于外表大而子查询表小的情况。
3、如果两个表中一个表大,另一个是表小,EXISTS适合于外表小而子查询表大的情况。
in不会使用索引搜索,会全表扫描。

数据量过大:
1、查询时限定数据范围。2、读写分离,主写从读。3、垂直分区4、水平分区.

数据库相关操作语句
数据库范式:1NF:每个关系的属性都是原子的,不可能分割。每一个列只有一个值。
2NF: 如果关系模式R是1NF,且每一个非主属性完全依赖(而不能部分依赖)于候选建,那么就称R是第二范式。
3NF:如果关系模式R是2NF,且关系模式R(U,F)中的所有非主属性对任何候选关键字都不存在传递依赖,则称关系R是属于第三范式。
BCNF: BC范式(BCNF):符合3NF,并且,主属性不依赖于主属性

内连接NNER JOIN:内连接是一种一一映射关系,就是两张表都有的才能显示出来
左连接LEFT JOIN: 左连接是左边表的所有数据都有显示出来,右边的表数据只显示共同有的那部分,没有对应的部分只能补空显示.
右连接RIGHT JOIN:右连接,右边表的所有数据都会显示出来,左边的只会出现共同的那部分,其他的空。
全连接、外连接Outer Join : 查询出左表和右表所有数据,但是去除两表的重复数据

MySQL中一条SQL语句的执行过程
查询sql的执行语句:
1、客户端通过TCP连接发送连接请求到mysql连接器,连接器会对该请求进行权限验证及连接资源分配。
2、建立连接后客户端发送一条语句,mysql收到该语句后,通过命令分发器判断其是否是一条select语句,如果是,在开启查询缓存的情况下,先在查询缓存中查找该SQL是否完全匹配,如果完全匹配,验证当前用户是否具备查询权限,如果权限验证通过,直接返回结果集给客户端,该查询也就完成了。如果不匹配继续向下执行。
3、如果在查询缓存中未匹配成功,则将语句交给分析器作语法分析,MySQL需要知道到底要查哪些东西,如果语法不对,就会返回语法错误中断查询。
4、分析器的工作完成后,将语句传递给预处理器,检查数据表和数据列是否存在,解析别名看是否存在歧义等。
5、语句解析完成后,MySQL就知道要查什么了,之后会将语句传递给优化器进行优化(通过索引选择最快的查找方式),并生成执行计划。
6、之后交给执行器去具体执行该语句,在执行之前,会先检查该用户是否具有查询权限,如果有,继续执行该语句。执行器开始执行后,会逐渐将数据保存到结果集中,同时会逐步将数据缓存到查询缓存中,最终将结果集返回给客户端。

group by语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。
SELECT DEPT, MAX(SALARY) AS MAXIMUM FROM STAFF GROUP BY DEPT :每个部分的最高薪水

SELECT DEPT, sum( SALARY ) AS total FROM STAFF GROUP BY DEPT,每个部门的总薪水

having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。我的理解就是真实表中没有此数据,这些数据是通过一些函数生存。
SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region HAVING SUM(area)>1000000
SELECT DEPT, MAX( SALARY ) AS MAXIMUM, MIN( SALARY ) AS MINIMUM FROM staff GROUP BY DEPT
HAVING COUNT( * ) >2 ORDER BY DEPT

查询最近N天(不超过30天)某一款产品的订单。从第10条开始取5条,ID从大到小倒序。
select * from table limit 9,5;#从0开始
写代码 创建索引
CREATE (UNIQUE/FULLTEXT/) INDEX indexName ON mytable(username(length));
ALTER table tableName ADD INDEX indexName(columnName)
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length)) );

主从复制架构相关

数据库主从复制:
复制的用途:1、读写分离,提供数据库性能和并发能力。2、实时备灾,用于故障切换。
复制存在的问题:1、主库宕机后,数据可能丢失。2、主库写压力大时,复制可能延时。复制延迟怎么解决???
复制原理:主从复制是myql内带功能,是一个异步的过程,把主库的二进制日志文件binlog,复制到从库上,然后从库在本地完全顺序的执行日志中的各种操作。
复制过程:1、主节点log dump线程:当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。2、从节点I/O线程:当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点bin log dump 进程发来的更新之后,保存在本地relay-log中。3、从节点SQL线程:SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。
MySQL 主从复制默认是异步的模式:
异步复制:主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理;主节点不会主动push bin log到从节点;
半同步模式:这种模式下主节点只需要接收到其中一台从节点的返回信息,就会commit;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性。半同步模式不是mysql内置的,需要装插件开启半同步模式。
全同步模式:全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。
binlog记录格式:1、基于SQL语句的复制:记录会修改数据的sql语句到binlog中,减少了binlog日志量,节约IO,提高性能。某些情况:会导致主从节点中数据不一致。2、基于行的复制:将SQL语句分解为基于Row更改的语句并记录在bin log中,也就是只记录哪条数据被修改了,修改成什么样。优点:解决了特定情况下的存储过程、或者函数、或者trigger的调用或者触发无法被正确复制的问题。缺点日志量太大。3、混合方式:能语句就语句,不能语句就切换行。

数据库用到了读写分离,那你知不知道这样做会有什么问题:
在从库上会读到系统的一个过期状态”的现象,暂且称之为“过期读”。
强制走主库方案其实就是,将查询请求做分类,对于必须要拿到最新结果的请求,强制将其发到主库上。
sleep 方案:主库更新后,读从库之前先 sleep 一下。具体的方案就是,类似于执行一条 select sleep(1) 命令。

mysql主从复制存在的问题:
主库宕机后,数据可能丢失
从库只有一个sql Thread,主库写压力大,复制很可能延时
解决方法:
半同步复制—解决数据丢失的问题
并行复制—-解决从库复制延迟的问题(并行是指从库多线程apply binlog库级别并行应用binlog,同一个库数据更改还是串行的(5.7版并行复制基于事务组)设置)

Mysql逻辑架构可以分为两层:服务层和存储引擎。服务层:Mysql的核心服务功能,查询语句解析,缓存,词法语法分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值