数据库的一些基本概念

1. 事务

事务是数据库中一个单独的执行单元(Unit),它通常由高级数据库操作语言(SQL等)或编程语言(Java、C++等)编写的用户程序的执行所引起的。当在数据库中更改数据成功时,在事务中更改的数据便会提交,不再改变。否则,事务就取消或者回滚。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。

例如,网上购物的一次交易,其付款过程至少包括以下几步数据库操作:

  1. 更新客户所购商品的库存信息;
  2. 保存客户付款信息–可能包括与银行系统的交互;
  3. 生成订单并且保存到数据库中;
  4. 更新用户相关信息,例如购物数量等等。

正常的情况下,这些操作将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新。但是,如果在这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常、该顾客银行帐户存款不足等,都将导致交易失败。一旦交易失败,数据库中所有信息都必须保持交易前的状态不变,比如最后一步更新用户信息时失败而导致交易失败,那么必须保证这笔失败的交易不影响数据库的状态–库存信息没有被更新、用户也没有付款,订单也没有生成。否则,数据库的信息将会一片混乱而不可预测。

数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。

事务必须满足四个属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),即ACID四种属性。

原子性

事务是一个不可分割的整体,为保证事物的总体目标,事务必须具有原子性,即当数据修改时,要么全部执行,要么全都不执行,不允许事务部分地完成,避免了只执行这些操作的一部分所带来的错误。

一致性

事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。
由于并发操作带来的数据不一致性通常包括以下几种类型:丢失数据修改、读“脏”数据、不可重复读和产生幽灵数据。

隔离性

也称独立性,由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为隔离性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。
实施隔离线是解决临时更新与消除级联回滚问题的一种方式。

持久性

也称永久性,事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。持久性一般通过数据库备份与恢复来保证。

严格而言,数据库事务属性都是由数据库管理系统来进行保证的,在整个应用程序的运行过程中,应用程序无需去考虑数据库的ACID实现。

事务开始于:

  • 连接在数据库上,并执行一条DML语句(INSERT、UPDATE、DELETE)
  • 前一个事务结束后,又输入了一条DML语句

事务结束于:

  • 执行COMMIT或者ROLLBACK语句
  • 执行一条DDL语句,例如Create Table,在这种情况下会自动执行COMMIT语句
  • 执行一条DCL语句,例如Grant,在这种情况下会自动执行COMMIT语句
  • 断开与数据库的连接
  • 执行了一条DML语句,但该语句失败了;在这种情况下会自动执行ROLLBACK语句

事务的隔离级别:

  • 读取未提交(Read Uncommitted)
  • 读取已提交(Read committed)
  • 可重复读(Repeatable read)
  • 序列化(Serializable)

2. 存储过程

SQL语句执行的时候,要首先编译,然后再被执行。在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行。

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

使用存储过程可以增强SQL语言的功能和灵活性
由于用流程控制语句编写存储过程具有很强的灵活性,所以使用存储过程可以完成复杂的判断和运算,并且可以保证数据库的安全性和完整性,同时存储过程可以使没有权限的用户在控制之下间接地存取数据库,也保证了数据的安全

1. 创建存储过程
create procedure sp_name @[参数][类型]
as
begin
           ……
end
2. 调用存储过程
exec sp_name [参数名][类型]
3. 删除存储过程
drop procedure sp_name

存储过程的优点:

  1. 执行效率高;
  2. 减少网络流量;
  3. 安全机制好。

3. 索引

索引是对数据库表中一列或者多列的值进行排序的一种结果,使用索引可快速访问数据库表中的特定信息。它是一种提高数据库查询速度的机制。一条索引记录包含键值和逻辑指针。

数据库中索引可以分为两种类型:聚集索引和非聚集索引。

聚集索引:
  • 表数据按照索引的顺序来存储,即索引项的顺序和表中记录的物理顺序一致。
  • 在一张表上最多只能创建一个聚集索引。
  • 叶子结点即存储了真实的数据行,不再有另外单独的数据页。
  • 一般使用B树来实现。
非聚集索引:
  • 表数据存储顺序与索引顺序无关,数据存储与索引不在同一个地方。
  • 叶子结点包含索引字段值及指向数据页、数据行的逻辑指针。
  • 为提高索引性能一般使用B树来实现。

聚集索引一般情况下可以获得更快的数据访问速度。

创建索引可以大大提高系统的性能:

  1. 通过创建唯一性索引,可以保证数据库中表中每一行数据的唯一性;
  2. 通过索引可以大大加快数据的检索速度;
  3. 通过索引可以加速表和表之间的连接,从而有效实现数据的完整性;
  4. 在使用分组和排序子句进行数据检索时,可以显著减少查询中的分组和排序的时间;
  5. 通过索引可以在查询过程中使用优化隐藏器,提高系统的性能。

优化隐藏 就是指在执行查询语句、使用多表连接检索或者指定查询语句操作的对象表时,明确地指出应该使用的查询方法、连接算法或者对表的操作方式。当使用优化隐藏时,一定要认真考虑优化隐藏对性能的影响。

然而过多的索引也会带来不利:

  1. 创建索引和维护索引要耗费时间、空间,当数据量大时问题尤为突出,效率会非常突出;
  2. 除了数据表占据数据空间之外,每一个索引还需要占用一定的物理空间,如果要建立聚集索引,那么需要的空间就会更大,从而造成不必要的空间浪费;
  3. 当对表中的数据进行增、删、改时,索引也要动态的维护,从而降低了数据的维护速度。

如果需要提高查询速度,可以在经常被查询的字段上创建索引来提高效率。

建立索引有以下原则:

  1. 定义主键的数据列一定要建立索引;
  2. 定义有外键的数据列一定要建立索引;
  3. 对于经常查询的数据列最好建立索引;
  4. 对于需要在指定范围内快速或频繁查询的数据列最好建立索引;
  5. 经常用where子句中的数据列最好建立索引;
  6. 经常出现在关键字order by、group by、distinct后面的字段,最好建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则,索引不会被使用;

4. 死锁

死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样就互相等待就形成死锁。

产生死锁的原因主要有:

  1. 系统资源不足;
  2. 进程运行推进的顺序不合适;
  3. 资源分配不当。

产生死锁的四个条件:

  1. 互斥使用,一个资源每次只能被一个进程使用;
  2. 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  3. 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  4. 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

只要上述死锁条件之一不能满足,就不会产生死锁。

预防死锁:

  • 通过设置某些条件,去破坏产生死锁的四个必要条件中的一个或多个;
  • 易于实现,但会导致系统资源利用率和系统吞吐量降低。

避免死锁:

允许前三个条件存在,但通过合理的资源分配算法来确保永远不会形成环形等待的封闭进程链,从而避免思索

  1. 一次封锁法
  2. 顺序封锁法
  3. 银行家算法

下列方法有助于最大限度降低死锁

  1. 按同一顺序访问对象;
  2. 避免事务中的用户交互;
  3. 保持事务简短并在一个批处理中;
  4. 使用低隔离等级。

4. 视图

在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。
注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。

视图有如下作用:

  1. 使用视图,可以定制用户数据,聚焦特定的数据;
  2. 使用视图,可以简化数据操作;
  3. 使用视图,基表中的数据就有了一定的安全性;
  4. 可以合并分离的数据,创建分区视图。

参考并感谢
1. Java程序员面试笔试真题与解析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值