数据库面试常考点一

243 阅读7分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

一、MySQL四种常见的数据库引擎

1. InnoDB存储引擎

InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,InnoDB是默认的MySQL引擎。

(1)InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事物安全(ACID兼容)存储引擎

(2)InnoDB是为处理巨大数据量的最大性能设计

(3)InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池

(4)InnoDB支持外键完整性约束

(5)InnoDB被用在众多需要高性能的大型数据库站点上

2. MyISAM存储引擎

MyISAM基于ISAM存储引擎,并对其进行扩展。MyISAM拥有较高的插入、查询速度,但不支持事物

(1)大文件,在支持大文件的文件系统和操作系统上被支持

(2)每个MyISAM表最大索引数是64,这可以通过重新编译来改变。

使用MyISAM引擎创建数据库,将产生3个文件。文件的名字以表名字开始,扩展名之处文件类型:frm文件存储表定义、数据文件的扩展名为.MYD(MYData)、索引文件的扩展名时.MYI(MYIndex)

3. MEMORY存储引擎

MEMORY存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问

(1)可以在一个MEMORY表中有非唯一键值

4. Archive存储引擎

Archive支持高并发的插入操作,但是本身不是事务安全的。Archive非常适合存储归档数据,如记录日志信息可以使用Archive

5. 对比记忆

img_009790b51a88771c9d9d3a4ebd577f16.png

  • InnoDB:支持事务(提交、回滚、崩溃恢复能力的事务安全[ACID兼容]能力),要求实现并发控制
  • MyISAM:处理查询和查询效率极高
  • Memory:如果临时存放数据数据量不大,并且不需要较高的数据安全性。可以作为临时表,存放查询的中间结果。
  • Archive:如果只有insert和select操作,可以选择。支持高并发插入操作,但是本身不事务安全

使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能

二、事务特性(ACID)

  • 原子性(Atomicity):事务应该当作一个单独单元的操作,这意味着整个序列操作要么是成功,要么是失败的。

    保证1-6所有过程要么都执行,要么都不执行。一旦在执行某一步骤的过程中发生问题,就需要执行回滚操作。 假如执行到第五步的时候,B账户突然不可用(比如被注销),那么之前的所有操作都应该回滚到执行事务之前的状态。

  • 一致性(Consistency):这表示数据库的引用完整性的一致性,表中唯一的主键等。转账前后双方账户金额总和不变

    在转账之前,A和B的账户中共有500+500=1000元钱。在转账之后,A和B的账户中共有400+600=1000元。也就是说,数据的状态在执行该事务操作之后从一个状态改变到了另外一个状态。同时一致性还能保证账户余额不会变成负数等。

  • 隔离性(Isolation):可能同时处理很多有相同的数据集的事务,每个事务应该与其他事务隔离,以防止数据损坏。

    在A向B转账的整个过程中,只要事务还没有提交(commit),查询A账户和B账户的时候,两个账户里面的钱的数量都不会有变化。 如果在A给B转账的同时,有另外一个事务执行了C给B转账的操作,那么当两个事务都结束的时候,B账户里面的钱应该是A转给B的钱加上C转给B的钱再加上自己原有的钱。

  • 持久性(Durability):一个事务一旦完成全部操作后,这个事务的结果必须是永久性的,不能因系统故障而从数据库中删除。

    一旦转账成功(事务提交),两个账户的里面的钱就会真的发生变化(会把数据写入数据库做持久化保存)!

三、MySQL三大范式

第一范式:确保每列的原子性

  • 最基本的范式。

  • 数据库表中的字段都是单一属性,不可再分。

  • 只要是关系数据库都满足第一范式

  • 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式

    例如:顾客表(姓名、编号、地址、……)其中"地址"列还可以细分为国家、省、市、区等。

第二范式:确保表中的每列都和主键相关

如果一个关系满足第一范式,并且除了主键以外的其它列,都依赖于该主键,则满足第二范式.

例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系,即"产品编号"列不依赖于主键列,应删除该列。

第三范式:确保每列都和主键列直接相关,而不是间接相关

如果一个关系满足第二范式,并且除了主键以外的其它列都不传递依赖于主键列,则满足第三范式.

例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客编号"相关,"顾客编号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。为了满足第三范式,应去掉"顾客姓名"列,放入客户表中。

总结

  • 1NF:字段不可分
  • 2NF:有主键,非主键字段依赖主键
  • 3NF:非主键字段不能相互依赖

1NF:原子性,字段不可再分,否则就不是关系数据库

2NF:唯一性,一个表只说明一个事物

3NF:每列都与主键有直接关系,不存在传递依赖

四、MySQL排他锁&共享锁

mysql锁机制分表级锁行级锁。共享锁和排他锁都属于行级锁。

  • 共享锁:读锁,简称S锁。共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
  • 排他锁:写锁,简称X锁。排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。

对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据,对于排他锁大家的理解可能就有些差别,我当初就犯了一个错误,以为排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的。

排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select ...for update语句,加共享锁可以使用select ... lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制。