数据库高频知识点总结

MyBatis相关:

1.mybatis一级和二级缓存?

  一级缓存:

      sqlSession级别的缓存。

      当我们创建一个sqlSession,在sqlSession对象内部维护Map。

      当执行sql语句的时候,首先将sql语句和参数作为key,在一级缓存中查找数据。

  • 如果有数据: 直接返回
  • 如果没有数据:将sql语句发送到数据库,数据库执行 sql 返回结果。 将 sql 语句和参数作为key , 将查询到的数据作为value存入一级缓存。

       每个sqlSesssion有自己的一级缓存。

    一级缓存清理:

  •  当执行增删改操作,sqlSession一级缓存会被清理。
  •  当我们调用sqlSession.clearCache() 会清理一级缓存。

    二级缓存:

         该级缓存默认不开启,但如果使用二级缓存需要在每个XML映射文件中添加以配置该级缓存(相应实体类要序列化)。

         sqlSessionFactory 级别的缓存,可以被所有的sqlSession共享。

         通过sqlSession查询数据,这些数据将会放到当前会话的一级缓存中;如果当前会话关闭,则一级缓存中的数据会被保存到二级缓存中,此后新的sqlSession将从二级缓存中查找数据;

         二级缓存什么时候被清理?

         select标签的userCache属性用于设置是否使用二级缓存,默认是true;

         insert     update delete 或 select标签 均有flushCache属性,其中增删改默认true,即sql执行以后,会同时清空一级和二级缓存,查询默认false。

2.mybatis中 ${}  和  #{}  有什么区别?

#{ } :  底层会翻译成占位符,将来会使用PreparedStatement执行预编译sql。

${ } :  底层是字符串替换,将来会使用PreparedStatement执行sql 可能会出现sql注入。

3.mybatis如何执行批量插入?

public void saveBatch(@Param("users") List<User> users);
<insert id="saveBatch">
<if test="users != null and users.size() > 0">
insert into user(user_name,user_email) values
<foreach collection="users" item="user" separator=",">
(#{user.userName},#{user.userEmail})
</foreach>
</if>
</insert>

4.mybatis如何在插入后获得主键 ?

useGeneratedKeys = "true"      keyProperty = "id"

<insert id="save" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into user(user_name,user_email) values (#{userName},#{userEmail})
</insert>
@Insert("insert into user(user_name,user_email) values (#{userName},#
{userEmail})")
@Options(useGeneratedKeys = true,keyColumn = "id",keyProperty = "id")

5.mybatis中resultType和resultMap区别?

 resultType:查询结果集中字段名和实体类中属性名一致 或者字段使用_命名方式,属性使用驼峰命名,只要开启下划线可以映射驼峰。

resultMap:查询结果集中字段和实体类中不一致。

MySQL相关:

1.说一下Mysql常用的存储引擎?

存储引擎(engine): 存储引擎是决定了表中数据如何存储,查询,更新及索引如何存储。

InnoDB:

       兼顾高可用性和高性能的存储引擎

       Supports transaction, row-level locking, and foregin keys

       支持事务,行锁,外键

       底层:每个表InnoDB只有一个文件  .ibd 文件(数据,表结构,索引)

MyISAM:

       不支持事务,不行锁,不外键,支持表锁。

       底层:每个MyISAM的表对应三个文件myi(索引), myd(数据), sdi(表结构)

Memory:

       基于hash索引,数据存储内存,用于临时表。数据存储在内存中,断电丢失,经常作为临时表或者缓存,访问速度快

       底层:每个Memory的表对应一个文件sdi(表结构)

2.数据库三大范式?

  • 1范式: 表中的每一个字段都是不可分割的数据项
  • 2范式: 非主键字段,要依赖于主键字段
  • 3范式: 任意2个非主键字段之间不能存在函数依赖关系

3.Inner join    left join   right join 的区别?

Inner join 内连接:

     特点: 只查询2张表有关联关系的数据,没有关联关系的数据不展示。

left join 和 right join 外连接:

     特点: 左表数据全部展示,右表只展示有关联关系的数据

                 左表某些数据和右表没有关联关系,右表用Null展示

     right join 和 left join 相对关系

4.Mysql中数据库事务的三个安全性问题?

  • 脏读: 指的是一个事务读到另外一个事务未提交的数据。
  • 不可重复读: 指的是一个事务读到了另一个事务已经提交的update的数据,导致多次查询结果不一致,导致在一个事务中两次读取数据不一致。
  • 虚读/幻读: 指的是一个事务读到了另一个事务已经提交的insert的数据,导致多次查询结果不一致。

4.1 ACID是什么?

  •  A (Atomicity)原子性: 要么全部成功,要么全部失败,不可能只执行一部分操作。
  • C (Consistency)一致性:系统(数据库)总是从一个一致性的状态转移到另一个一致性的状态,不会存在中间状态。
  • I (Isolation) 隔离性: 通常来说,一个事务在完全提交之前,对其他事务是不可见的。
  • D(Durability) 持久性: 一旦事务提交,那么就永远是这个样子了,哪怕系统崩溃也不会影响到这个事务的结果。

5.Mysql索引

   索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构(B+树),这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

6.索引数据结构

  不同的存储引擎数据结构不同。

  1. B+Tree 索引:  全部支持, MySQL默认使用的索引底层数据结构是B+树 B+树不同于二叉树, 一种多叉路平衡查找树,每个节点可以有多个分支 比如一棵5阶的B树,每一个节点最多存储4个key,对应5个指针。一旦节点 存储的key数量到达5,就会裂变,中间元素向上分裂。所有的数据都会出现 在叶子节点,叶子节点形成一个双向链表,利于范围查询。非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。

  2. Hash索引: 仅仅Memory

  3. R-tree索引: 存储地理位置信息,MyISAM

  4. Full-text全文索引: InnoDB & MyISAM

7.索引创建的原则有哪些?

  1. 针对于数据量较大,且查询比较频繁的表建立索引。
  2. 针对于常作为查询条件(where), 排序(order by), 分组(group by) 操作的字段建立索引。
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
  6. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
  7. 如果索引列不能存储null值,请在创建表时使用not null 来约束它。当优化器知道每列是否包含null值时候,它可以更好地确定哪个索引最有效地用于查询。

8.左前缀原则?

      如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(后面的字段索引失效)。

9.索引的分类?

  •  主键索引:主键字段自带主键索引。
  •  唯一索引:保证某一列值的唯一性。 
  •  普通索引
  •  组合索引
  •  全文索引: 倒排索引
  •  创建索引
  •  create [索引类型] index 索引名称 on 表名称(字段名称......)

10.什么情况下索引会失效?

  1. 违反了最左前缀法则
  2. 范围查询右边的列,不能使用索引
  3. 在索引列上进行运算操作,索引将失败
  4. 字符串不加单引号,造成索引失效
  5. 尽量使用覆盖索引,避免select *,如果查询列,超出索引列,也会降低性能。
  6. 用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
  7. 以 % 开头的 like 模糊查询,索引失效。通过覆盖索引来解决。
  8. 如果MySQL评估使用索引比全表更慢,则不使用索引。
  9. is NULL , is NOT NULL  有时索引失效
  10. in 走索引, Not in 索引失效

11.如何确定慢sql?

      开启慢查询日志。

            show variables like 'slow_query_log' 查看是否开启慢查询日志

      在mysql的配置文件中开启

            long_query_time=1 : sql的执行时长超过多久算慢sql;

            slow_query_log=1  : 开启慢查询日志

12.一个SQL语句执行很慢,如何分析?

     可以采用  EXPLAIN 或者  DESC 命令 获取MySQL 如何执行  select 语句的信息,包括在select语句执行过程中表如何连接以及连接的顺序。

     主要可以根据几个字段,判断sql是否需要优化,特别是是否能命中索引或命中索引的情况

  • type通过sql的连接的类型进行优化
  • possible_key 通过它查看是否可能会命中索引
  • key 当前sql实际命中的索引
  • key_len 索引占用的大小
  • Extra 额外的优化建议   

13.MySQL超大分页怎么处理?

        在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。

   一般分页查询时,通过创建 覆盖索引 能够比较好的提高性能,然后通过覆盖索引加子查询形式进行优化。

14.覆盖索引

       覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。比如有一个user表,给里面的字段创建了一个复合索引,顺序是 name, age, email, 当查询索引只select后面只包含name , age , email 的时候就算是覆盖索引了。

15.回表查询

       回表查询是使用二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式。

       举个栗子!

       有一个user表,给user表中的name 创建了索引,那这个name的索引其实就是二级索引。当我们select * from user where name = xxx 的时候,条件name是可以走索引,但是要查询表中的所有字段,这个时候name的这个索引是没有的,但是能查询出来name这一行的id值,然后这个id其实就是我们刚才说的聚集索引,然后根据这个id再去到索引去查一次,就相当于回表查询了!!

16.sql优化的经验

  1. 选择表合适的存储引擎:
  • MyISAM :应用时以读和插入操作为主,只有少量的更新和删除,并且对事务的完整性,并发性要求不是很高。
  • Innodb: 事务处理,以及并发条件下要求数据的一致性。除了插入和查询外,包括很多的更新和删除。尽量设计所有字段都得有默认值,尽量避免null。

     2.选择合适的数据类型

    数据库表设计时候更小的磁盘占比空间,尽可能使用更小的整数类型,一般来说,数据库中的表越小,在它上面执行的查询也就会越快。

   比如设置合适的数值(tinyint ,  int ,   bigint)要根据实际情况选择。

   比如设置合适的字符串类型   char 定长效率更高, varchar 可变长度,效率稍低。

     

      3. 索引优化

  • 表的主键,外键必须有索引
  • 数据量大的表应该有索引
  • 经常与其他表进行连接的表,在连接字段上应该建立索引
  • 经常出现在where子句的字段,特别是大表的字段,应该建立索引
  • 索引应该建在选择性高的字段上,(sex 性别这种就不合适哦)
  • 索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引
  • 频繁进行数据操作的表,不要建立太多的索引
  • 删除无用的索引,避免对执行计划造成负面影响   

   

       4.sql语句优化

  • select语句务必指明字段名称(避免直接使用select *)
  • SQL语句要避免造成索引失效的写法
  • SQL语句中 IN 包含的值不应过多
  • 当只需要一条数据的时候,使用 limit 1
  • 如果排序字段没有用到索引,就尽量少排序
  • 如果限制条件中其他字段没有索引,尽量少用 or
  • 尽量用 union all 代替 union
  • 避免在 where子句中对字段进行 null 值判断
  • 不建议使用%前缀模糊查询
  • 避免在where子句中对字段进行表达式操作
  • Join优化 尽量用 innerjoin

    

      5.主从复制 读写分离

     读写分离的基本原理是让主数据库处理事务性 增, 改, 删操作,而 从数据库 处理 select查询操作。

     6.mysql的分库分表

    当单表的数据量太大或单库的数据量太大的话,性能会降低的比较厉害,这个时候就要考虑选择合适的拆分策略,比如垂直分库和水平分库。

 17.主从同步的原理

      MySQL主从复制的核心就是二进制日志,二进制日志记录了所有的DDL语句和DML语句。具体的主从同步过程大概的流程是这样的:

  1.  Master主库在事务提交时,会把数据变更记录在二进制日志文件 Binglog中
  2.  从库读取主库的二进制日志文件Binglog,写入到从库的中继日志 Relay Log中
  3. slave重做中继日志中的事件,将改变反映它自己的数据。

18.Mysql为什么要分库分表? 分库分表的策略有哪些?

    当时项目业务量其实一直都在增长,有的单表就接近了20万的数据,如果不分库分表的话,性能会直线下降。 关于分库分表的策略有很多, 比如: 垂直分库,垂直分表,水平分库,水平分表。

    水平分库:以字段为依据,按照一定策略,将一个库的数据拆分到多个库中。当然为了让我们的微服务更方便的去调用多个库中的数据,当时采用的mycat作为我们分库分表的中间件来使用的。

19.分库分表后id主键如何处理?

  1. 如果选择的主键还是自增的话 ,可以使用数据库中间件去解决,比如mycat 就能在配置中设置一个表是自增,由mycat帮助我们去设置自增。
  2. 如果不是自增的,可以选择UUID或雪花算法来生成ID 尽可能不要使用UUID 因为UUID太长了,占用空间大,作为主键的性能不高,也不能排序。

20.Mysql中有哪几种锁?

 按照锁的粒度来分:

 全局锁:

         锁定MySQL某个数据库中所有表,典型的应用场景,数据库的备份,如果不加全局锁,数据备份会导致数据的不一致。

 表级锁:

         每次操作锁住整张表。锁的粒度大,并发度低。

         读锁:阻塞其他用户端的写操作,但是不会阻塞读操作。

         写锁:当前线程可以读写,其他线程读写会阻塞。

         解锁: unlock tables

         元数据锁(meta data lock):由mysql自动控制,在访问一张表的时候自动加上。

               作用是 保证数据和表结构的一致性!!

               1.当在一个事务中进行了查询给该表加MDL_SHARED_READ

               2.当在一个事务中进行了增删改该表加MDL_SHARED_WRITE

               3.修改了表结构,会给表加exclusive

               4.MDL_SHARED_READ  MDL_SHARED_WRITE和exclusive冲突

       

       意向锁:

                1.当A线程加一个行锁的时候,同时加一个意向锁;

                2.其他线程加表锁,就可以快速知道。这张表是有锁的;

                3.select * from xxx lock in share mode;意向锁读锁,它和表锁的读锁不冲突和写锁冲突

                4.update delete insert select ... for update和表锁的读写锁都冲突;

       

       行级锁:每次加锁操作,锁住的是数据行,粒度小,并发度高。InnoDB存储引擎支持

   21.表级锁和行级锁的区别?

  • 表级锁,每次操作锁住整张表。锁的粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM   InnoDB等存储引擎中。
  • 行级锁,每次操作锁住对应的行数据。锁的粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

   

   22.意向锁有什么作用?

      在DML操作的时候有可能会产生行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。

   23.共享锁和排他锁?

         共享锁是指允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

         排他锁是指允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。  insert  update delete 都会自动添加排他锁,而select不会加锁。

   24.MVCC

    

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值