## 为什么要分库分表?
分库主要针对的在单库情况下并发限制问题或单库的磁盘限制问题;
分表主要针对的是单表的数据量很大,影响读性能;
##分库分表之后事务是如何解决的?
在每个库中记录一张流水表
## 三大范式是什么?
* 第一范式:数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是确保每一列的原子性;
* 第二范式(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的物理外键,这样可能会有超出预期的后果。推荐使用逻辑外键,就是自己做表设计,根据代码逻辑设定的外键,自行实现相关的数据操作。
## innodb和myisam有什么区别?
* InnoDB支持事务,而MyISAM不支持事物,崩溃后无法安全恢复,表锁非常影响性能
* InnoDB支持行级锁,而MyISAM支持表级锁
* InnoDB支持MVCC,实现了四个标准的隔离级别 而MyISAM不支持
* InnoDB 表是基于聚族索引建立的,聚族索引对主键查询有很高的性能
* InnoDB支持外键,而MyISAM不支持
* InnoDB文件结构是.frm和.ibd/.ibdata,而MyISAM是.frm、.myd、.myi
* MyISAM 存储引擎已经有了20年的历史,在1995年时,MyISAM 是 MySQL 唯一的存储引擎,服务了20多年,即将退居二线。随着mysql5.7,8版本的提升,myisam优点已经逐渐被 InnoDB 实现了。比如全文索引,表空间优化,临时表优化,高效的count(\*)
>独享表空间存储方式使用.ibd文件,并且每个表一个ibd文件
共享表空间存储方式使用.ibdata文件,所有表共同使用一个ibdata文件
## 什么是索引?
索引是一种数据结构,可以帮助我们快速的进行数据的查找.
## 索引是个什么样的数据结构呢?
索引的数据结构和具体存储引擎的实现有关, 在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引.
## innodb索引的实现原理是什么?
InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。
## btree和hash类型的索引有什么不同?
首先要知道Hash索引和B+树索引的底层实现原理:
hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据.B+树底层实现是多路平衡查找树.对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据.
那么可以看出他们有以下的不同:
* hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询.
因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询.而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围.
* hash索引不支持使用索引进行排序,原理同上.
* hash索引不支持模糊查询以及多列索引的最左前缀匹配.原理也是因为hash函数的不可预测.**AAAA**和**AAAAB**的索引没有相关性.
* hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询.
* hash索引虽然在等值查询上较快,但是不稳定.性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差.而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低.
因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度.而不需要使用hash索引.
## 什么是覆盖索引?
简单的说,select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引不存储索引列的值,所以mysql**只能用B-tree索引**做覆盖索引。
## B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,什么是聚簇索引?
在B+树的索引中,叶子节点可能存储了当前的key值,也可能存储了当前的key值以及整行的数据,这就是聚簇索引和非聚簇索引. 在InnoDB中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键建立聚簇索引.如果没有唯一键,则隐式的生成一个键来建立聚簇索引.
当查询使用聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不用再次进行回表查询.
## 在建立索引的时候,都有哪些需要考虑的因素呢?
建立索引的时候一般要考虑到字段的使用频率,经常作为条件进行查询的字段比较适合.如果需要建立联合索引的话,还需要考虑联合索引中的顺序.此外也要考虑其他方面,比如防止过多的所有对表造成太大的压力.这些都和实际的表结构以及查询方式有关.
## 联合索引/多列索引的注意事项是什么?
MySQL可以使用多个字段同时建立一个索引,叫做联合索引.在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引.
具体原因为:
MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序.
当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找,,,以此类推.因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面.此外可以根据特例的查询或者表结构进行单独的调整.
## 导致索引失效的原因有哪些?
* 列参与了数学运算或者函数;
* 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因);
* 对于多列索引,不符合最左匹配的命中规则;
* like查询是以%开头;
* 如果直接查比用索引快,那么数据库会自动选择最优方式,不用索引;
* in 和 not in 也要慎用,否则会导致全表扫描。
## 主键使用自增ID还是UUID?
推荐使用自增ID,不要使用UUID.
因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降.
总之,在数据量大一些的情况下,用自增主键性能会好一些.
## 字段为什么要求定义为not null?
MySQL官网这样介绍:
> NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.
null值会占用更多的字节,且会在程序中造成很多与预期不符的情况.
## 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**
## 关心过业务系统里面的sql耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
在业务系统中,除了使用主键进行的查询,其他的我都会在测试库上测试其耗时,慢查询的统计主要由运维在做,会定期将业务中的慢查询反馈给我们.
慢查询的优化首先要搞明白慢的原因是什么? 是查询条件没有命中索引?是load了不需要的数据列?还是数据量太大?
所以优化也是针对这三个方向来的,
* 首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写.
* 分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引.
* 如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表.
## UNION、UNION ALL区别?
union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
union All:对两个结果集进行并集操作,包括重复行,不进行排序;
## 你的sql优化常用技巧有哪些?
1. 去掉不必要的查询和搜索字段
2. 争取命中索引,或者根据已有的查询情景简历合理的索引
3. 不要使用select *:以提高查询效率,减少输出的数据量,提高传输速度
4. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理和是否分页
5. 减少访问数据库的次数,业务代码逻辑优化,避免for循环
6. 使用表的别名(Alias):当在SQL语句中连接多个表时, 减少解析的时间,减少那些由Column歧义引起的语法错误
7. 字段设计not null
8. 索引可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因此索引并非越多越好,合理有效的使用
9. 尽量避免大事务操作,提高系统并发能力
## 数据库事务的使用的规范有哪些?
1. 控制事务大小,减少锁定的资源量和锁定时间长度。
2. 所有的数据检索都通过索引来完成,从而避免因为无法通过索引加锁而升级为表锁。
3. 减少基于范围的数据检索过滤条件,避免因为间隙锁带来的负面影响而锁定了不该锁定的数据。
4. 在业务条件允许下,尽量使用较低隔离级别的事务隔离。减少隔离级别带来的附加成本。
5. 合理使用索引,让innodb在索引上面加锁的时候更加准确。
6. 在应用中尽可能做到访问的顺序执行(串行)。
7. 如果容易死锁,就可以考虑使用表锁来减少死锁的概率。
## InnoDB怎么实现的事务ACID特性?
* redo log重做日志用来保证事务的持久性
* undo log回滚日志保证事务的原子性
* undo log+redo log保证事务的一致性
* 锁(共享、排他)用来保证事务的隔离性
undo log 实现如下两个功能:1.实现事务回滚 2.实现MVCC
undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
推荐阅读,加深理解 :[https://www.cnblogs.com/jianzh5/p/11643151.html]
- 消息队列
- 为什么要用消息队列
- 各种消息队列产品的对比
- 消息队列的优缺点
- 如何保证消息队列的高可用
- 如何保证消息不丢失
- 如何保证消息不会重复消费?如何保证消息的幂等性?
- 如何保证消息消费的顺序性?
- 基于MQ的分布式事务实现
- Beanstalk
- PHP
- 函数
- 基础
- 基础函数题
- OOP思想及原则
- MVC生命周期
- PHP7.X新特性
- PHP8新特性
- PHP垃圾回收机制
- php-fpm相关
- 高级
- 设计模式
- 排序算法
- 正则
- OOP代码基础
- PHP运行原理
- zavl
- 网络协议new
- 一面
- TCP和UDP
- 常见状态码和代表的意义以及解决方式
- 网络分层和各层有啥协议
- TCP
- http
- 二面
- TCP2
- DNS
- Mysql
- 锁
- 索引
- 事务
- 高可用?高并发?集群?
- 其他
- 主从复制
- 主从复制数据延迟
- SQL的语⾔分类
- mysqlQuestions
- Redis
- redis-question
- redis为什么那么快
- redis的优缺点
- redis的数据类型和使用场景
- redis的数据持久化
- 过期策略和淘汰机制
- 缓存穿透、缓存击穿、缓存雪崩
- redis的事务
- redis的主从复制
- redis集群架构的理解
- redis的事件模型
- redis的数据类型、编码、数据结构
- Redis连接时的connect与pconnect的区别是什么?
- redis的分布式锁
- 缓存一致性问题
- redis变慢的原因
- 集群情况下,节点较少时数据分布不均匀怎么办?
- redis 和 memcached 的区别?
- 基本算法
- MysqlNew
- 索引new
- 事务new
- 锁new
- 日志new
- 主从复制new
- 树结构
- mysql其他问题
- 删除
- 主从配置
- 五种IO模型
- Kafka
- Nginx
- trait
- genergtor 生成器
- 如何实现手机扫码登录功能
- laravel框架的生命周期