美文网首页
java基础面试题总结——数据库

java基础面试题总结——数据库

作者: 天渊hyominnLover | 来源:发表于2018-08-15 10:56 被阅读8次

    1. 数据库事务4大特性(ACID),

    数据库事务4大特性(ACID):

    1.原子性(Atomicity):

    事务中一系列对数据库的操作要么全部成功,要么全部失败,如果成功就要全部应用到数据库,如果失败则不能对数据库造成任何影响

    2.一致性(Consistency)

    事务必须使数据库从一个一致性状态变换到另一个一致性状态(转账举例,两个账号转账前和转账后总金额数目不变)

    3.隔离性(Isolation)

    多个并发事务相互隔离,数据库为一个用户开启的事务不能被其他事务的操作干扰,数据库引擎提供了多种隔离级别来保证事务隔离性

    4.持久性(Durability)

    一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作

    2. 数据库事务隔离级别

    事务隔离级别由数据库引擎实现,由低到高依次为Read uncommitted(读未提交)、Read committed(读提交)、Repeatable read(可重复读)、Serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题

    1.脏读

    一个事务处理过程中读取了另一个事务中还未提交的数据:

    事务A:

    update account set money=money + 100 where name=’B’;  (此时A通知B查看账户)
    
    update account set money=money - 100 where name=’A’;
    

    事务B:

    select money from account where name=’B’; (B被通知查看账户)
    

    如果事务A最终操作不成功回滚,但B读取了修改后的账户金额(此为脏数据),即为脏读

    2.不可重复读

    事务A多次修改并最终提交了数据,事务B在事务A提交前读取了一个数据,在事务A提交后又读取了一个数据,两次数据不一致,即为不可重复读的问题。和脏读的区别是,不可重复读问题是读取的另一事务已提交的数据

    3.幻读(虚读)

    事务A对数据库中所有记录都进行了修改,但这个过程中事务B向表中插入了一条数据,事务A执行完成后发现数据库中有一条数据未被修改,就好像发生了幻觉一样,即为幻读

    MySQL数据库为我们提供的四种隔离级别:

    ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

    ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

    ③ Read committed (读已提交):可避免脏读的发生。

    ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

    隔离级别越高,执行效率越低,例如Serializable使用锁表的方式达到了最高的隔离级别;记得设置数据库的隔离级别一定要是在开启事务之前

    3. 设置数据库隔离级别

    • 在MySQL数据库中设置事务的隔离 级别:
    set  [glogal | session]  transaction isolation level 隔离级别名称;
    
    set tx_isolation=’隔离级别名称;’
    
    • 通过JDBC设置数据库隔离级别
      调用Connection对象的setTransactionIsolation(level)可设置当前链接的隔离级别,具体level设置如下:
    TRANSACTION_NONE: 指定该链接不支持事务
    TRANSACTION_READ_COMMITTED: 指定该链接的操作为读可提交,可解决脏读
    TRANSACTION_READ_UNCOMMITTED: 指定该链接的操作为读未提交,隔离等级最低
    TRANSACTION_REPEATABLE_READ: 指定该链接操作为可重复读,可解决脏读和不可重复读
    TRANSACTION_SERIALIZABLE: 指定链接为序列化,最高隔离等级
    

    对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

    4. sql依赖关系

    • 函数依赖:关系型数据库中有属性集合X,属性集合Y,若X中的元素能够唯一决定一个Y,则Y依赖于X,记为X -> Y
    • 完全函数依赖:X -> Y且对于任意X的真子集Z都存在Z !-> Y(即X所有元素才能唯一决定一个Y,X中的部分元素无法唯一决定一个Y),则称为Y对X的完全函数依赖
    • 部分函数依赖:Y完全函数依赖于X的真子集Z,则Y部分函数依赖于X
    • 传递函数依赖:X -> Y, Y -> Z, 且Y不是X真子集,Z不是Y真子集,Z不是X真子集,X不依赖于Y,则Z传递函数依赖于X
    • 平凡函数依赖:X -> Y且Y是X的真子集,则Y平凡函数依赖于X
    • 非平凡函数依赖:X -> Y且Y不是X的真子集,则Y非平凡函数依赖于X

    5. sql范式

    关系型数据库的范式是制定二维表的标准和依据

    • 1NF:表中的每一个属性都是原子属性(不可分割的数据项),非主属性对主属性存在部分或者完全函数依赖
    • 2NF:在1NF的前提下,每一个非主属性对于主键都是完全函数依赖的,但属性之间存在传递函数依赖
    • 3NF:在2NF的前提下,每个属性之间不存在传递函数依赖,即属性与属性之间基本独立
    • BCNF:在3NF前提下,表中只有一个候选键,没有多余候选键

    6. mysql事务的redo和undo机制

    事务常说一系列操作作为一个整体要么都成功要么都失败,主要特性acid,事务的的实现主要依赖两个log redo-log,undo-log,每次事务都会记录数据修改前的数据undo-log,修改后的数据放入redo-log,提出成功则使用redo-log 更新到磁盘,失败则使用undo-log将数据恢复到事务之前的数据

    7. Mysql锁机制

    mysql的锁机制是两段锁:将事务分为加锁阶段和解锁阶段两个阶段,加锁阶段对事务进行"读"的操作之前,需要申请S锁(共享锁),对事务进行"写"的操作之前,需要申请X锁(排它锁),当事务提交之后,就会释放锁,此时事务进入解锁阶断,在这个阶段只能进行解锁操作,不能再进行加锁操作

    1) 共享锁:

    共享锁的代号是S,S锁的锁粒度是行或者元组(多个行)。一个事务进行读操作时可以对数据加S锁,获取了S锁之后,可以对锁定范围内的数据执行读操作,其余事务也可以获取这部分数据的S锁,但无法获取X锁(写锁)

    2) 互斥锁:

    互斥锁代号是X,X锁的粒度与S锁相同,也是行或者元组。一个事务获取了X锁之后,可以对锁定范围内的数据执行写操作,其余事务无法获取这部分数据的S锁和X锁

    3) 乐观锁:

    mysql提供了种mvcc的机制,支持乐观锁,通过版本号的方式,避免同一数据不同事务间的竞争,所说的乐观锁只在事务级别为读未提交(Read committed)和 读已提交(Read committed)才会生效,也就是说对于这两个隔离级别,mysql就是使用乐观锁的方式保证并发

    4) 锁和事务隔离级别的关系:mysql就是通过锁机制来保证事务的隔离性:

    • 读未提交:无论是读的操作还是写的操作,都不会进行加锁操作
    • 读已提交:数据的读取操作不会进行加锁,但是数据的写入、修改和删除操作是需要加锁的,保证不会读到脏数据
    • 可重复读:数据的读取操作进行加锁,保证读取数据的一致性
    • 序列化:每次读取的时候事务都要获取表级别的S锁,每次写入的时候都会加写锁(X锁),读写操作会相互阻塞

    5) 数据库锁和索引的关系

    当加锁的语句没有涉及到该行数据的索引、指定索引不明确或者指定索引不为唯一索引,mysql会给整张表加锁,而不是给某个数据行加锁

    相关文章

      网友评论

          本文标题:java基础面试题总结——数据库

          本文链接:https://www.haomeiwen.com/subject/nsvibftx.html