1、MySQL为什么默认存储引擎是InnoDB?
从存储数据角度来讲,innodb采取的是在一个文件中用B+树结构存储索引和完整数据(即聚集索引),减少了拿着索引去另一个文件寻找完整数据的过程,提高了查询的效率。
支持事务;
对于并发控制有很好的支持,innodb支持行锁,在高并发场景下可以最大限度解决锁冲突,myisam存储引擎仅支持表锁
支持外键约束;
支持热备份;
支持崩溃恢复。
2、小明公司的数据库用的MySQL 引擎是Innodb。小明创建了一张表,忘记给这张表添加主键,请问这张表有没有聚簇索引?哪个是它的聚簇索引呢?
innodb存储引擎默认是以主键来建立聚集索引的,如果没有主键,会查看这张表中是否有唯一索引,若有,则以唯一索引来建立聚集索引;
如果这张表中既没有主键也没有唯一索引,那么会根据row_id来建立聚集索引,不过依据row_id建立的聚集索引,是无法享受到索引带来的便利,即查询操作只能全表扫描,其次很影响这张表的插入性能,row_id字段是全局共享的,即其他没有设置主键和唯一索引的表都是公用这个字段的
注意:前面两种情况的row_id是可见的,既可以用select *,_rowid from table
查看到当前行的row_id值为多少;但是如果没有设置主键和唯一键的话是无法查看到rowid值的
3、小明创建了一张订单表(mysql数据库),关于订单金额字段不知道用什么类型, 你觉得应该使用什么类型呢?
使用decimal(m,d) m为有效长度,d为小数点后面的有效位数
1. DECIMAL 类型:
推荐使用:DECIMAL 类型是最适合存储货币数据的,因为它是一个定点数,有助于避免精度问题。
2. BIGINT 类型:
场景:在某些情况下,货币可以以最小单位存储(比如分或厘),然后使用 BIGINT 类型进行存储,这样可以避免浮点运算的问题。
优点:使用整数可以提高计算性能,避免小数精度问题。
实现方式:将货币值以最小单位进行存储,例如将 $10.23 存为 1023(以分为单位)。
3. FLOAT/DOUBLE 类型:
不推荐:这些浮点类型可能会由于精度问题导致金额计算不准确,因此不建议用于存储货币数据。
4、小明想清理一下一张表的历史数据(mysql数据库),请问这truncate、delete、drop三种方式哪种更好些?有什么区别吗?
drop是直接删除整张表
delete和truncate删除的是表数据,其中delete可以加入where条件语句,truncate不行
---------------------
扩充一下4答案
truncate:快速清除表中数据(比delete快)(因为它通常不记录单独的行删除操作,也不触发行级触发器),但保留表结构。是一个DDL操作,一般执行之后不可回滚。而且执行这条语句自动递增的行会重置id
truncate table table_name
delete:删除表中(所有或指定)数据,会保留表结构(在处理大表时,因为它逐行记录删除操作,并能激活触发器,删除数据操作就比truncate慢),是DML操作,支持事务处理可以执行回滚语句。
drop:删除整个表,包括表结构和表内数据,是一个DDL操作,不可恢复。
DML:是针对于表数据的操作insert/update这些
DDL:是针对于表的操作,包含:建表/删表/建索引这些
DDL与DML具体的区分可以查看这位博主的文章
简述DML与DDlhttp://t.csdnimg.cn/KxgTF
5、小明想使用模糊查询MySQL数据库的数据,根据业务场景前缀匹配和后缀匹配都可能用到, 请问这个模糊查询该如何优化?
模糊匹配如果使用不当的话就会让查询变成全表扫描
针对前缀匹配:一般来说查询字段建立了索引,或者是联合索引的话,一般还是会用到索引或者是部分索引的(联合索引的话需要注意最左前缀原则)
针对后缀匹配:可以创建一个辅助列,存放反转的字符串,并基于此列可以进行前缀匹配
使用搜索引擎中间件:类似es
全文索引:针对innodb存储引擎5.7.6之后开始支持中文的全文索引,在创建表的时候就创建
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT,
FULLTEXT (title, body)
);
-- 在已有表上添加全文索引
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title, body);
查询时,使用 MATCH 关键字与 AGAINST 子句来指定搜索词。
SELECT * FROM articles
WHERE MATCH (title, body) AGAINST ('search terms');
6、今天小明去大厂面试,面试官问他mysql查询的时候使用where 1=1会不会影响性能?你的答案是什么呢?说说你的看法。
很多小伙伴会在where后面跟上1=1的保证语,经常看网上的八股文说1=1会影响性能, 建议用Mybatis的<where>标签。两种方案,该如何选择?
如果 MySQL Server版本小于 5.7,用了 MyBatis的话,建议使用<where> 标签。
在5.7之后,会在mysql的内部组件server层中,被优化器识别并优化掉。
7、MVCC的原理是什么?谈谈你的理解
- undolog日志版本链
- readview视图(组成/创建时机)
- 可见性算法
- 当前读与快照读
参照MVCChttp://t.csdnimg.cn/pTMEi
8、Innodb加索引的时候会锁表吗?
首先我们知道DDL与DML的详细区别,加索引属于DDL操作加入的是X锁(排他锁)会进行锁表。
在5.6版本之后Innodb支持Online DDL
alter table ... add index ... online
使用Online DDL添加索引时的操作过程
- 建立临时索引文件,扫描原始表索引
- 将原始索引复制到临时索引中,同时记录原表的更改操作记录
- 将操作更改记录同步到临时索引中
- 切换索引
- 删除旧索引,释放资源
添加索引最开始的时候(也就是第一步)加的是X锁,将数据复制到临时文件中(2)会将锁降级为S锁,是可以允许DML操作的。
在生产环境中,如果符合业务情况,且数据库支持Online DDL,在生产环境业务不忙时可以执行这类的DDL操作,同时还能允许DML操作,一定程度上提高了数据库的并发和可用性。
9、小明今天不小心把数据库删了,然后连夜跑路了。领导让你把数据恢复出来,请问应该怎么做?
误删数据表或数据库
使用 `DROP TABLE`、`TRUNCATE TABLE` 或 `DROP DATABASE` 误删数据时,binlog 记录的是 statement 格式,一般不能通过 binlog 恢复。
恢复方法:依赖全量备份和增量日志。这个需要定期的全量备份和实时备份的 binlog。
误删数据行
使用DELETE语句误删数据行,可以通过Flashback(闪回)进行数据恢复
防止错误操作快速到从库
在mysql5.6之后引入了延迟复制的备库,目的是防止错误的操作蔓延到从库,从而导致主从库数据一起被删除。
具体方法: 通过命令 CHANGE MASTER TO MASTER_DELAY = N ,可以指定这个备库持续保持跟主库有 N 秒的延迟。