数据库
1. MySQL 索引使用的注意事项
数据库索引
- 使用了空间换取时间,会占用额外存储;
- 索引提升查询性能的同时,影响数据的增删改;
- null值不适合做索引,要加索引的列一般添加not null约束,并给一个默认值;
- 列的取值越唯一,区分度越高,越适合做索引;
- mysql主键索引(聚簇索引,把这一行的值都存储到叶子节点上)和普通索引(只存储了主键的值),查询普通索引时,如果select的列值不是建立了索引的列,则会搜索两遍,先走普通索引再走主键索引(主键索引叶子节点上包含全部信息,普通索引叶子节点上只有主键和建立了索引的列)这种成为回表。
- 避免回表的方法,不随便使用select* ;建立复合索引;
索引与主键的区别
- 主键一定是唯一性索引,唯一性索引并不一定就是主键;
- 一个表中可以有多个唯一性索引,但只能有一个主键;
- 主键列不允许控制,而唯一索引列允许空值;
- 索引可以提高查询的速度。
2. DDL、DML、DCL分别指什么
- DDL数据定义语言,用来操作表结构,增删表;
- DML数据操控语言,用来增删改查数据;
- DCL数据控制语言,用来创建用户,授权,回收权限;
3. explain命令
显示了mysql如何使用索引来处理select语句以及连接表,现实的信息可以帮助选择更好的索引和写出更优化的查询语句;
4. left join,right join,inner join
- inner join:等值连接,内连接,在两张表进行连接查询的时候,只保留两张表中完全匹配的结果集;
- left join:左链接,返回包括左表中的所有记录和右表连接字段相等的记录;
- right join :右链接,返回包括右表的所有记录和左表连接字段相等的记录;
** 5. 数据库事务ACID**
- 原子性(Atomicity):是指事务包含的的所有操作,要么全部成功,要么全部回滚;
- 一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态;
- 隔离性(Isplation):多个并发事务要相互隔离;
- 持久性(Durability):一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。
6. 事物的隔离级别
- 脏读(读未提交):事务2查到了事务1修改了但是未提交的数据,如果事务1回滚了,则事务2读到了无效的数据;所以应该将隔离级别提高到读提交级别;
- 不可重复读(读已提交):一个事务多次查询却返回了不同的结果,这是因为在查询的间隔,数据被别的事务修改了,一边查询,另一边修改;可将隔离级别提高到可重复读;
- 幻读(可重复读):幻读是针对多条数据,比如一个事务正在查询数据条数,而另一个事务插入一条数据在读到位置的前面,如果查询事务再次查询会发现多了一条数据,就像出现了幻觉一样;一边查询,另一边增删;可以将隔离级别提高到序列化读;
- 序列化:可避免脏读、不可重复读、幻读的发生;
序列化读是以锁表的方式类似于多线程中的锁,Mysql默认的隔离级别是不可重复读。
脏读在于只读取了一次;
不可重复读在于多次读到别人不停修改的数据,导致结果不一致;
幻读在于多次读到别人不停增加修改记录数,导致结果记录数不一致;
7. 数据库的几大范式
- 第一范式(1NF):数据表中的每一列必须是不可拆分的最小单元,也就是确保每一列的原子性;
- 第二范式(2NF):满足1NF后,要求表中的所有列,都必须依赖主键,而不能有任何一列与主键没关系;消除部分依赖;
- 第三范式(3NF):满足2NF后,表中的每一列只与主键之间直接相关而不是传递相关;消除传递依赖;
范式的作用:可以避免数据冗余,减少数据库的查询,减轻维护数据完整性的麻烦;减少列之间的依赖,不至于要修改一个列而必须同时修改其他列。
8. 关于分库分表问题
-
分表:能够借护额单表数据量过大带来的查询效率下降的问题;
-
分库:面对该并发的读写问题,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器,都是没有意义的,此时应该通过数据分库策略,提高数据库并发访问能力;
-
横向水平分表:解决表记录太大的问题,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询次数;适用于表中的数据本身就有独立性;
- 缺点:通常查询需要多个表名,查询所有数据都需要UNION操作;
-
纵向垂直分表:把主键和一些列放在一个表,然后把主键和另外的列放在另一个表中;适用场景:一个表中某些列常用,另一些列不常用;可以使数据行变小,一个数据页能存储更多数据,查询时减少IO次数。
- 缺点:管理冗余列,查询所有数据需要join操作;
-
分表的缺点:有些分表策略基于应用层的逻辑算法,一旦逻辑算法改变,整个表逻辑都会改变,扩容性较差;
9. 分库与分表带来的分布式困境与应对之策
-
数据迁移与扩容问题
- 方法一:连续分表,不需要考虑迁移旧数据问题,直接添加分表就可以扩容,但是可能存在数据热点表问题,对于有些表可能会被频繁的查询而造成较大压力;
- 方法二:随机分表:数据相对较均匀,不容易出现热点和并发访问的瓶颈,但是分表扩展需要迁移旧数据;
-
表关联问题:随着分库分表的演变,联合查询就遇到跨库跨表问题;
- 方法一:可以通过程序中进行拼装;
- 方法二:通过反范式化设计进行规避;
-
分页与排序问题:
-方法: 需要在不同的分表中将数据进行排序返回,并将不同分表返回的结果集进行汇总和再排序,最后返回给用户; -
分布式事务问题
-
分布式全局唯一ID
10. 说说 SQL 优化之道
- 多使用explain来查看下执行计划,分析出索引的合理性;
- 尽量避免select * 的存在,适用具体的列代替* ,避免多余的列;
- 使用where限定具体要查询的数据,避免多余的行;
- 减少表连接数量;
- 避免类型转换;
- 用in代替or,少用like,避免使用函数运算;
- insert:尽量使用批量插入数据,避免一个个循环插入;
11. MySQL遇到的死锁问题、如何排查与解决
-
先了解数据库使用的引擎:
- MyISAM和MEMORY采用表级锁;
- BDB采用页面锁或表级锁默认为页面锁;
- InnoDB支持行级锁和表级锁,默认为行级锁;
表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用;
行级锁则更适合于大量按索引条件并发更新数据,同时又有并发查询的应用;
-
解决
- 按同一顺序访问对象;
- 避免事物中的用户交互;
- 保持事务简短并在一个批处理中;
- 使用低隔离级别
- 使用绑定连接;
12. 存储引擎的 InnoDB与MyISAM区别,优缺点,使用场景
13. 索引类别(B+树索引、全文索引、哈希索引)、索引的原理
14. 什么是自适应哈希索引(AHI)
哈希是一种非常快速的查找方法,在一般情况下这种查找的时间复杂度为O(1),仅需要一次就能查找到定位数据,InnoDB存储会监控对表上各索引页的查询,如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称为自适应哈希索引,InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引;
建立要求:
- 对这个页的连续访问模式必须是一样的;
- 页通过该模式访问了N次,其中N满足N=页中记录/16;
Mysql中只有在memory引擎中支持哈希索引;
15. 为什么要用 B+tree作为MySQL索引的数据结构
索引是存在于索引文件中的,存在于磁盘中,因为索引通常很大,因此无法一次将全部索引加载到内存中,每次只能从磁盘中读取一个磁盘业的数据到内存中,而磁盘读取的速度较内存中读取的速度而言差了好几个级别。
比较平衡二叉树、B-Tree和B+Tree:
平衡二叉树:其物理上是数组,由于逻辑结构相近的节点在物理结构上可能会相差很远,因此每次读取的磁盘数据中有许多是用不上的,故而查找过程中要进行多次磁盘读取,非常耗时,所以不适合做索引结构;
B-Tree:是为了充分利用磁盘预读功能而创建的一种数据结构,可以说是为了作为索引才被发明出来的;B树的每个节点可以存储多个关键字,它将节点大小设置为磁盘页的大小,充分利用了磁盘预读的功能,每次读取磁盘页时就会读取一个整节点,更多的是在内存中对读取进来的数据进行查找;
B+Tree:B+树的主要原因是B树在提高磁盘IO性能的同时并没有解决元素遍历的效率低下问题,B+树只要遍历叶子节点就可以实现整棵树的遍历,而且在数据库中基于范围查询是非常频繁的,而B树不支持这样的操作;
16. 聚集索引与非聚集索引的区别
定义:
-聚集索引:聚集索引中键值的逻辑顺序决定了表中相应的物理存储位置,因此一个表中只能有一个聚集索引,索引的逻辑顺序与相应行的物理位置一致;类比在查字典时根据拼音进行查找;拼音的目录和正文的目录顺序是一致的;
- 非聚集索引:逻辑顺序与行的物理位置不一致,数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置;类比查字典时根据偏旁部首进行查找;偏旁的目录和正文存储顺序不一致;
聚集索引适用于:
- 包含大量非重复值的列;
- 进行非等值查询时也就是范围查询时;
- 被连续访问的列;
- 返回大型结果集的查询;
- 经常被使用连接group by子句的查询访问的列;对group by或order by中指定的列进行索引,可以提高性能;
不适用于:
- 频繁更改的列,将导致整行移动;
- 宽键;
聚集索引的叶节点就是最终的数据节点,非聚集索引的叶节点仍然是索引节点,但它有一个指向最终数据的指针;
17. 遇到过索引失效的情况没,什么时候可能会出现,如何解决
- 查询条件中带有or的时候
- 如果列类型是字符串,在条件中要将数据使用引号引用起来;
- 如果mysql估计使用全表扫描要比使用索引块,则不使用索引;
- 存在NULL值条件;
- NOT条件,数据库更倾向于全表扫描;
- LIKE通配符,尽量不要使用前缀匹配;
- 条件上包括函数,因为索引在建立时会和计算后可能不同。
- 数据类型转换;
18.select for update语句
为了在查询时,避免其他用户以对表进行插入,修改,或删除等操作,造成表的不一致性。
什么是关系型数据库?
- 类似于Excel的二维表结构;
- 使用Sql语句来进行操作管理;
- 代表作品Mysql和
Redis
Redis有哪些数据类型
- 字符串(String);
- 散列表(hash);
- 列表(list);
- 有序集合(zset);
- 集合(set);
redis发布/订阅使用场景
- 聊天系统、社交网络中的通知触发器。