Nacos的超级大坑你踩了吗?
前言
1.1总结:
1存储引擎:
2 字符集和校对规则:
3 索引:
4 缓存:
5 事务:
6 锁:
7 大表优化的几种方案:
总结
前言
现在java程序员面试的话,数据库的话题是逃不掉的?面试官会问你常用什么数据库,肯定我们做业务操作的话就是mysql,那么面试官就会顺势展开下来进行追问,本篇结合我自己本身的面试经验进行一番总结,帮助大家更好的通过mysql数据库方面的面试。
1存储引擎:
问题:介绍下mysql有哪些存储引擎?适用场景等。首先想说的是如果真是平常没这方面的研究,还真不一定能回答上来这道题,就说有哪几种可能都不知道,因为创建的时候就是点点点去创建数据库的。第二,创建数据库的时候不涉及到存储引擎的选择,真正创建表的时候才会选择存储引擎,一般默认我们选择的是InnoDB,字符集utf8,和字符集核对:忽略大小写的utf8_general_ci,完成表创建。回到正题存储引擎介绍:在mysql5之后,支持的存储引擎有十几个,但是常用的就那么几种,而且默认支持的也是InnoDB,我们常用的也就是InnoDB,其他的也很少用。
功能支持 | MyISAM | Memory | InnoDB |
---|---|---|---|
存储限制 | 256TB | RAM | 64TB |
支持事务 | 否 | 否 | 是 |
支持全文索引 | 是 | 否 | 否 |
支持B树索引 | 是 | 是 | 是 |
支持哈希索引 | 否 | 是 | 否 |
支持集群索引 | 否 | 否 | 是 |
支持数据索引 | 否 | 是 | 是 |
支持数据压缩 | 是 | 否 | 否 |
空间使用率 | 地 | n/a | 高 |
支持外键 | 否 | 否 | 是 |
MyISAM:使用这个存储引擎,每个MyISAM在磁盘上存储成三个文件。
frm文件:存储表的定义数据
MYD文件:存放表具体记录的数据
MYI文件:存储索引
frm和MYI可以存放在不同的目录下。MYI文件用来存储索引,但仅保存记录所在页的指针,索引的结构是B+树结构。
InnoDB:InnoDB是默认的数据库存储引擎,他的主要特点有:
(1)可以通过自动增长列,方法是auto_increment。
(2)支持事务。默认的事务隔离级别为可重复度,通过MVCC(并发版本控制)来实现的。
(3)使用的锁粒度为行级锁,可以支持更高的并发;
(4)支持外键约束;外键约束其实降低了表的查询速度,但是增加了表之间的耦合度。
(5)配合一些热备工具可以支持在线热备份;
(6)在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度;
(7)对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+数的叶子节点上;
当然InnoDB的存储表和索引也有下面两种形式:
(1)使用共享表空间存储:所有的表和索引存放在同一个表空间中。
(2)使用多表空间存储:表结构放在frm文件,数据和索引放在IBD文件中。分区表的话,每个分区对应单独的IBD文件,分区表的定义可以查看我的其他文章。使用分区表的好处在于提升查询效率。
对于InnoDB来说,最大的特点在于支持事务。但是这是以损失效率来换取的。
Memory:将数据存在内存,为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联。文件是frm。
(1)支持的数据类型有限制,比如:不支持TEXT和BLOB类型,对于字符串类型的数据,只支持固定长度的行,VARCHAR会被自动存储为CHAR类型;
(2)支持的锁粒度为表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈;
(3)由于数据是存放在内存中,一旦服务器出现故障,数据都会丢失;
(4)查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低;
(5)默认使用hash索引。
(6)如果一个内部表很大,会转化为磁盘表。
在这里只是给出3个常见的存储引擎。使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能
1.1总结:
上面是一个大而全的存储引擎的介绍,一般面试可能不会说那么多,就讲出来 MyISAM 和 InnoDB 的主要区别:前者不支持事务,后者支持事务,前者支持全文索引,后者不支持等等。就算过。
2 字符集和校对规则:
字符集指的是一种从二进制编码到某类字符符号的映射,回影响存储的长度等。常用的字符集我们需要了解下,utf8中文字符集,utf8mb4中文支持表情支持表情字符集,校对规则一般我们都选用utf8_general_ci、utf8mb4_general_ci忽略大小写的校验规则。
3 索引:
4 缓存:
my.cnf中配置缓存:
query_cache_type=1query_cache_size=600000
执行命令添加缓存:
set global query_cache_type=1;set global query_cache_size=600000;
开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果。开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果。通过sql命令来控制是否需要缓存;sql_cache和sql_no_cache来控制某个查询语句是否需要缓存:select sql_no_cache count(*) from usr;
5 事务:
事务的四大特性ACID是大概率会问的问题,作为开发人员也需要对事务的特性和隔离级别进行了解清除。
特性 | 说明 | 备注 |
---|---|---|
原子性(Atomicity) | 事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。 | |
一致性(Consistency) | 事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。其实一致性也是因为原子型的一种表现 | |
隔离性(Isolation) | 同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。串行化 | |
持久性(Durability) | 事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。 |
事务并发问题:
问题 | 说明 | 备注 |
---|---|---|
脏读 | 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据,与表中最终的实际数据不一致 | |
不可重复读 | 事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。读取结果与上次结果不一致 | |
幻读 | 系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。修改过来了但又被改了,导致结果和预期不一样 |
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 |
读已提交(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
6 锁:
MyISAM中采用的是表级锁,特定为:Mysql中锁定 粒度最大 的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM和 InnoDB引擎都支持表级锁。
InnoDB存储引擎采用的是行级锁,特点是:Mysql中锁定 粒度最小的一种锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,有可能出现死锁。
7 大表优化的几种方案:
方案 | 说明 | 备注 |
---|---|---|
限定数据范围 | 带上查询条件减少数据量 | 近一个月的订单查询等 |
读/写分离 | 经典的方案,主库负责写,读库负责度 | 能够提高数据库的并发能力 |
缓存 | 缓存可以在一些场景中提高效率 | 对重量级、更新少的数据可以考虑使用应用级别的缓存; |
垂直分区 | 把一张表拆成多张表存储 | 用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库,特点是行数据变少,这个应该根据实际业务场景配合水平分区去做选择 |
水平分区 | 把一张大表tb拆成tb1、tb2、tb3 | 使用中间件mycat或者sharding-jdbc进行分片拆分表达到扩容的目的,比较的常用,但是拆分后会带来逻辑、部署、运维等复杂度 |