• MySQL面试问题(一)


    文章目录

    数据库三范式是什么?

    1. 第一范式(1NF):字段具有原子性,不可再分。
    2. 第二范式(2NF):要求数据库表中的每条记录都必须被唯一的区分,即具有主键;
    3. 第三范式(3NF):要求数据库表中不包含已在其它表中已包含的非主关键字信息。非主键字段依赖主键字段,不存在以来传递。

    MySQL的技术特点是什么?

    1. MySQL是一个客户端或服务器系统,其中包含支持各种客户端程序和库的多线程SQL服务器、不同的后端、广泛的应用程序编程接口和管理工具。
    2. MySQL是开源软件,随时可用,无需付费;MySQL是便携式的。

    主键和候选键有什么区别?

    1. 每条记录都由主键唯一标识,一个表只有一个主键。
    2. 主键也是候选键,按照惯例,候选键也可以被指定为主键,并且可以用于任何外键引用。

    Heap表是什么?

    1. heap表存在于内存中,用于临时高速存储。blob或text字段是不允许的,只能使用比较运算法,heap表不支持auto_increment,索引不可以为null。
    2. 通过max_heap_table_size配置来控制heap表的大小。

    MySQL表中允许有多少个触发器

    1. before insert、after insert;
    2. before update、after update;
    3. before delete、after delete。

    列设置为auto_increment时,如果在表中达到最大值,会发生什么情况?

    1. 列会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。

    2. 怎么找出最后一次插入时分配了那个自动增量?

      last_insert_id返回由auto_increment分配的最后一个值,并且不需要指定表名称。

    3. 一张表中有ID自增主键,当insert了17条记录后,删除了第15,16,17条记录,再把mysql重启,再insert一条记录,这条记录的id是18还是15?

      如果是myisam表,那么是18,因为MyISAM表会把自增主键的最大ID记录到数据文件中,重启后不会丢失;如果是innodb则是15,InnoDB只是把自增主键的最大ID记录到内存中,重启后会丢失。

    请简述常用的索引有哪些种类?

    1. 普通索引:即针对数据库表创建索引;
    2. 唯一索引:数据库索引列的值必须唯一,但允许有空值;
    3. 主键索引:特殊的唯一索引,不允许有空值,一般在建表时候创建主键索引;
    4. 组合索引:为了进一步提升效率,考虑建立;
    5. 任何标准表最多可以创建16个索引;
    6. 查看表中的所有索引:show index from table;
    7. 索引是加快检索表中数据的方法;索引降低了插入、删除、修改等任务的速度;唯一索引可以每行数据的唯一性;索引需要占物理和数据空间。

    MySQL有关权限的表有哪些?

    1. mysql权限表由mysql_install_db脚本初始化,这些权限表分别为user, db, table_priv, columns_priv和host。

    like声明中的%和_是什么意思?

    1. %表示0个或多个字符,_表示一个字符。

    2. like和regexp操作有什么区别

      like和regexp运算符用于表示^和%。

    select emp_name from employee where emp_name regexp "^b";
    select emp_name from employee where emp_name like "b%";
    
    • 1
    • 2

    什么是存储过程?有哪些优缺点?

    1. 存储过程是一些预编译的SQL语句。存储过程可以说是一个记录集,由一些T-SQL语句组成的代码块,这些T-SQL语句就是一个方法一样实现一些功能;
    2. 处处过程执行效率高,一个存储过程替代大量T-SQL语句,可以降低网络通信量,提高通信速率,可以一定程度上确保数据安全。

    有那些数据库优化方面的经验?

    1. 用PreparedStatement替代Statement,一个sql发给服务器去执行,涉及语法检查、语义分析、编译、缓存;
    2. 有外键约束会影响插入和删除性能,如果能够保证数据完整性,那在设计数据库时就去掉外键;表中允许适当冗余,比如主题帖的回复数量和最后回复时间等;
    3. union all要比union快很多,如果可以确认合并的两个结果集中不包含重复数据且不需要排序时的话,那么就是用union all;子查询转换成连接查询,在join表的时候使用相同类型的列;
    4. distinct在所有列上转换为group by,并与order by子句结合使用;
    5. 用查询缓存优化查询,像now()这类的SQL函数都不会开启查询缓存,因为这些函数的返回是不固定的,可以使用变量来替换MySQL的函数,从而开启缓存。
    6. 当只要一行数据时使用limit 1,当你查询表的时候,如果已经知道只会有一个结果,但因为你可能需要去fetch游标,或者会检查返回的记录数。这种情况下增加limit 1可以提升性能。
    7. 从procedure analyse()取得建议;
    8. 越小的列会越快,尽可能使用更小的字段;
    9. 避免使用null,空值需要特殊处理,可以使用默认值。

    若一张表中只有一个字段VARCHAR(N)类型,utf8编码,则N 最大值为多少?

    1. 由于utf8的每个字符最多占用3个字节,每行的长度不能超过65535,因此N的最大值计算方法是(65535-1-2)/3。减去1是因为实际存储从第二个字节开始,减去2是因为要在列表长度存储时机的字符长度,除以3是utf8限制。

    MySQL中varchar与char的区别以及varchar(50)中的50代表的含义?

    1. varchar是一种可变长度类型,char是固定长度的类型,当char值被存储时,它们被用空格填充到特定长度,检索char值时需要删除尾随空格。
    2. varchar(50)中50是指最多存放50个字节;
    3. int(20)中20是指最大显示宽度是20,最大设为255。

    MySQL中InnoDB引擎的行锁是如何实现的?

    1. InnoDB行锁通过给索引上的索引项加锁来实现的,这一点MySQL和Oracle不同,后者通过在数据块中相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着只有通过索引条件检索数据,InnoDB才使用行级锁,否则使用表锁。
    2. 举例说明。
    # for update可以根据条件完成行锁锁定,如果id不是索引键,那么将完成表锁
    select * from tab_with_index where id=1 for update;
    
    • 1
    • 2

    timestamp在update current_timestamp数据类型上做什么?

    1. 创建表时timestamp列用zero更新。只要表中的其他字段发生更改,update timestamp修饰符就将时间戳字段更新为当前时间。

    2. 如何在unix和mysql时间戳之间进行转换?

      unix_timestamp是从mysql时间戳转换为unix时间戳的命令;

      from_timestamp是从unix时间戳转换为mysql时间戳的命令。

    now和current_date有什么区别?

    1. now()用于显示当前年月日时分秒;
    2. current_date()仅显示当前年月日。

    什么是事务,以及事务的四大特性?

    1. 事务是并发控制的单位,是一个操作序列,这些操作要么都执行,要么都不执行,是不可分工的工作单位;

    2. 事务具有原子性、一致性、隔离性、持久性;

    3. 有多少种日志?

      错误日志:记录出错信息,也记录一些警告信息或正确的信息;

      查询日志:记录所有对数据库请求的信息,不论是否得到正确的执行;

      慢查询日志:设置一个域值,将运行时间超过该值的所有SQL语句都记录到慢查询日志文件中;

      二进制日志:记录对数据库执行更改的所有操作;

      中继日志:也是二进制日志,用来给slave库恢复;

      事务日志:重做日志和回滚日志。

    4. 事务是如何通过日志来实现的?

      事务日志是通过redo和InnoDb的存储引擎日志缓冲(InnoDB log buffer)来实现的,当一个事务开始时候,会记录该事务的lsn(log sequence number);当事务执行时,会往日志缓存中插入事务日志;当事务提交时,必须将日志缓冲写入磁盘,写数据前需要先写日志。

    MySQL中enum的用法是什么?

    1. enum是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用;
    2. 列的字符串类型可以有set、blob、enum、char、text、varchar。
    create table size(name enum('Small', 'Medium', 'Large'));
    
    • 1

    事务的隔离级别有哪些,MySQL默认是哪个?

    1. 读未提交:所有事务都可以看到其他未提交事务的执行结果,可能出现脏读、幻读、不可重复读;
    2. 读已提交:大多数数据库系统的默认隔离级别。一个事务只能看见已经提交事务所做的改变,可能出现不可重复读、幻读;
    3. 可重复读:MySQL的默认隔离级别,确保同一事务的多个实例在并发读取数据时,会看到同样数据行,可能出现幻读。幻读是指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的幻影行。InnoDB通过MVCC机制解决了该问题。
    4. 可串行:通过强制事务排序,使得不能相互冲突,从而解决幻读问题。在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

    having和where的异同点?

    1. 语法上:where用表中列名,having用select结果别名;
    2. 影响结果范围:where是从表中读出数据的行数,having返回客户端的行数;
    3. 索引:where可以使用索引,having不能使用索引,只能在临时结果集操作;
    4. where后面不能使用聚合函数,having是专门使用聚集函数的。

    如何区分FLOAT和DOUBLE?

    1. 浮点数是以8位精度存储在FLOAT中,并且有4个字节;
    2. 浮点数存储在DOUBLE中,精度为18位,有8个字节。

    区分char_length和length?

    1. char_length是字符数,而length是字节数。Latin字符的这两个数据是相同的,其他编码情况下,两者不相同。
    2. 在utf8mb4字符集下,char_length一个汉字长度是1,而length长度是3。

    MySQL当记录不存在时insert,存在时update,语句怎么写?

    insert into T(a,b,c) values(1,2,3) on duplicate key update c=c+1;
    
    • 1

    数据库的乐观锁和悲观锁是什么?

    1. 乐观锁假定不会发生并发冲突,只有在提交操作时检查是否违反数据完整性;
    2. 悲观锁假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

    MySQL常用函数?

    1. 数学函数

      abs求绝对值,floor向下取整,ceil向上取整;

    2. 字符串函数

      替换函数:insert(s1, index, length, s2) ,s1表示被替换的字符串,s2表示将要替换的字符串,index表示被替换的起始位置,length表示被替换的长度;

      字母变大写函数:upper(str)、ucase(str);

      字母变小写函数:lower(str)、lcase(str);

      返回字符串的前length个字符:left(str, length);

      返回字符串的后length个字符:right(str, length);

      返回字符串从index开始长度为length个字符:substring(str, index, length);

      将字符串倒序:reverse(str);

    3. 日期函数

      获取当前日期:curdate()、current_date();

      获取当前时间:curtime()、current_time();

      获取当前时间和日期:now();

      获取天数差:datediff(d1, d2);

      返回指定日期后num天的日期:adddate(date, num);

      返回指定日期前num天的日期:subdate(date, num);

    4. 聚合函数

      count、max、min、avg、sum。

    MySQL的insert和update的select语句写法?

    insert into student(id, name, deptid) select 10, 'xm', 3 from student where id>8;
    update student a inner join student b on b.id=10 set a.name=concat(b.name, b.id) where a.id=10;
    
    • 1
    • 2

    [select *]和[select 全部字段]的写法有何优缺点?

    1. 前者要解析数据字段,后者不需要;
    2. 结果输出顺序,前者与建表顺序相同,后者按指定字段顺序;
    3. 表字段改名,前者不需要修改,后者需要修改;
    4. 后者可以建立索引进行优化,前者无法优化;
    5. 后者的可读性比前者要高。

    MyISAM与InnoDB的区别?

    1. InnoDB支持事务,而MyISAM不支持事务;
      InnoDB支持行级锁,而MyISAM不支持;
      InnoDB支持MVCC,而MyISAM不支持;
      InnoDB支持外键,而MyISAM不支持;
      InnoDB不支持全文索引,而MyISAM支持;
      InnoDB和MyISAM都是B+树索引,InnoDB是索引组织表,而MyISAM是堆表;
    2. 可移植性、备份及恢复:MyISAM数据是以文件形式存储的,所以在跨平台数据转移中都会很方便;InnoDB免费的方案可以是拷贝数据文件、备份binlog,或者使用mysqldump,在数据量达到几十G的时候就会相对痛苦了;
    3. 存储结构:MyISAM在磁盘上存储成三个文件。第一个文件的名称以表的名字开始,扩展名指出文件类型。.frm文件存储表定义,数据文件扩展名为.MYD,索引文件扩展名为.MYD。InnoDB所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
    4. InnoDB的四大特性?
      插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(ahi)、预读(read ahead)。

    使用索引查询一定能够提高性能?

    1. 通常情况下使用索引查询数据比全表扫描要快,但是也要注意它的代价;
    2. 索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改,每条记录的增删改需要增加几次磁盘IO,因为索引需要额外的存储空间和处理,那些不必要的索引反而会使反应时间变慢;
    3. 索引的范围查询适用于两种情况:基于一个范围的检索,一般查询返回结果集小于表中记录数的30%;基于非唯一性索引的检索。

    如何查看MySQL的执行计划?

    1. explain出来的各项的含义?

      id:每个被独立执行的操作标志,id值越大越先执行;

      select_type:查询中每个select子句的类型;

      table:被操作对象的名称;

      partitions:匹配的分区信息;

      type:连接类型;

      possible_keys:列举出可能会用到的索引;

      key:实际用到的索引;

      key_len:用到的索引键的平均长度,单位是字节;

      ref:表示本行被操作的对象的参照对象;

      rows:估计每次需要扫描的行数;

      filtered:rows*filtered/100表示该步骤最后预估得到的行数;

      extra:额外的补充信息。

    2. profile的意义及使用场景?

      profile用来分析sql性能的消耗分布情况,当使用explain无法解决慢SQL的时候,需要用profile进行更细致的分析,找出sql所花的时间大部分消耗在哪个部分,确认性能瓶颈。

    binlog几种日志录入格式区别?

    1. statement/row模式,mixed模式是两者的结合;
    2. 在一条SQL操作了多行记录时,statement更节省空间,但是row模式更可靠。

    索引失效的情况有哪些?

    1. 联合索引不满足最左匹配原则;
    2. 使用了select *;
    3. 索引列上有函数或者做计算;
    4. 字段类型不同;
    5. 模糊查询like左边包括%;
    6. 使用not in和not exist。

    什么是回表查询?

    1. 先通过数据库索引扫描出数据所在的行,在通过行主键取出索引中未提供的数据,也就是说非主键索引的查询需要多扫描一棵索引树。

    什么是MVCC?

    1. MVCC指的是多版本并发控制,只有在InnoDB引擎下存在,通过版本号避免同一数据在不同事务之间的竞争,实现事务的隔离性,MVCC的优势是读不加锁,读写不冲突;
    2. 在多线程操作数据过程中,MVCC保证事务隔离的机制,可以降低锁竞争的压力,保证较高的并发量。每开启一个事务时,会生成一个事务的版本号,被操作的数据会临时生成一条新的数据行,但是在提交之前对其他事务是不可见的。对于数据的更新操作成功后会将这个版本号更新到数据行中,事务提供成功,把新的版本号更新到此数据行中,这样保证了每个事务操作数据都是互不影响的。InnoDB在每行数据都增加两个隐藏字段,一个记录创建的版本号,一个记录删除的版本号。

    MySQL复制的原理以及流程?

    1. 基本原理流程,三个线程以及它们之间的关系?

      主:binlog线程——记录下所有改变了数据库数据的语句,放到master上的binlog中;

      从:io线程——在使用start slave后,负责从master上拉取binlog内容,写入到relay log中;

      从:sql执行线程——执行relay log中的语句。

    2. MySQL支持的复制类型

    (1)基于语句的复制:在主服务器执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率较高。一旦发现没法精确复制时,会自动选择基于行的复制。
    (2)基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍,从MySQL5.0开始支持;
    (3)混合类型的复制:默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。

    1. 一致性延时性?

      延时性:MySQL5.7是多线程复制,基于group commit,只要master上的事务是group comiit的,那么slave上也可以通过多个worker线程去并发执行。

    数据库备份?

    # 导出整个数据库
    mysqldump -u 用户名 -p 数据库名 > 导出文件名
    # 导出一个表
    mysqldump -u 用户名 -p 数据库名 表名 > 导出文件名
    # 导出一个数据库结构,-d没有数据, --add-drop-table在每个create语句前增加一个drop table
    mysqldump -u dbuser -p -d --add-drop-table dbname > C:/dbname_db.sql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    MySQL数据库CPU飙到500%怎么处理?

    1. 列出所有进程show processlist,观察进程,干掉长时间没有变化的;
    2. 查看超时日志或错误日志,一般是查询以及大批量的插入更新会导致CPU与IO飙升。

    InnoDB的读写参数优化?

    1. 读取参数

      global buffer pool:innodb_buffer_pool_size、innodb_log_buffer_size;

      local buffer:join_buffer_size、read_buffer_size、key_buffer_size、sort_buffer_size。

    2. 写入参数

      insert_buffer_size、innodb_double_write、innodb_write_io_thread。

    3. 与IO相关参数

      innodb_io_capacity、innodb_lru_scan_depth。

    4. 缓存参数以及使用场景

      query_cache_size、query_cache_type。

    简单说下drop、delete与truncate的区别?

    1. delete、truncate只删除表数据而不删除表结构;
    2. 从速度来说,drop > truncate > delete;
    3. delete语句是DML,会放到rollback segement中,事务提交后才会生效;
    4. 如果有相应的触发器,执行时候会被触发。truncate、drop是DDL,操作立即生效,元数据不放到回滚段中,不能回滚。

    主从一致性校验?

    使用第三方工具,比如checksum、mysqldiff等。

    innodb_io_capacity、innodb_lru_scan_depth。

    1. 缓存参数以及使用场景

      query_cache_size、query_cache_type。

    简单说下drop、delete与truncate的区别?

    1. delete、truncate只删除表数据而不删除表结构;
    2. 从速度来说,drop > truncate > delete;
    3. delete语句是DML,会放到rollback segement中,事务提交后才会生效;
    4. 如果有相应的触发器,执行时候会被触发。truncate、drop是DDL,操作立即生效,元数据不放到回滚段中,不能回滚。

    主从一致性校验?

    使用第三方工具,比如checksum、mysqldiff等。

  • 相关阅读:
    Prometheus+Grafana可视化监控【Redis状态】
    C++图像金字塔下采样的函数
    产品设计师根据处理哪些问题来设计外观?
    Java中的反射
    IDEA中JDBC连接MYSQL数据库步骤超详细总结
    HTML+CSS+JS制作一个迅雷看看电影网页设计实例 ,排版整洁,内容丰富,主题鲜明,简单的网页制作期末作业
    一文总结你需要的OpenCV操作
    经典的设计模式6——桥接模式
    Spring Authorization Server授权服务器入门
    LeetCode 200. 岛屿数量
  • 原文地址:https://blog.csdn.net/dolly_baby/article/details/126807465