【面试题】MySQL相关

xiaoxiao2021-02-28  166

1. MySQL常用命令

创建表:create table employee(id int,name varchar(20));修改表结构(列):alter table employee add/modify/drop salary float;修改字符集:alter table employee character set GBK;修改列名:alter table employee change math English int;更改表名:alter table employee rename student;删除表:drop table student;创建索引:create unique index unique_id on employee (id);或alter table employee add fulltext index fulltextidx(id);删除索引:drop index unique_id on employee;或alter table employee drop index fulltextidx;添加数据:insert into student values(1,“W”);删除数据:delete from student where name = ‘Lee’;修改数据:update employee set salary = 5000;查询数据: select distinct English from student;select * from student where English between 80 and 100;select * from student where name like ‘张%’;select name 姓名,math 数学from student where name like ‘张%’ order by 数学 desc;select count(*)/sum(math)/avg(math) from student;select product, sum(price) from orders group by product having sum(price) > 100; 查询日期:select now() from dual;或select date_add(now(),interval 20 minute) from dual;添加外键约束:alter table student add constraint FK_ID foreign key (gid) references grade (id) ;(先添加主表,先修改或删除副表)左外连接查询:select * from dept left join possible on dept. id = possible.dept_id;子查询:select *from department where did>any(select did from employee);备份数据库:mysqldump -u username -p mydb2 >c:/311.sql创建触发器:create trigger newproduct after insert on products for each now select “product added”;

2. 数据库中事物的特征?

事务:start transaction;、commit; 、rollback;

事务的四大特性

原子性:事务是一组不可分割的单位,要么同时成功要么同时不成功一致性:事务前后的数据完整性应该保持一致,隔离性:多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰持久性:一个事务一旦被提交,对数据库中的数据的改变就是永久性的,即使数据库发生故障也不应该对其有任何影响。

读的种类

脏读:一个事务读取到另一个事务未提交的数据不可重复读:一个事务多次读取同一条记录,读取的结果不相同虚读(幻读):一个事务多次查询整表的数据,由于其他事务新增(删除)记录造成多次查询出的记录条数不同。

四大隔离级别

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom Read)读未提交(Read uncommitted)可能可能可能不可重复读(Read committed)不可能可能可能可重复读(Repeatable read)不可能不可能可能可串行化(SERIALIZABLE)不可能不可能不可能

注:mysql 默认是repeatable read 级别!

3. JDBC的使用?

使用步骤

注册驱动:Class.forName(“com.mysql.jdbc.Driver”);建立连接:Connection conn = DriverManager.getConnection(URL, user, password);执行SQL语句:PreparedStatement ps = conn.prepareStatement(sql);PreparedStatement 可用预编译的sql、sql缓存区、有效防止sql注入(OR 1=1 )执行处理结果:ResultSet rs = ps.executeQuery();

常用组件

BeanUtils:对象的拷贝、注册日期类型转换器DbUtils:定义了所有的与数据库操作的方法,简化编码量C3P0连接池:new ComboPooledDataSource();

4. InnodB与MyISAM的区别

建立索引的目的是加快对表中记录的查找或排序,但索引是占用空间的,影响速度。索引类型:主键索引、唯一索引、普通索引、全文索引(FULLTEXT ),而主键索引是特殊的唯一性索引。

MySQL支持MyISAM、InnoDB、MEMORY、MERGE、ARCHIVE多种存储引擎,而默认是InnoDB

MyISAM:独立于操作系统,表锁,不支持外键、事务。存储格式分为静态、动态、压缩表,适合以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性,并发性要求不是很高的情况

InnoDB:默认,行级锁定、外键约束、自动灾难恢复、支持事务。对事物的完整性有比较高的要求,在并发条件下要求数据的一致性,包含很多操作。InnoDB只有通过索引进行检索的时候才会使用行级锁,否则会使用表级锁。

MEMORY:存在内存,为得到最快的响应时间;MERGE:一组MyISAM表的组合;ARCHIVE:归档后仅支持插入和查询。

实现方式:

MyISAM:使用B+ Tree作为索引结构,叶节点存放的是数据记录的地址,索引和实际的数据是分开的,只不过是用索引指向了实际的数据,即非聚集索引。InnoDB:数据本身就是按B+ Tree组织的一个索引结构,叶节点存放的是完整的数据记录,即聚集索引,主键是InnoDB表记录的”逻辑地址“,所以InnoDB要求表必须有主键,MyISAM可以没有。

5. MySQL为什么使用B+树作为索引?

几种索引结构的区别:

B tree:适合在磁盘等直接存储设备上组织动态查找表,因为B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少,这时若要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低;Hash:虽然可以快速定位,但是没有顺序,IO复杂度高。并存在散列冲突问题,一般利用率仅为50%,当存储比例达到一定程度时hash表必须进行扩容才能维持之后的操作。二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。红黑树:树的高度随着数据量增加而增加,IO代价高。

数据结构作为索引的优劣指标:索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数,因为影响MySQL查找性能的主要是磁盘IO次数,大部分是磁头移动到指定磁道的时间花费。

从物理存储结构上说,B-Tree和B+Tree都以页(4K)来划分节点的大小,但是由于B+Tree中中间节点不存储数据,因此B+Tree能够在同样大小的节点中,存储更多的key,提高查找效率。

B+树可以对叶子结点顺序查找,因为叶子结点存放了数据结点且有序

6. MySQL的自增主键用完了怎么办?

自增主键若是无符号整型,存储范围约43亿!若自增id达到最大值,数据继续插入时会报一个主键冲突异常。解决方法:将Int类型改为BigInt

怎么在线上修改列的数据类型?

使用mysql5.6+提供的在线修改功能:不支持并发的DML,会导致这张表无法进行更新类操作。借助第三方工具:pt-osc、gh-ost等。改从库表结构,然后主从切换。

终极答案:自增主键达到最大值前,进行分库分表。

7. MySQL主从复制的原理?

主库将变更写binlog日志,然后从库连接到主库之后,从库有一个IO线程,将主库的binlog日志拷贝到自己本地,写入relay中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容,即在本地再次执行一遍SQL。出现的问题: 主库数据丢失问题:使用半同步(semi-sync)复制,即从库将日志写入本地的relay log后,会返回一个ack给主库,主库接收到至少一个从库的ack之后才会认为写操作完成了。主从同步延时问题:并行复制,从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。

8. 分库分表的实现

如何拆分?

水平拆分:将一个表的数据分别保存到多个库的多个表中,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。垂直拆分:将一个有很多字段的表给拆分成多个表或多个库。每个库表的结构都不一样,每个库表都包含部分字段。

分库分表的方式?

hash取模:数据分布均匀,扩容麻烦。range:方便扩容,容易产生热点问题,即大部分的请求都是访问最新的数据。

分库分表后的主键id怎么生成?

数据库的自增ID:简单、高效,但高并发、分布式情况下性能比较低。Flicker:充分借助数据库的自增ID机制,提供高可靠性,生成的ID有序。但占用两个独立的MySQL实例,成本较高。Redis的原子操作INCR和INCRBY:id有序,但增加了系统复杂度。UUID:扩展性好,但无法保证趋势递增,作为主键性能差。Snowflake算法:高性能、低延迟。 但依赖机器的时钟,如果服务器时钟回拨,会导致重复ID生成,分布式环境的每个服务器的时钟不可能完全同步,所以可能会出现非全局递增的情况。

拆分后的查询过程?

分库分表后利用一主多从或多主多从解决读写压力

9. MySQL的死锁问题

9.1 MySQL死锁的原因有哪些?
不同表相同记录行锁冲突相同表记录行锁冲突不同索引冲突gap锁冲突(RR有gap锁,但RC无)
9.2 如何尽可能避免死锁?
以固定的顺序访问表和行。比如对第2节两个job批量更新的情形,简单方法是对id列表先排序,后执行,这样就避免了交叉等待锁的情形;又比如对于3.1节的情形,将两个事务的sql顺序调整为一致,也能避免死锁。大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添加上锁,死锁的概率大大增大。

其它

InnoDB一棵B+树可以存放多少行数据?

约2千万, InnoDB存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在B+树中叶子节点存放数据,非叶子节点存放键值+指针。索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而在去数据页中查找到需要的数据;

一条SQL执行慢的原因?

概率很慢:数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘,或是执行的时候,遇到锁,如表锁、行锁。一直很慢:数据库选错了索引,或是没有用到索引,例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。

MySQL中乐观锁与悲观锁的实现?

乐观锁通过记录数据版本来实现,即通过在表中添加版本号字段来作为是否可以成功提交的关键因素。悲观锁可以通过select * for update加上排它锁。

主键索引和普通索引的区别?

主键索引的叶子结点存放了整行记录,普通索引的叶子结点存放了主键ID,查询的时候需要做一次回表查询;不一定要回表查询,当查询的字段刚好是索引的字段或者索引的一部分,就可以不用回表,这也是索引覆盖的原理。

为什么官方建议使用自增长主键作为索引?

结合B+Tree的特点,自增主键是连续的,在插入过程中尽量减少页分裂,即使要进行页分裂,也只会分裂很少一部分。并且能减少数据的移动,每次插入都是插入到最后。总之就是减少分裂和移动的频率。若主索引不是自增的(id作主键),那么每次插入新的数据,都很可能对B+Tree的主索引进行重整,影响性能。因此,尽量以自增id作为InnoDB的主索引。

MySQL如何实现Rollback?

数据库在写入数据之前是先对数据的改动写入redolog和undolog,然后在操作数据,如果成功提交事务就会讲操作写入磁盘;如果失败就会根据redolog和undolog逆向还原到事务操作之前的状态。redolog记录物理日志,记录的是数据页的物理修改,用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。undolog记录逻辑日志,它的作用是提供回滚和多个行版本控制(MVCC)。

MRR、ICP和BKA是什么?

MRR(Multi-Range Read)是优化器将随机 IO 转化为顺序 IO 以降低查询过程中 IO 开销的一种手段。ICP(Index Condition Pushdown)是mysql使用索引从表中检索行数据的一种优化方式,并会大大减少行锁的个数。ICP的目标是减少从基表中全纪录读取操作的数量,从而降低IO操作。对于InnoDB表,ICP只适用于辅助索引。BKA(Batched Key Access)是提高表join性能的算法。当被join的表能够使用索引时,就先好顺序,然后再去检索被join的表。对这些行按照索引字段进行排序,因此减少了随机IO。如果被Join的表上没有索引,则使用老版本的BNL(Block Nested Loop)策略。

本人才疏学浅,若有错,请指出,谢谢! 如果你有更好的建议,可以留言我们一起讨论,共同进步! 衷心的感谢您能耐心的读完本篇博文!

转载请注明原文地址: https://www.6miu.com/read-17591.html

最新回复(0)