🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## InnoDB 引擎的 4 大特性,了解过吗? * 插入缓存:对于为非唯一索引,辅助索引的修改操作并非实时更新索引的叶子页,而是把若干对同一页面的更新缓存起来做合并为一次性更新操作,转化随机IO 为顺序IO,这样可以避免随机IO带来性能损耗,提高数据库的写性能。 * 二次写:当页需要写回数据库时,首先把页备份到内存中的doublewrite buffer,然后每次1M,写入到共享表空间中,共享表空间也是在磁盘上,因为是顺序写,所以很快,然后再将这些页写入到真的数据文件中,就算这个时候服务器出了问题,也是可以用共享表空间中的数据进行还原的 * 自适应hash:当某个非聚集索引被等值查询的次数很多时,就会为这个非聚集索引再构造一个hash索引,hash索引对呀等值查询是很快的,这个hash索引会放在缓存中 * 磁盘预读: ## 一条查询语句发生了什么 ![](https://img.kancloud.cn/83/d2/83d2b43d256121f10c57c5b42799c2c4_661x500.png) ## 三大范式是什么? * 第一范式:数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是确保每一列的原子性; * 第二范式(2NF):满足1NF后,要求表中的所有列,都必须依赖于主键,而不能有任何一列与主键没有关系,也就是说一个表只描述一件事情; * 第三范式:必须先满足第二范式(2NF),要求:表中的每一列只与主键直接相关而不是间接相关,(表中的每一列只能依赖于主键); ## 怎么区分三大范式? 第 一范式和第二范式在于有没有分出两张表,第二范式是说一张表中包含了所种不同的实体属性,那么要必须分成多张表, 第三范式是要求已经分成了多张表,那么一张表中只能有另一张表中的id(主键),而不能有其他的任何信息(其他的信息一律用主键在另一表查询)。 ## 数据库五大约束是什么? 1.primary KEY:设置主键约束; 2.UNIQUE:设置唯一性约束,不能有重复值; 3.DEFAULT 默认值约束,height DOUBLE(3,2)DEFAULT 1.2 height不输入是默认为1,2 4.NOT NULL:设置非空约束,该字段不能为空; 5.FOREIGN key :设置外键约束。 ## 主键是什么,怎么设置主键? 主键默认非空,默认唯一性约束,只有主键才能设置自动增长,自动增长一定是主键,主键不一定自动增长; 在定义列时设置:ID INT PRIMARY KEY 在列定义完之后设置:primary KEY(id) ## 数据库的外键是什么? 只有INNODB的数据库引擎支持外键。 不见已使用基于mysql的物理外键,这样可能会有超出预期的后果。推荐使用逻辑外键,就是自己做表设计,根据代码逻辑设定的外键,自行实现相关的数据操作。 ## 主键索引和唯一索引的区别 1. 主键一定会创建一个唯一索引,但是有唯一索引的列不一定是主键; 2. 主键不允许为空值,唯一索引列允许空值; 3. 一个表只能有一个主键,但是可以有多个唯一索引; 4. 主键可以被其他表引用为外键,唯一索引列不可以; 5. 主键是一种约束,而唯一索引是一种索引,是表的冗余数据结构,两者有本质的差别 ## innodb和myisam有什么区别? * InnoDB支持事务,而MyISAM不支持事物,崩溃后无法安全恢复,表锁非常影响性能 * InnoDB支持行级锁,而MyISAM支持表级锁 * InnoDB支持MVCC,实现了四个标准的隔离级别 而MyISAM不支持 * InnoDB 表是基于聚族索引建立的,聚族索引对主键查询有很高的性能 * InnoDB支持外键,而MyISAM不支持 * MyISAM 存储引擎已经有了20年的历史,在1995年时,MyISAM 是 MySQL 唯一的存储引擎,服务了20多年,即将退居二线。随着mysql5.7,8版本的提升,myisam优点已经逐渐被 InnoDB 实现了。比如全文索引,表空间优化,临时表优化,高效的count(\*) ## btree和hash类型的索引有什么不同? 首先要知道Hash索引和B+树索引的底层实现原理: hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据.B+树底层实现是多路平衡查找树.对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据. 那么可以看出他们有以下的不同: * hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询. 因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询.而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围. * hash索引不支持使用索引进行排序,原理同上. * hash索引不支持模糊查询以及多列索引的最左前缀匹配.原理也是因为hash函数的不可预测.**AAAA**和**AAAAB**的索引没有相关性. * hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询. * hash索引虽然在等值查询上较快,但是不稳定.性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差.而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低. 因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度.而不需要使用hash索引. ## drop、delete与truncate分别在什么场景之下使用? 我们来对比一下他们的区别: drop table * 1)属于DDL * 2)不可回滚 * 3)不可带where * 4)表内容和结构删除 * 5)删除速度快 truncate table * 1)属于DDL * 2)不可回滚 * 3)不可带where * 4)表内容删除 * 5)删除速度快 delete from * 1)属于DML * 2)可回滚 * 3)可带where * 4)表结构在,表内容要看where执行的情况 * 5)删除速度慢,需要逐行删除 总结: **不再需要一张表的时候,用drop** **想删除部分数据行时候,用delete,并且带上where子句** **保留表而删除所有数据的时候用truncate** ## MySQL中的varchar和char有什么区别? 1. char的长度是不可变的,而varchar的长度是可变的 。 2. 定义一个char\[10\]和varchar\[10\],如果存进去的是‘abcd’,那么char所占的长度依然为10,除了字符‘abcd’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的, 3. char的存取速度比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。 4. char的存储方式是,对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节;而varchar的存储方式是,对每个英文字符占用2个字节,汉字也占用2个字节,两者的存储数据都非unicode的字符数据。 5. char适合存储长度固定的数据,varchar适合存储长度不固定的。 ## varchar(10)和int(10)代表什么含义? varchar的10代表了申请的空间长度,也是可以存储的数据的最大长度,而int的10只是代表了展示的长度,不足10位以0填充.也就是说,int(1)和int(10)所能存储的数字大小以及占用的空间都是相同的,只是在展示时按照长度展示. ## 超大分页怎么处理? 超大的分页一般从两个方向上来解决. * 数据库层面,这也是我们主要集中关注的(虽然收效没那么大),类似于`select * from table where age > 20 limit 1000000,10`这种查询其实也是有可以优化的余地的. 这条语句需要load1000000数据然后基本上全部丢弃,只取10条当然比较慢. 当时我们可以修改为`select * from table where id in (select id from table where age > 20 limit 1000000,10)`.这样虽然也load了一百万的数据,但是由于索引覆盖,要查询的所有字段都在索引中,所以速度会很快. 同时如果ID连续的好,我们还可以`select * from table where id > 1000000 limit 10`,效率也是不错的,优化的可能性有许多种,但是核心思想都一样,就是减少load的数据. * 从需求的角度减少这种请求....主要是不做类似的需求(直接跳转到几百万页之后的具体某一页.只允许逐页查看或者按照给定的路线走,这样可预测,可缓存)以及防止ID泄漏且连续被人恶意攻击. 解决超大分页,其实主要是靠缓存,可预测性的提前查到内容,缓存至redis等k-V数据库中,直接返回即可.