龙空技术网

⑦ MySql

静无止境S2 149

前言:

此刻我们对“mysql左连接右连接”都比较注意,各位老铁们都想要学习一些“mysql左连接右连接”的相关知识。那么小编也在网络上汇集了一些有关“mysql左连接右连接””的相关文章,希望大家能喜欢,同学们一起来学习一下吧!

1. 数据库的三范式是什么?

2. 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

3. 如何获取当前数据库版本?

4. 说一下 ACID 是什么?

5. char 和 varchar 的区别是什么?

6. float 和 double 的区别是什么?

7. mysql 的内连接、左连接、右连接有什么区别?

8. mysql 索引是怎么实现的?

9. 怎么验证 mysql 的索引是否满足需求?

10. 说一下数据库的事务隔离?

11. 说一下 mysql 常用的引擎?

12. MySQL的锁机制

13. 说一下乐观锁和悲观锁?

14. mysql 问题排查都有哪些手段?

15. 如何做 mysql 的性能优化?

1. 数据库的三范式是什么?

简单概括:1)第一范式:每个字段都不能够在拆分 2)第二范式:满足一范式,非主键依赖主键3)第三范式:满足二范式,非主键之间不互相依赖

解释:

1)原子性,保证字段不可再拆分2)唯一性,保证一个表只针对一个事物3)每一列只与主键有关联,不存在传递依赖

2. 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

如果使用的是InnoDB,ID是6。-- InnoDB表把自增ID的最大值存储到缓存中,重启会丢失重新获取最大值。如果使用的是MyISAM,ID是8。-- MyISAM会把自增ID的最大值存储到文件中,重启不会丢失数据。

4. MySql的ACID 是什么?

原子性:一个事务是一个不可分割的操作,要么什么都不做,要么什么都做。隔离性:多个事务并发执行的时候,每个事务都是独立执行的,相互之间互不影响。持久性:事务一旦提交,它对数据库的操作是永久性的,后续的变化或者异常不对其产生影响。一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

举例说明:张三向李四转100元,转账前和转账后的数据是正确的状态,这就叫一致性,如果出现张三转出100元,李四账号没有增加100元这就出现了数据错误,就没有达到一致性。

MySql如何保证一致性:

1)从数据库层面,必须满足A原子性,I隔离性,D持久性,才能够保证C一致性2)从业务层面,根据代码判断数据库数据是否有效,然后再决定是提交事务还是回滚。

MySql如何保证原子性:

使用InnoDB的undo logundo log是回滚日志,是实现原子性的关键,undo log记录了事务回滚操作时候的需要的信息。

MySql如何保证持久性:

使用InnoDB的redo log当数据发生修改的时候,不仅修改内存信息,还会修改redo log,当执行提交的时候会将redo log进行刷盘;当发生宕机事件,重启后会读取redo log信息,然后再根据undo log 和binlog信息再决定数据是提交还是回滚。

MySql如何保证隔离性:

利用锁和MVCC机制。

5. char 和 varchar 的区别是什么?

一、定长与变长

char是定长的,如果插入的数据小于定义的长度,剩下的空间使用空格填充;varchar是变长的,插入的数据长度是多少,存储的空间就是多少。 因为char是定长的,所以查询数据比较快,但是也浪费了空间。

二、存储的容量

char的最大容量是255字符varchar的容量可以65532个字符

7. mysql 的内连接、左连接、右连接有什么区别?

内连接:inner join on 只展示两表关联的数据。左连接:left join on 左表全展示,右表关联展示,如果右表中不存在关联数据则字段使用null展示右连接:right join on 右表全展示,左表关联展示,如果左表中不存在关联数据则字段使用null展示

8. mysql 索引是怎么实现的?

mysql的索引使用的是B+树。非叶子节点只存储指针不存储数据,节约资源,叶子节点存储数据和指针。B+树是顺序排列的(InnoDB)

对比其它的存储结构的缺点:

哈希表:① 需要存储的数据量大,浪费空间 ② hash冲突问题严重 ③无法进行区间查询二叉树: 层级太多,高度太高,查询效率慢,浪费效率 IO操作太多红黑树:层级太多,高度太高,查询效率慢,浪费效率 IO操作太多,插入时候需要旋转节点,消耗一部分性能来提高查询VAL平衡二叉树:层级太多,高度太高,查询效率慢,浪费效率 IO操作太多,插入时候需要旋转节点,消耗一部分性能来提高查询B树: 非叶子节点也存储数据,浪费大量的内存空间,效率较B+树慢

MyISAM的叶子节点中存储的文件地址(索引文件和存储文件分开存放)

9. 怎么验证 mysql 的索引是否满足需求?

使用explain 查看SQL是如何执行的,查看索引的使用情况

10. 说一下数据库的事务隔离?

隔离级别:

Read uncommitted:读未提交Read committed: 不可重复读Repeatable Read:可重复读Serializable:串行化

解释下几个名词:

脏读:在一个事务中,可以读取其它未提交事务的数据不可重复读:在一个事务中,对于同一个数据,在不同时期读取到的值可能不一样。 例:事务A在刚开始的时候读取A的值为1,期间事务B更新了A的值为2,事务A在后面读取到A的值为2。(针对update操作)可重复读:在一个事务中,对于同一个数据,在不同时期读取到的值都是相同的。例:事务A在刚开始的时候读取A的值为1,期间事务B更新了A的值为2,事务A在后面读取到A的值还是1。(针对update操作)幻读:(针对Insert操作)事务A对一条记录进行修改,在执行修改记录后,事务B插入了一条事务A修改前一模一样的数据,事务A再次进行查询的时候,返回还是存在一样的数据,这就是幻读。

事务的隔离级别就是为了解决上面这几种情况的。

Read Uncommitted 会出现 脏读、不可重复读、幻读Read committed 会出现 不可重复读、幻读Repeatable read 会出现 幻读Serialable 可以解决上面所有的情况

mysql是如何实现事务隔离的:

1)Read uncommitted 事务不加锁操作,效率很快,风险较高2)Serializable 单线程操作,一个事务执行结束后才会执行下一个,效率低下3)Read committed与Repeatable read是使用MVCC(多版本并发控制)来解决的。 每一个版本都会有一个快照,快照在事务开始的时候生成,快照遵循以下规则:

1)当前事务内的更新,可以读到

2)版本未提交,读取不到

3)版本已提交,但是在快照创建前,可以读到

4)版本已提交,但是在快照创建后,读取不到

4)Read committed与Repeatable read之间的区别是,Read Committed在每次执行语句之后都会重新生成一个新的快照,Repeatable read只有在事务开始时候创建一次快照。

11 mysql 常用的引擎

InnoDB与MyISAM的异同

1)InnoDB支持事务,MyISAM不支持事务2)InnoDB支持外键,MyISAM不支持外键3)InnoDB存在聚簇索引,使用B+树结构,数据和索引同时存储在主键索引中,在叶子节点中保存整行的数据,顺序排列,必须存在主键索引(主键->唯一键 ->row_id)。MyISAM不存在聚簇索引,底层也是B+数结构,叶子节点中存储的是指针和数据的存储地址,数据文件和索引文件分开存放。4)InnoDB支持行级锁,MyISAM只支持表级锁5)InnoDB没地方存储表数据总数,MyISAM会存储表数据的总数6)MyISAM表格可以压缩后再查询7)InnoDB在5.5版本后支持全文索引,MyISAM支持全文索引8)InnoDB必须有一个唯一索引,MyISAM可以没有9)InnoDB frm表定义文件 ibd数据文件; MyISAM frm表定义文件 MYD数据文件 MYI 索引文件

补充:

1. 如何选择InnoDB或者MyISAM

1)如何需要使用事务,选择InnoDB,不需要可以使用MyISAM2)如果数据库绝大部分都是读查询,可以使用MyISAM,不然就使用InnoDB3)系统崩溃后MyISAM恢复困难,是否可以接受4)mysql5.5之后,InnoDB是默认引擎,如果不清楚如何选择,那就使用InnoDB

2. 为何推荐使用自增ID作为表的主键使用自增ID作为主键,每次新增数据的时候都只需要在B+树索引的最右侧进行维护,减少了B+树节点频繁的合并和分裂,提高了效率和维护成本

12. MySQL的锁机制

不同的存储引擎支持不同的锁机制。MyISAM和Memory支持表级锁,BDB支持页级锁和表级锁,InnoDB支持行级锁与表级锁。

表级锁:开销小,加锁速度快,锁定粒度大,不会产生死锁,锁冲突概率高,并发度低行级锁:开销大,加锁速度慢,锁定粒度小,会产生死锁,锁冲突概率低,并发度高页级锁:开销介于两者之间,加锁速度一般,会产生死锁,锁定粒度介于两者之间。

MyISAM表锁:

1. 分为表共享读锁和表共享写锁。

当表为读锁的时候,外部线程允许读取操作,但是不允许写操作;当表为写锁的时候,外部线程既不允许读取操作,也不允许写操作。

2. 加锁:当执行select前会加读锁,当执行update、insert、delete前会加写锁。一般都是引擎自动加锁。

显示加锁:Lock tables A read,B read 当SQL中涉及多张表,需要将所有涉及的表一起加锁,这也是为什么MyISAM不会死锁的原因。如果SQL中使用了表的别名,需要将别名一起加锁:lock tables A as a read, B as b read。

3. 并发插入的时候可以修改concurrent_insert:

0 不允许并发插入;1 不存在空洞(中间未删除过记录),允许一个进程在读表的时候,另一个进程在表尾进行插入操作;2 无论有没有空洞,都允许在表尾插入记录。

4. MyISAM的锁调度是写锁优先级高于读锁,即使在等待队列中读锁先到,写锁后到,也会先获取写锁。

可以通过参数来调节。(max_write_lock_count参数可以设置当读锁等待个数到达多少时,降低写请求的优先级)

5. 查看锁争用:show status like 'table%' -- table_locks_waited table_locks_immediate

InnoDB锁:

1. ACID(原子性、一致性、隔离性、持久性)2. 事务隔离(Read uncommitted、Read committed、Repeatable read、Serializable)3. InnoDB的锁:行级锁:共享锁S、排它锁X,表级锁:意向共享锁IS、意向排它锁IX ① 如果不使用索引,那么加的是表锁,而不是行锁 ② InnoDB的锁是加在索引的上,而不是行上面,如果不同的行的索引是同一个,那么会出现锁冲突 ③ 一个表允许存在多个索引,那么不同的索引允许同时对不同的表进行加锁 ④ 如果在一下SQL语句中使用了索引,但是是否使用索引是由mysql通过判断不同执行计划的代价来决定的,如果使用索引后的效率不如全部扫描快,那么就不会使用索引。

4. 间隙锁(next-key lock)

在查询的时候如果查询的是范围类型,那么当申请加共享锁或者排它锁的时候,会对满足条件的数据进行加锁,同时会对满足条件但是并不存在的数据也加锁,这个锁就是间隙锁

例如:select * from table where id >100; 数据库存在id为1,2,3,4--100,101,102,会对101,102的数据加共享锁,会对id大于102的数据加间隙锁。

只有Repeatable read级别的隔离才会存在间隙锁,防止幻读。

如果查询不存在的记录时,也会使用间隙锁。 select * from table where id =103; 对id为103的记录加上间隙锁,会导致插入103记录等待。

对于MyISAM的表锁,主要讨论了以下几点:

(1)共享读锁(S)之间是兼容的,但共享读锁(S)与排他写锁(X)之间,以及排他写锁(X)之间是互斥的,也就是说读和写是串行的。

(2)在一定条件下,MyISAM允许查询和插入并发执行,我们可以利用这一点来解决应用中对同一表查询和插入的锁争用问题。

(3)MyISAM默认的锁调度机制是写优先,这并不一定适合所有应用,用户可以通过设置LOW_PRIORITY_UPDATES参数,或在INSERT、UPDATE、DELETE语句中指定LOW_PRIORITY选项来调节读写锁的争用。

(4)由于表锁的锁定粒度大,读写之间又是串行的,因此,如果更新操作较多,MyISAM表可能会出现严重的锁等待,可以考虑采用InnoDB表来减少锁冲突。

对于InnoDB表,本文主要讨论了以下几项内容:

(1)InnoDB的行锁是基于索引实现的,如果不通过索引访问数据,InnoDB会使用表锁。

(2)介绍了InnoDB间隙锁(Next-key)机制,以及InnoDB使用间隙锁的原因。

在不同的隔离级别下,InnoDB的锁机制和一致性读策略不同。

在了解InnoDB锁特性后,用户可以通过设计和SQL调整等措施减少锁冲突和死锁,包括:

尽量使用较低的隔离级别; 精心设计索引,并尽量使用索引访问数据,使加锁更精确,从而减少锁冲突的机会;

选择合理的事务大小,小事务发生锁冲突的几率也更小;

给记录集显式加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再请求排他锁,这样容易产生死锁;

不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大大减少死锁的机会;

尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响; 不要申请超过实际需要的锁级别;除非必须,查询时不要显示加锁;

对于一些特定的事务,可以使用表锁来提高处理速度或减少死锁的可能。

标签: #mysql左连接右连接