• MS SQL高级——事务与索引


    事务与索引

    什么是事务?

    事务的概念及要求

    • 事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。
    • 多个操作作为一个整体向系统提交,要么都执行、要么都不执行。
    • 事务是一个不可分割的工逻辑单元。

    银行转账过程就是一个事务

    • 它需要两条UPDATE语句来完成,这两条语句是一个整体。
    • 如果其中任一条出现错误,则整个转账业务也应取消,两个账户中的余额应恢复到原来的数据,从而确保转账前和转账后的余额不变。

    事务的特性

    事务必须具备以下四个属性:

    • 原子性(Atomicity):事务是一个完整的操作,事务的各步操作是不可分的,要么都执行,要么都不执行。
    • 一致性(Consistency):当事务完成时,数据必须处于一致状态。
    • 隔离性(Isolation):并发事务之间彼此隔离、独立,它不应以任何方式依赖于或影响其他事务。
    • 永久性(Durability):事务完成后,它对数据库的修改被永久保存。

    事务分类

    显式事务

    • 用BEGIN TRANSACTION明确指定事务的开始。
    • 最常用的事务类型。

    隐性事务

    • 通过设置SETIMPLICIT_TRANSACTIONS ON语句,将隐性事务模式设置为打开。
    • 其后的T-SQL语句自动启动一个新事务。
    • 提交或回滚一个事务后,下一个T-SQL语句又将启动一个新事务。

    自动提交事务

    • SQLServer的默认模式。
    • 每条单独的T-SQL语句视为一个事务。

    如何创建事务

    使用SQL语句管理事务的基本步骤

    开始事务
    • BEGIN TRANSACTION
    提交事务
    • COMMIT TRANSACTION
    回滚(撤销)事务
    • ROLLBACK TRANSACTION

    事务处理中的关键问题

    • 对事务中的insert、update、delete语句实时跟踪。

    判断某条语句执行是否出错的方法

    • 使用全局变量@@ERROR
    • @@ERROR只判断当前一条T-SQL语句执行是否有错。
    • 为了判断事务中所有T-SQL语句是否有错,可以对错误进行累计。
    SET@errorSum=@errorSum+@@ERROR

    事务的应用

    应用实践:编写存储讨程,实现学员一卡通转账功能,要求用户输入转入和转出的金额和账户

     测试转账存储过程

    索引

    索引类型

    聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个

    • 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。
    • 主键索引要求主键中的每个值是唯一的,并且不能为空

    非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。

    • 数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。
    • 可以有多个,小于249个
    • 唯一索引:唯一索引不允许两行具有相同的索引值

    如何创建索引

     使用SQL Server Management Studio创建索引

    使用SQL语句创建索引

     

     在Students表的StudentName列创建非聚集索引

    按指定的索引查询数据

    索引的优缺点

    优点

    • 加快访问速度。
    • 加强行的唯一性。

    缺点

    • 带索引的表在数据库中需要更多的存储空间。
    • 操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新。

    创建索引的指导原则

    按照下列标准选择建立索引的列

    • 频繁搜索的列。经常用作查询选择的列。
    • 经常排序、分组的列。
    • 经常用作联接的列(主键/外键)。

    请不要使用下面的列创建索引

    • 仅包含几个不同值的列。
    • 表中仅包含几行。

    使用索引时注意事项

    • 查询时减少使用*返回全部列,不要返回不需要的列
    • 索引应该尽量小,在字节数小的列上建立索引
    • WHERE子句中有多个条件表达式时,包含索引列的表达式应置于其他条件表达式之前
    • 根据业务数据发生频率,定期重新生成或重新组织索引,进行碎片整理

    查看索引

    ADO.NET的事务处理

    ADO.NET提供了事务处理功能:

    ADO.NET通过 SqlTransaction对象执行事务处理

    使用ADO.NET事务

    编写启用事务的通用数据访问方法

     

     测试ADO.NET事务(事务回滚)

     测试ADO.NET事务(事务提交)

     

    示例

    示例1:转账中遇到的问题

     1 use StudentManager
     2 go
     3 --从贺小张的账户减掉1000
     4 update CardAccount set CurrentMoney=CurrentMoney-1000
     5            where StudentId=100001
     6 --给马小李的账户加上1000
     7 update CardAccount set CurrentMoney=CurrentMoney+1000
     8            where StudentId=100002
     9 --查询余额
    10 select Students.StudentId,StudentName,CurrentMoney from Students
    11 inner join CardAccount on Students.StudentId=CardAccount.StudentId
    View Code

    示例2:使用事务回滚有错误的数据

     1 use StudentManager
     2 go
     3 declare @errorSum int --定义变量,用于累计事务执行过程中的错误
     4 set @errorSum=0        --初始化为0,即无错误
     5 begin transaction
     6    begin                
     7     update CardAccount set CurrentMoney=CurrentMoney-1000
     8         where StudentId=100001
     9        set @errorSum=@errorSum+@@error --累计是否有错误                
    10     update CardAccount set CurrentMoney=CurrentMoney+1000
    11         where StudentId=100002
    12       set @errorSum=@errorSum+@@error --累计是否有错误
    13       if(@errorSum>0)
    14     rollback transaction
    15       else 
    16           commit transaction
    17  end
    18 go
    19 --查询余额
    20 select Students.StudentId,StudentName,CurrentMoney from Students
    21 inner join CardAccount on Students.StudentId=CardAccount.StudentId
    View Code

    示例3:启用事务的转账存储过程

     1 use StudentManager
     2 go
     3 if exists(select * from sysobjects where name='usp_TransferAccounts')
     4 drop procedure usp_TransferAccounts
     5 go
     6 create procedure usp_TransferAccounts
     7 @inputAccount int,--转入账户
     8 @outputAccount int,--转出账户
     9 @transferMoney int --交易金额
    10 as
    11     declare @errorSum int 
    12     set @errorSum=0      
    13     begin transaction
    14        begin                
    15         update CardAccount set CurrentMoney=CurrentMoney-@transferMoney
    16             where StudentId=@outputAccount
    17         set @errorSum=@errorSum+@@error         
    18         update CardAccount set CurrentMoney=CurrentMoney+@transferMoney
    19             where StudentId=@inputAccount
    20            set @errorSum=@errorSum+@@error 
    21            if(@errorSum>0)
    22             rollback transaction
    23            else 
    24             commit transaction
    25      end        
    26 go
    27 --测试失败的转账
    28 exec usp_TransferAccounts 100002,100001,1000
    29 --查询余额
    30 select Students.StudentId,StudentName,CurrentMoney from Students
    31 inner join CardAccount on Students.StudentId=CardAccount.StudentId
    32 --测试成功的转账
    33 exec usp_TransferAccounts 100002,100001,800
    34 --查询余额
    35 select Students.StudentId,StudentName,CurrentMoney from Students
    36 inner join CardAccount on Students.StudentId=CardAccount.StudentId
    View Code

    示例4:使用T-SQL创建索引

     1 use StudentManager
     2 go
     3 /*--检测是否存在该索引(索引存放在系统表sysindexes中)--*/
     4 IF EXISTS (SELECT name FROM sysindexes
     5           WHERE name = 'IX_Student_StudentName')
     6 DROP INDEX Student.IX_Student_StudentName  --删除索引
     7 GO
     8 
     9 /*--学生姓名列创建非聚集索引:填充因子为30%--*/
    10 CREATE NONCLUSTERED INDEX IX_Student_StudentName
    11    ON Students(StudentName)
    12        WITH FILLFACTOR = 30
    13 GO
    View Code

    示例5:使用索引查询数据

    1 use StudentManager
    2 go
    3 /*----指定按索引:IX_Student_StudentName查询----*/
    4 SELECT * FROM Students
    5 WITH (INDEX=IX_Student_StudentName)
    6 WHERE StudentName LIKE '刘%'
    View Code

    END

  • 相关阅读:
    Visual Studio 2017 激活密钥
    jwt的ASP.NET MVC 身份验证
    Building a ASP.NET solution from commandline?从命令行构建 ASP.NET 解决方案?
    10 款更先进的开源命令行工具
    Cookie的Secure属性
    阻碍一个人成长的原因是什么?
    逃   离
    如何判断Javascript函数是否是Async函数
    【四百来块】小米RMMNT215NF显示器评测
    npm 中,n 是什么鬼?
  • 原文地址:https://www.cnblogs.com/zeon/p/16324625.html
Copyright © 2020-2023  润新知