博主
258
258
258
258
专辑

第三节 关系型数据库的问题

亮子 2022-08-04 13:57:42 9197 0 0 0

D1、【初级】你都使用过哪些数据库?

(1)MySQL:开源数据库,被Oracle公司收购
(2)Oracle:Oracle公司
(3)SQL Server:微软公司
(4)DB2:IBM公司
(5)PostgrepSql:1985年开发,号称世界最先进的开源数据库,目前越来越多的公司选择PostgrepSql
(6)ClickHouse:ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储的高效能分析性数据管理系统,具有原生的向量化执行引擎

理解思路

  • MySQL,经常使用
  • Oracle,维护项目的时候,使用
  • 其他都是听说过

D2、【初级】Mysql分页和Oracle分页关键字分别是什么?

(1)Mysql分页关键字limit 第一个参数是从第几条开始[下标],第二个参数是显示几条数据。

     select * from t_order limit 5,10;

(2)Oracle分页关键字是rownum(从1开始),Oracle数据库每条数据都有对应的下标,通过下标范围查询。

-- 40为pageCurrent * pageSize,31 应为为(pageCurrent - 1) * pageSize
SELECT * FROM  
(  
SELECT A.*, ROWNUM RN  
FROM (SELECT * FROM TABLE_NAME 
      WHERE 1 = 1 -- 条件
      ORDER BY CREATETIME DESC -- 排序
     ) A  
    WHERE ROWNUM <= 40  
 )  
WHERE RN >= 31

理解思路

  • MySQL分页关键字是limit,MySQL是开源的
  • Oracle分页关键字 rownum,是闭源
  • 都是甲骨文(Oracle)公司的产品

D3、【初级】where和having有啥区别?

(1)where和having都是做条件查询,where可以用于更新和删除条件,having可以使用聚合函数。
(2)having在group by之后使用,先分组在过滤。
(3)where在group by之前使用,先过滤在分组。
(4)如果where和having一起用时,where会先执行,having后执行。

理解思路

  • where 过滤之后产生结果
  • having 是对结果进行过滤

D4、【初级】左连接、右连接、内连接、全连接有什么区别?

(1)左连接(left join),以左表为主,返回左表全部数据,右表显示符合条件的,不符合则显示null。
左连接
(2)右连接(right join),以右表为主,返回右表全部数据,左表显示符合条件的,不符合则显示null。
右连接
(3)内连接(inner join),返回两张表都满足条件的部分
内连接
(4)全连接(full join),返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。(MySql数据库不支持全连接)
全连接

D5、【初级】Mysql数据库的存储引擎有哪些?

(1)InnoDB存储引擎:提供了良好的事务处理、崩溃修复能力和并发控制。缺点是读写效率较差,占用的数据空间相对较大。
(2)MyISAM存储引擎:优势在于占用空间小,处理速度快。缺点是不支持事务的完整性和并发性。
(3)MEMORY存储引擎:数据读写速度快。缺点是如果重启或者关机,所有数据都会消失。

D6、【初级】数据库设计三大范式?

(1)第一范式(1NF)列不可再分
(2)第二范式(2NF)属性完全依赖于主键
(3)第三范式(3NF)属性不依赖于其它非主属性,属性直接依赖于主键

D7、【初级】你对数据库中的冗余字段是怎么理解的?

(1)问题:占用存储空间、修改效率底
(2)优势:适当的冗余可以提升查询速度

D8、【初级】数据库的事务有哪些特性?

(1)原子性(Atomicity):最小的执行单元,不可分割,事务要么全部被执行,要么全部不执行
(2)一致性(Consistency):数据库从一种正确状态转换成另外一种正确状态,同步更新
(3)隔离性(Isolation):每个事务都是独立存在,互不影响。
(4)持久性(Durability):事务正确提交之后,其结果将永远保存在数据库之中。

D9、【初级】数据库的事务隔离级别有哪些?

(1)read_uncommitted(读未提交)
(2)read_commited(读已提交)
(3)repeatable_read(可重复读)
(4)serlalizable(串行化)

D10、【中级】每种隔离级别可能会出现什么问题?

隔离级别

D11、【初级】什么是脏读、不可重复度、幻读?

(1)脏读:事务A读到了事务B还没有提交的数据
(2)不可重复度(虚读):在同一个事务中前后多次,读出来的数据内容不一致。
(3)幻读:在一个事务里面的操作中发现了未被操作的数据。(前后多次读取,数据总量不一致,常发生在添加 或者 删除)

D12、【高级】数据库事务的底层是如何实现?

(1)通过undo log和redo log保证了事务的原子性和持久性
(2)通过mvcc和锁来保证事务的隔离性。
(3)保证了事务的原子性,持久性和隔离性就做到了事务的一致性。

D13、【中级】说说你对乐观锁的理解?

(1)不会阻塞,允许多个线程同时访问,但是只能有一个线程操作成功。
(2)一般会使用版本号或CAS实现,适用于读多写少的场景。

D14、【中级】说说你对悲观锁的理解?

(1)会阻塞,保证同一时刻,只有一个线程能够操作数据,其他线程阻塞挂起。
(2)Java中synchronized,lock,数据库中读锁,写锁等都是悲观锁的实现,适用于读少写多的场景。

D15、【中级】什么时候要用乐观锁?什么时候要用悲观锁?

(1)读多写少的时候用乐观锁
(2)写多读少的时候用悲观锁

D16、【中级】数据库锁有哪些?

(1)表锁

  • 读锁:所有线程只允许对当前表进行读操作,不允许写操作。
  • 写锁:只允许当前线程对表进行读写操作,其他线程既不能读也不能写。

(2)行锁

  • 共享锁:多个事务可以共同对同一数据加锁,共同使用一把锁,所有事务都可以进行读操作,但是只有当其他事务操作完成(释放锁)之后才能进行写入或更新。
  • 排它锁(独占锁):同一数据只能有一个事务进行加锁,当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。

D17、【中级】SQL优化你们是怎么做的?

(1)问题定位:找出慢查询语句或者CPU飙高的语句
(2)SQL语句分析:通过explain查看SQL的执行计划
(3)解决表设计、表索引、SQL语句中的问题

D18、【中级】你们是如何排查慢查询语句的?

(1)方法一:我们使用的是德鲁伊数据库连接池,他有一个web页面,可以查看哪些语句是慢查询语句。
(2)方法二:开启MySQL的慢查询日志,通过日志也可以查看哪些语句是慢查询语句。

D19、【中级】SQL查询中哪些情况会导致索引失效?

(1)查询条件中索引列使用了函数,比如日期转换,字符串处理,计算,统计等等,会导致索引失效。
(2)模糊查询like以%号开头会导致索引失效。
(3)范围查询可能会导致索引失效,in,or,is null,<>等。
(4)如果数据库中存储的数据很少,mysql的执行引擎认为全表扫描会比索引扫描更快,就不会再去查索引了。
(5)复合索引要遵循最左侧匹配原则,查询条件中如果没有最左侧列会导致索引失效。

D20、【初级】你们项目中的数据表都有哪些字段?

(1)id:主键
(2)create_by:创建人
(3)create_time:创建时间
(4)update_by:更新人
(5)update_time:更新时间
(6)del_flag:删除标识
(7)version:版本号

理解思路

  • 自增ID
  • 逻辑删除
  • 更新时间
  • 创建时间

D21、【中级】数据库索引的结构有哪些?

Mysql支持多种索引结构类型,哈希表,全文索引,B-Tree,B+Tree等。
(1)哈希表:只有memory存储引擎下支持哈希索引,底层哈希表,存储原理和HashMap类似。
(2)全文索引:MyISAM支持全文索引,生成全文索引非常消耗时间和空间,所以一般不会通过数据库做全文索引,通过sorl或es搜索引擎解决。
(3)B-Tree:B-Tree是多叉平衡树,每个节点保存索引值和数据。
(4)B+Tree:B-Tree的优化,数据保存到叶子节点,非叶子节点存储数据的地址。

D22、【初级】数据库的索引类型有哪些?

(1)主键索引:是一种特殊的唯一索引,在一张表中只能定义一个主键索引。
(2)唯一索引:唯一索引,不允许被索引列数据重复,可以为null,比如:学号,身份证号,手机号,用户名等都可以创建唯一索引。
(3)单值索引:允许被索引列的数据重复,性能比唯一索引,主键索引要差。
(4)复合索引:复合索引和单值索引的区别就是一个复合索引可以包含多个列。

D23、【初级】哪些字段适合建索引?

(1)频繁作为查询条件且过滤性好的字段应该创建索引。
(2)查询中与其它表关联的字段,关联字段上建立索引。
(3)排序、分组查询、排序字段、分组字段建议加索引。
(4)单键/复合索引的选择问题, 复合索引性价比更高;

D24、【初级】哪些情况不适合建立索引?

(1)表数据太少。(可以不说)
(2)经常增删改的表或者字段。
(3)查询条件里用不到的字段不创建索引。
(4)过滤性不好的不适合建索引。

D25、【中级】说说你对复合索引的最左匹配原则的理解?

(1)查询条件中必须要包含最左侧的索引列。
(2)查询条件中索引列要连续,中间不能断开。
(3)查询条件中如果有范围查询,则范围查询后的索引失效。
(4)查询条件中有null,or,<>可能会使整个复合索引失效。

D26、【高级】说说你对索引回表的理解?

(1)B+ 树索引主要可以分为两种索引,聚集索引和非聚集索引。
(2)聚集索引:也就是平常我们说的主键索引,在 B+ 树中叶子节点存的是整行数据
(3)非聚集索引:也叫二级索引,也就是一般的普通索引,在 B+ 树中叶子节点存的是主键的值
(4)我们如果直接用主键查找,用的是聚集索引,能找到全部的数据。
(5)如果我们是用非聚集索引查找,如果索引里不包含全部要查找的字段,则需要根据索引叶子节点存的主键值,再到聚集索引里查找需要的字段,这个过程也叫做回表。

索引回表

理解思路

  • 一定要说出聚簇索引和非聚簇索引的区别
  • 一定要举一个例子来说明回表

D27、【高级】说说B-tree和B+tree有什么区别?

B-tree和B+tree都是常用的数据结构,常用于实现高效的数据库索引。它们之间的主要区别如下:

(1)数据存储方式不同:B-tree节点中除了索引键外还会存储数据,而B+tree则只在叶子节点中存储数据,内部节点只存储索引信息。

(2)叶子节点结构不同:B-tree的叶子节点包含索引键和对应数据的指针,而B+tree的叶子节点只包含索引键和对应数据的指针。

(3)遍历方式不同:B-tree需要在非终端节点进行关键字比较,根据比较结果选择下一个子节点进行遍历;而B+tree只需在叶子节点进行比较,由于叶子节点形成了有序链表,因此可以很方便地进行范围查询等特定查询操作。

(4)索引检索效率不同:B-tree的检索效率相对较高,在低层次索引时性能优于B+tree;而B+tree索引具有更好的批量读写能力,在顺序读取时性能优于B-tree。

(5)多关键字处理能力不同:B-tree支持多关键字查询,可以在节点中存储多个key-value对;而B+tree只支持单关键字查询,需要按照多个关键字建立多个索引。

综上所述,B-tree和B+tree都是常用的数据结构,主要用于实现高效的数据库索引。它们的区别主要体现在存储方式、叶子节点结构、遍历方式以及索引检索效率等方面,需要根据实际需求进行选择。

理解思路

  • btree数据在所有节点上,查找时间不稳定
  • b+tree数据都在叶子节点上,b+tree的所有叶子节点组成一个双向链表,查找时间比较稳定,b+tree是存在指针的,也是顺序排序的,所以查找更快

D28、【高级】什么是索引回表,如何避免?

(1)回表:先定位【主键值】,再定位【行记录】,扫描了两次B+树,这就是回表。
(2)避免方法:用覆盖索引可以避免回表。将被查询的字段,建立到联合索引里去。

D29、【资深】执行计划中Explain中key_len是如何计算的?

(1) 影响key_len的因素有1、字符集;2、数据类型;3、定义长度;4、是否为null;
(2)key_len的计算方法详见下表:
key_len的计算方法

理解思路

  • 看KEY字段,为空则没有使用索引,不为空则使用了索引
  • 看KEYLEN字段,越短越好
  • 看Type

D30、MySQL死锁产生的原因和解决方法是什么?

  • 产生原因

当多个事务同时持有和请求同一资源上的锁而产生循环依赖的时候就产生了死锁。死锁发生在事务试图以不同的顺序锁定资源。以StockPrice表上的两个事务为例:

START TRANSACTION;
UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
COMMIT;
START TRANSACTION;
UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
UPDATE StockPrice SET;
COMMIT;

如果不走运的话,每个事务都可以执行完第一个语句,并在过程中锁住资源。然后每个事务都试图去执行第二行语句,当时却发现它被锁住了。两个事务将永远的等待对方完成,除非有其他原因打断死锁。

  • 解决方案

(1)使用更小的事务,尽量避免死锁
(2)修改事务的隔离级别
(3)使用更少的锁定。如果你可以接受允许一个SELECT从一个旧的快照返回数据,不要给它添加FOR UPDATE或LOCK IN SHARE MODE子句。