加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 钦州站长网 (https://www.0777zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql字段 MySQL 经典 38 问!

发布时间:2022-10-15 11:07:25 所属栏目:MySql教程 来源:
导读:  今天给大家分享MySQL 常考的面试题,看看你们能答对多少

  本期 MySQL 面试题的目录如下:

  常见的存储引擎有哪些?MyISAM 和 InnoDB 的区别?MVCC 实现原理?快照读和当前读共享锁和排他锁大表怎么
  今天给大家分享MySQL 常考的面试题,看看你们能答对多少
 
  本期 MySQL 面试题的目录如下:
 
  常见的存储引擎有哪些?MyISAM 和 InnoDB 的区别?MVCC 实现原理?快照读和当前读共享锁和排他锁大表怎么优化?bin log / redo log / undo logbin log 和 redo log 有什么区别?讲一下 MySQL 架构?分库分表什么是分区表?分区表类型查询语句执行流程?更新语句执行过程?exist 和 in 的区别?truncate、delete 与 drop 区别?having 和 where 的区别?什么是 MySQL 主从同步?为什么要做主从同步?乐观锁和悲观锁是什么?用过 processlist 吗?事务的四大特性?
 
  事务特性 ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
 
  事务隔离级别有哪些?
 
  先了解下几个概念:脏读、不可重复读、幻读。
 
  不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
 
  幻读和不可重复读都是读取了另一条已经提交的事务,不同的是不可重复读的重点是修改,幻读的重点在于新增或者删除。
 
  事务隔离就是为了解决上面提到的脏读、不可重复读、幻读这几个问题。
 
  MySQL 数据库为我们提供的四种隔离级别:
 
  查看隔离级别:
 
  select @@transaction_isolation;
  设置隔离级别:
 
  set session transaction isolation level read uncommitted;
  索引什么是索引?
 
  索引是存储引擎用于提高数据库表的访问速度的一种数据结构。
 
  索引的优缺点?
 
  优点:
 
  缺点:
 
  索引的作用?
 
  数据是存储在磁盘上的,查询数据时,如果没有索引,会加载所有的数据到内存,依次进行检索,读取磁盘次数较多。有了索引,就不需要加载所有数据,因为 B+ 树的高度一般在 2-4 层,最多只需要读取 2-4 次磁盘,查询速度大大提升。
 
  什么情况下需要建索引?经常用于查询的字段经常用于连接的字段建立索引,可以加快连接的速度经常需要排序的字段建立索引,因为索引已经排好序,可以加快排序查询速度什么情况下不建索引?where条件中用不到的字段不适合建立索引表记录较少需要经常增删改参与列计算的列不适合建索引区分度不高的字段不适合建立索引,如性别等索引的数据结构
 
  索引的数据结构主要有 B+ 树和哈希表,对应的索引分别为 B+ 树索引和哈希索引。InnoDB 引擎的索引类型有 B+ 树索引和哈希索引,默认的索引类型为 B+ 树索引。
 
  B+ 树索引
 
  B+ 树是基于 B 树和叶子节点顺序访问指针进行实现,它具有 B 树的平衡性mysql字段,并且通过顺序访问指针来提高区间查询的性能。
 
  在 B+ 树中,节点中的 key 从左到右递增排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,则该指针指向所有 key 大于等于 keyi 且小于等于 keyi+1的节点。
 
  进行查找操作时,首先在根节点进行二分查找,找到key所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出key所对应的数据项。
 
  MySQL 数据库使用最多的索引类型是BTREE索引,底层基于 B+ 树数据结构来实现。
 
  mysql> show index from blog\G;
  *************************** 1. row ***************************
          Table: blog
     Non_unique: 0
       Key_name: PRIMARY
   Seq_in_index: 1
    Column_name: blog_id
      Collation: A
    Cardinality: 4
       Sub_part: NULL
         Packed: NULL
           Null:
     Index_type: BTREE
        Comment:
  Index_comment:
        Visible: YES
     Expression: NULL
  哈希索引
 
  哈希索引是基于哈希表实现的,对于每一行数据,存储引擎会对索引列进行哈希计算得到哈希码,并且哈希算法要尽量保证不同的列值计算出的哈希码值是不同的,将哈希码的值作为哈希表的 key 值,将指向数据行的指针作为哈希表的 value 值。这样查找一个数据的时间复杂度就是 O(1),一般多用于精确查找。
 
  Hash 索引和 B+ 树索引的区别?为什么 B+ 树比 B 树更适合实现数据库索引?索引有什么分类?
 
  1、主键索引:名为 primary 的唯一非空索引,不允许有空值。
 
  2、唯一索引:索引列中的值必须是唯一的,但是允许为空值。唯一索引和主键索引的区别是:唯一约束的列可以为null且可以存在多个null值。唯一索引的用途:唯一标识数据库表中的每条记录,主要是用来防止数据重复插入。创建唯一索引的 SQL 语句如下:
 
  ALTER TABLE table_name
  ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);
  3、组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时需遵循最左前缀原则。
 
  4、全文索引:只有在MyISAM引擎上才能使用,只能在CHAR、VARCHAR和TEXT类型字段上使用全文索引。
 
  什么是最左匹配原则?
 
  如果 SQL 语句中用到了组合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个组合索引去进行匹配。当遇到范围查询(>、 2 and c = 3,那么 a、b 两个字段能用到索引,而 c 无法使用索引,因为 b 字段是范围查询,导致后面的字段无法使用索引。
 
  如下图,对 (a, b) 建立索引,a 在索引树中是全局有序的,而 b 是全局无序,局部有序(当 a 相等时,会根据 b 进行排序)。
 
  当 a 的值确定的时候,b 是有序的。例如a = 1时,b 值为 1,2 是有序的状态。当执行a = 1 and b = 2时 a 和 b 字段能用到索引。而对于查询条件a < 4 and b = 2时,a 字段能用到索引,b 字段则用不到索引。因为 a 的值此时是一个范围,不是固定的,在这个范围内 b 的值不是有序的,因此 b 字段无法使用索引。
 
  什么是聚集索引?
 
  InnoDB 使用表的主键构造主键索引树,同时叶子节点中存放的即为整张表的记录数据。聚集索引叶子节点的存储是逻辑上连续的,使用双向链表连接,叶子节点按照主键的顺序排序,因此对于主键的排序查找和范围查找速度比较快。
 
  聚集索引的叶子节点就是整张表的行记录。InnoDB 主键使用的是聚簇索引。聚集索引要比非聚集索引查询效率高很多。
 
  对于InnoDB来说,聚集索引一般是表中的主键索引,如果表中没有显示指定主键,则会选择表中的第一个不允许为NULL的唯一索引。如果没有主键也没有合适的唯一索引,那么InnoDB内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键长度为 6 个字节,它的值会随着数据的插入自增。
 
  什么是覆盖索引?
 
  select的数据列只用从索引中就能够取得,不需要回表进行二次查询,也就是说查询列要被所使用的索引覆盖。对于innodb表的二级索引,如果索引能覆盖到查询的列,那么就可以避免对主键索引的二次查询。
 
  不是所有类型的索引都可以成为覆盖索引。覆盖索引要存储索引列的值,而哈希索引、全文索引不存储索引列的值,所以 MySQL 使用 b+ 树索引做覆盖索引。
 
  对于使用了覆盖索引的查询,在查询前面使用explain,输出的 extra 列会显示为using index。
 
  比如user_like 用户点赞表,组合索引为(user_id, blog_id),user_id和blog_id都不为null。
 
  explain select blog_id from user_like where user_id = 13;
  explain结果的Extra列为Using index,查询的列被索引覆盖,并且 where 筛选条件符合最左前缀原则,通过索引查找就能直接找到符合条件的数据,不需要回表查询数据。
 
  explain select user_id from user_like where blog_id = 1;
  explain结果的Extra列为Using where; Using index, 查询的列被索引覆盖,where 筛选条件不符合最左前缀原则,无法通过索引查找找到符合条件的数据,但可以通过索引扫描找到符合条件的数据,也不需要回表查询数据。
 
  mysql set 字段_mysql字段_mysql 字段允许为空
 
  索引的设计原则?索引什么时候会失效?
 
  导致索引失效的情况:
 
  什么是前缀索引?
 
  有时需要在很长的字符列上创建索引,这会造成索引特别大且慢。使用前缀索引可以避免这个问题。
 
  前缀索引是指对文本或者字符串的前几个字符建立索引,这样索引的长度更短,查询速度更快。
 
  创建前缀索引的关键在于选择足够长的前缀以保证较高的索引选择性。索引选择性越高查询效率就越高,因为选择性高的索引可以让 MySQL 在查找时过滤掉更多的数据行。
 
  建立前缀索引的方式:
 
  // email列创建前缀索引
  ALTER TABLE table_name ADD KEY(column_name(prefix_length));
  常见的存储引擎有哪些?
 
  MySQL 中常用的四种存储引擎分别是:MyISAM、InnoDB、MEMORY、ARCHIVE。MySQL 5.5 版本后默认的存储引擎为InnoDB。
 
  InnoDB 存储引擎
 
  InnoDB 是 MySQL默认的事务型存储引擎,使用最广泛,基于聚簇索引建立的。InnoDB 内部做了很多优化,如能够自动在内存中创建自适应 hash 索引,以加速读操作。
 
  优点:支持事务和崩溃修复能力;引入了行级锁和外键约束。
 
  缺点:占用的数据空间相对较大。
 
  适用场景:需要事务支持,并且有较高的并发读写频率。
 
  MyISAM 存储引擎
 
  数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,可以使用 MyISAM 引擎。MyISAM 会将表存储在两个文件中,数据文件.MYD和索引文件.MYI。
 
  优点:访问速度快。
 
  缺点:MyISAM 不支持事务和行级锁,不支持崩溃后的安全恢复,也不支持外键。
 
  适用场景:对事务完整性没有要求;表的数据都是只读的。
 
  MEMORY 存储引擎
 
  MEMORY 引擎将数据全部放在内存中,访问速度较快,但是一旦系统崩溃的话,数据都会丢失。
 
  MEMORY 引擎默认使用哈希索引,将键的哈希值和指向数据行的指针保存在哈希索引中。
 
  优点:访问速度较快。
 
  缺点:
 
  哈希索引数据不是按照索引值顺序存储,无法用于排序。不支持部分索引匹配查找,因为哈希索引是使用索引列的全部内容来计算哈希值的。只支持等值比较,不支持范围查询。当出现哈希冲突时,存储引擎需要遍历链表中所有的行指针,逐行进行比较,直到找到符合条件的行。
 
  ARCHIVE 存储引擎
 
  ARCHIVE 存储引擎非常适合存储大量独立的、作为历史记录的数据。ARCHIVE 提供了压缩功能,拥有高效的插入速度,但是这种引擎不支持索引,所以查询性能较差。
 
  MyISAM 和 InnoDB 的区别?
 
  是否支持行级锁 : MyISAM 只有表级锁,而InnoDB 支持行级锁和表级锁,默认为行级锁。
 
  是否支持事务和崩溃后的安全恢复:MyISAM 不提供事务支持,而InnoDB提供事务支持,具有事务、回滚和崩溃修复能力。
 
  是否支持外键: MyISAM不支持,而InnoDB支持。
 
  是否支持MVCC :MyISAM不支持,InnoDB支持。应对高并发事务,MVCC 比单纯的加锁更高效。
 
  MyISAM不支持聚集索引,InnoDB支持聚集索引。
 
  MVCC 实现原理?
 
  MVCC(Multiversion concurrency control) 就是同一份数据保留多版本的一种方式,进而实现并发控制。在查询的时候,通过read view和版本链找到对应版本的数据。
 
  作用:提升并发性能。对于高并发场景,MVCC 比行级锁开销更小。
 
  MVCC 实现原理如下:
 
  MVCC 的实现依赖于版本链,版本链是通过表的三个隐藏字段实现。
 
  每条表记录大概是这样的:
 
  使用事务更新行记录的时候,就会生成版本链,执行过程如下:
 
  用排他锁锁住该行;将该行原本的值拷贝到undo log,作为旧版本用于回滚;修改当前行的值,生成一个新版本,更新事务 id,使回滚指针指向旧版本的记录,这样就形成一条版本链。
 
  下面举个例子方便大家理解。
 
  1、初始数据如下,其中DB_ROW_ID和DB_ROLL_PTR为空。
 
  2、事务A对该行数据做了修改,将age修改为 12,效果如下:
 
  3、之后事务B也对该行记录做了修改,将age修改为 8,效果如下:
 
  4、此时 undo log 有两行记录,并且通过回滚指针连在一起。
 
  接下来了解下 read view 的概念。
 
  read view可以理解成将数据在每个时刻的状态拍成“照片”记录下来。在获取某时刻 t 的数据时,到 t 时间点拍的“照片”上取数据。
 
  在read view内部维护一个活跃事务链表,表示生成read view的时候还在活跃的事务。这个链表包含在创建read view之前还未提交的事务,不包含创建read view之后提交的事务。
 
  不同隔离级别创建 read view 的时机不同。
 
  read view 的记录筛选方式
 
  前提:DATA_TRX_ID 表示每个数据行的最新的事务 ID;up_limit_id表示当前快照中的最先开始的事务;low_limit_id表示当前快照中的最慢开始的事务,即最后一个事务。
 
  总结:InnoDB 的MVCC是通过 read view 和版本链实现的,版本链保存有历史版本记录,通过read view 判断当前版本的数据是否可见,如果不可见,再从版本链中找到上一个版本,继续进行判断,直到找到一个可见的版本。
 
  快照读和当前读
 
  表记录有两种读取方式。
 
  快照读情况下,InnoDB 通过mvcc机制避免了幻读现象。而mvcc机制无法避免当前读情况下出现的幻读现象。因为当前读每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。
 
  下面举个例子说明下:
 
  1、首先,user 表只有两条记录,具体如下:

  2、事务 a 和事务 b 同时开启事务start transaction;
 
  3、事务 a 插入数据然后提交;
 
  insert into user(user_name, user_password, user_mail, user_state) values('tyson', 'a', 'a', 0);
  4、事务 b 执行全表的 update;
 
  update user set user_name = 'a';
  5、事务 b 然后执行查询,查到了事务 a 中插入的数据。(下图左边是事务 b,右边是事务 a。事务开始之前只有两条记录,事务 a 插入一条数据之后,事务 b 查询出来是三条数据。)
 

(编辑:PHP编程网 - 钦州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!