SQL Server中锁的用法

目录
  • 通过锁可以防止的问题
    • 1、脏读
    • 2、非重复性读取
    • 3、幻读
    • 4、丢失更新
  • 可以锁定的资源
  • 锁升级和锁对性能的影响
  • 锁定模式
    • 1、共享锁
    • 2、排它锁
    • 3、更新锁
    • 4、意向锁
    • 5、模式锁
    • 6、批量更新锁
  • 锁的兼容性
    • 使用Management Studio确定锁
  • 设置隔离级别
    • 1、READ COMMITTED
    • 2、READ UNCOMMITTED
    • 3、REPEATABLE READ
    • 4、SERIALIZABLE
    • 5、SNAPSHOT
  • 处理死锁
    • 1、判断死锁的方式
    • 2、选择死锁牺牲者的方式
    • 3、避免死锁

锁是一种防止在某对象执行动作的一个进程与已在该对象上执行的其他进行相冲突的机制。也就是说,如果有其他人在操作某个对象,那么你旧不能在该对象上进行操作。你能否执行操作取决于其他用户正在进行的操作。

通过锁可以防止的问题

锁可以解决以下4种主要问题:

1、脏读

如果一个事务读取的记录是另一个未完成事务的一部分,那么这时就发生了脏读。如果第一个事务正常完成,那么就有什么问题。但是,如果前一个事务回滚了呢,那将从数据库从未发生的事务中获取了信息。

2、非重复性读取

很容易将非重复性读取和脏读混淆。如果一个事务中两次读取记录,而另一个事务在这期间改变了数据,就会发生非重复性读取。
例如,一个银行账户的余额是不允许小于0的。如果一个事务读取了某账户的余额为125元,此时另一事务也读取了125元,如果两个事务都扣费100元,那么这时数据库的余额就变成了-75元。

有两种方式可以防止这个问题:

  • 创建CHECK约束并监控547错误
  • 将隔离级别设置为REPEATABLEREAD或SERIALIZABLE

CHECK约束看上去相当直观。要知道的是,这是一种被动的而非主动的方法。然而,在很多情况下可能需要使用非重复性读取,所以这在很多情况下是首选。

3、幻读

幻读发生的概率非常小,只有在非常偶然的情况下才会发生。

比如,你想将一张工资表里所有低于100的人的工资,提高到100元。你可能会执行以下SQL语句:

UPDATE tb_Money SET Salary = 100
WHERE Salary < 100

这样的语句,通常情况下,没有问题。但是如果,你在UPDATE的过程中,有人恰好有INSERT了一条工资低于100的数据,因为这是一个全新的数据航,所以没有被锁定,而且它会被漏过Update。

要解决这个问题,唯一的方法是设定事务隔离级别为SERIALIZABLE,在这种情况下,任何对表的更新都不能放入WHERE子句中,否则他们将被锁在外面。

4、丢失更新

丢失更新发生在一个更新成功写入数据库后,而又意外地被另一个事务重写时。这是怎么发生的呢?如果有两个事务读取整个记录,然后其中一个向记录写入了更新信息,而另一个事务也向该记录写入更新信息,这是就会出现丢失更新。

有个例子写得很好,这里照敲下来吧。假如你是公司的一位信用分析员,你接到客户X打开的电话,说他已达到它的信用额度上限,想申请增加额度,所以你查看了这位客户的信息,你发现他的信用额度是5000,并且看他每次都能按时付款。

当你在查看的时候,信用部门的另一位员工也读取了客户X的记录,并输入信息改变了客户的地址。它读取的记录也显示信用额度为5000。

这时你决定把客户X的信用额度提高到10000,并且按下了Enter键,数据库现在显示客户X的信用额度为10000。

Sally现在也更新了客户X的地址,但是她仍然使用和您一样的编辑屏幕,也就是说,她更新了整个记录。还记得她屏幕上显示的信用额度吗?是5000.数据库现在又一次显示客户X的信用额度为5000。你的更新丢失了。

解决这个问题的方法取决于你读取某数据和要更新数据的这段时间内,代码以何种方式识别出另一连接已经更新了该记录。这个识别的方式取决于你所使用的访问方法。

可以锁定的资源

对于SQL Server来说,有6种可锁定的资源,而且它们形成了一个层次结构。锁的层次越高,它的粒度就越粗。按粒度由粗到细排列,这些资源包括:

  • 数据库:锁定整个数据库。这通常发生在整个数据库模式改变的时候。
  • 表:锁定整个表。这包含了与该表相关联的所有数据相关的对象,包括实际的数据行(每一行)以及与该表相关联的所有索引中的键。
  • 区段:锁定整个区段。因为一个区段由8页组成,所以区段锁定是指锁定控制了区段、控制了该区段内8个数据或索引页以及这8页中的所有数据航。
  • 页:锁定该页中的所有数据或索引键。
  • 键:在索引中的特定键或一系间上有锁。相同索引页中的其他键不受影响。
  • 行或行标识符:虽然从技术上将,锁是放在行标识符上的,但是本质上,它锁定了整个数据行。

锁升级和锁对性能的影响

升级是指能够认识到维持一个较细的粒度(例如,行锁而不是页锁),只在被锁定的项数较少时有意义。而随着越来越多的项目被锁定,维护这些锁的系统开销实际上会影响性能。这会导致所持续更长的时间。

当维持锁的数量达到一定限度时,则锁升级为下一个更高的层次,并且将不需要再如此紧密地管理低层次的锁(释放资源,而且有助于提升速度)。

注意,升级是基于锁的数量,而不是用户的数量。这里的重点是,可以通过执行大量的更新来单独地锁定表-行锁可以升级为页锁,页锁可以升级为表锁。这意味着可能将所有其他用户锁在该表之外。如果查询使用了多个表,则它很可能将每个人锁在这些表之外。

锁定模式

除了需要考虑锁定的资源层次以外,还要考虑查询将要获得的锁定模式,就像需要对不同的资源进行锁定一样,也有不同的锁定模式。一些模式是互相排斥的。一些模式什么都不做,只修改其他的模式。模式是否可以一起使用取决于他们是否是兼容的。

1、共享锁

这是最基本的一种锁。共享锁用于只需要读取数据的时候,也就是说,共享锁锁定时,不会进行改变内容的操作,其他用户允许读取。

共享锁能和其他共享锁兼容。虽然共享锁不介意其他锁的存在,但是有些锁并不能和共享锁共存。

共享锁告诉其他锁,某用户已经在那边了,它们并不提供很多的功能,但是不能忽略它们。然而,共享锁能做的是防止用户执行脏读。

2、排它锁

排它锁顾名思义,排它锁不与其他任何锁兼容。如果有任何其他其他锁存在,则不能使用排他锁,而且当排他锁仍然起作用时,他们不允许在资源之上创建任何形式的新锁。这可以防止两个人同时更新、删除或执行任何操作。

3、更新锁

更新锁是共享锁和排他锁的混合。更新锁是一种特殊的占位符。为了能执行UPDATE,需要验证WHERE子句来指出想要更新的具体的数据行。这意味着只需要一个共享锁,直到真正地进行物理更新。在物理更新期间,需要一个排他锁。

  • 第一个阶段指出了满足WHERE子句条件的内容,这是更新查询的一部分,该查询有一个更新锁。
  • 第二个阶段是如果决定执行更新,那么锁将升级为排他锁。否则,将把锁转换为共享锁。

这样做的好处是它防止了死锁。死锁本身不是一种锁定类型,而是一种已经形成矛盾的状况,两个锁在互相等待,多个锁形成一个环在等待前面的事务清除资源。

如果没有更新锁,死锁会一直出现。两个更新查询会在共享模式下运行。Query A完成了它的查询工作并准备进行物理更新。它想升级为排他锁,但是不可以这么做,因为Query B正在完成查询。除非Query B需要进行物理更新,否则它会完成查询。为了做到这点,Query B必须升级为排他锁,但是不能这么做,因为Query A正在等待。这样就造成了僵局。

而更新锁阻止建立其他的更新锁。第二个事务只要尝试取得一个更新锁,它们就会进入等待状态,直到超时为止-将不会授予这个锁。如果第一个锁在锁超时之前清除的话,则锁定会授予给新的请求者,并且这个处理会继续下去。如果不清楚,则会发生错误。

更新锁只与共享锁以及意向共享锁相兼容。

4、意向锁

意向锁是什么意思呢?就是说,加入你锁定了某一行,那么同时也加了表的意向锁(不允许其他人通过表锁来妨碍你)。

意向锁是真正的占位符,它用来处理对象层次问题的。假设一下如下情况:已对某一行建立了锁,但是有人想在页上或区段上建立所,或者是修改表。你肯定不想让另一个事务通过达到更高的层次来妨碍你。
如果没有意向锁,那么较高层次的对象将不会知道在较低层次上有锁。意向锁可改进性能,因为SQL Server只需要在表层次上检查意向锁(而不需要检查表上的每个行锁或者页锁),以此来决定事务是否可以安全地锁定整个表。

意向锁分为以下3种不同的类型:

  • 意向共享锁:该意向锁指已经或者将要在层次结构的一些较低点处建立共享锁。
  • 意向排他锁:它与意向共享锁一样,但是将会在低层项上设置排他锁。
  • 共享意向排他锁:它指已经或将会在对象层次结构下面建立共享锁,但目的是为了修改数据,所以它会在某个时刻成为意向排它锁。

5、模式锁

模式锁分为以下两种。

  • 模式修改锁:对对象进行模式改变。在Sch-M锁期间,不能对对象进行查询或其他CREATE、ALTER或DROP语句的操作。
  • 模式稳定锁锁定:它和共享锁很相似;这个锁的唯一目的是方式模式修改锁,因为在该对象上已有其他查询(或CREATE、ALTER、DROP语句)的锁。它与其他所有的锁定相兼容。

6、批量更新锁

批量更新锁(BU)只是一种略有不同的表锁定变体形式。批量更新锁允许并行加载数据。也就是说,对于其他任何普通操作(T-SQL)都会将表锁定,但可以同时执行多个BULK INSERT或bcp操作。

锁的兼容性

锁的资源锁定模式的兼容性表格,现有锁以列显示,要兼容的锁以行显示。

锁的类型 意向共享锁(IS) 共享锁(S) 更新锁(U) 意向排他锁(IX) 共享意向排它锁(SIX) 排他锁(X)
意向共享锁(IS)
共享锁(S)
更新锁(U)
意向排他锁(IX)
共享意向排它锁(SIX)
排他锁(X)

另外:

  • Sch-S与出Sch-M以外的所有锁定模式相兼容。
  • Sch-M和所有的锁定模式不兼容。
  • BU只与模式稳定性锁以及其他的批量更新锁相兼容。

有时想要在查询中或在整个事务中对锁定有更多的控制。可以通过使用优化器提示(optimizer hints)来实现这一点。

优化器提示明确告诉SQL Server将一个锁升级为特有的层次。这些提示信息包含在将要影响的表的名称之后。

优化器提示是一个高级主题,有经验的SQL Server开发人员会经常使用它,并且他们相当重视它。

使用Management Studio确定锁

查看锁的最好方式是使用Management Studio。通过使用Activity Monitor,Management Studio会以两种方式显示锁-通过processId或object。

为了使用Management Studio显示锁,只要导航到<Server>的Activity Monitor节点,其中的<Server>是监控其活动的服务器的顶级节点。

展开感兴趣的节点(Overview部分默认展开),可以通过滚动条查看大量度量值-包括当前系统中有效的锁。

显示界面如下:

设置隔离级别

事务和锁之间的联系是很紧密的。默认情况下,一旦创建了任何与数据修改相关的锁,该锁定就会在整个事务期间存在。如果有一个大型事务,就意味着将在很长一段时间内阻止其他进程访问锁定的对象。这明显是有问题的。

事务有5种隔离级别:

  • READ COMMITTED
  • READ UNCOMMITTED
  • REPEATABLE READ
  • SERIALIZABLE
  • SNAPSHOT

在这些隔离级别之间进行切换的语法也相当直观:

SET TRANSACTION ISOLATION LEVEL < READ COMMITTED | READ UNCOMMITTED | REPEATABLE READ | SERIALIZABLE | SNAPSHOT >

对隔离级别的修改只会影响到当前的连接-所以不必担心会影响到其他的用户。其他用户也影响不了你。

1、READ COMMITTED

默认情况就是这个,通过READ COMMITTED,任何创建的共享锁将在创建它们的语句完成后自动释放。也就是说,如果启动了一个事务,运行了一些语句,然后运行SELECT语句,再运行一些其他的语句,那么当SELECT语句完成的时候,与SELECT语句相关联的锁就会释放 - SQL Server并不会等到事务结束。

动作查询(UPDATE、DELETE、INSERT)有点不同。如果事务执行了修改数据的查询,则这些锁将会在事务期间保持有效。

通过设置READ COMMITTED这一默认隔离级别,可以确定有足够的数据完整性来防止脏读。然而,仍会发生非重复性读取和幻读。

2、READ UNCOMMITTED

READ UNCOMMITTED是所有隔离级别中最危险的,但是它在速度方面有最好的性能。
设置隔离级别为READ UNCOMMITTED将告诉SQL Server不要设置任何锁,也不要事先任何锁。
锁既是你的保护者,同时也是你的敌人。锁可以防止数据完整性问题,但是锁也经常妨碍或阻止你访问需要的数据。由于此锁存在脏读的危险,因此此锁只能应用于并非十分精确的环境中。

3、REPEATABLE READ

REPEATABLE READ会稍微地将隔离级别升级,并提供一个额外的并发保护层,这不仅能防止脏读,而且能防止非重复性读取。
防止非重复性读取是很大的优势,但是直到事务结束还保持共享锁会阻止用户访问对象,因此会影响效率。推荐使用其他的数据完整性选项,例如CHECK约束,而不是采用这个选择。
与REPEATABLE READ隔离级别等价的优化器提示是REPEATABLEREAD(除了一个空格,两者并无不同)。

4、SERIALIZABLE

SERIALIZABLE是堡垒级的隔离级别。除了丢失更新以外,它防止所有形式的并发问题。甚至能防止幻读。

如果设置隔离级别为SERIALIZABLE,就意味着对事物使用的表进行的任何UPDATE、DELETE、INSERT操作绝对不满足该事务中任何语句的WHERE子句的条件。从本质上说,如果用户想执行一些事务感兴趣的事情,那么必须等到该事务完成的时候。

SERIALIZABLE隔离级别也可以通过查询中使用SERIALIZABLE或HOLDLOCK优化器提示模拟。再次申明,类似于READ UNCOMMITTED和NOLOCK,前者不需要每次都设置,而后者需要把隔离级别设置回来。

5、SNAPSHOT

SNAPSHOT是最新的一种隔离级别,非常想READ COMMITTED和READ UNCOMMITTED的组合。要注意的是,SNAPSHOT默认是不可用的-只有为数据库打开了ALLOW_SNAPSHOT_ISOLATION特殊选项时,SNAPSHOT才可用。
和READ UNCOMMITED一样,SNAPSHOT并不创建任何锁,也不实现人和所。两者的主要区别是它们识别数据库中不同时段发生的更改。数据库中的更改,不管何时或是否提交,都会被运行READ UNCOMMITTED隔离级别的查询看到。而使用SNAPSHOT,只能看到在SNAPSHOT事务开始之前提交的更改。从SNAPSHOT事务一开始执行,所有查看到的数据就和在时间开始时提交的一样。

处理死锁

死锁的错误号是1205。

如果一个锁由于另一个锁占有资源而不能完成应该做的清除资源工作,就会导致死锁;反之亦然。当发生死锁时,需要其中的一方赢得这场斗争,所以SQL Server选择一个死锁牺牲者,对死锁牺牲者的事务进行回滚,并且通过1205错误来通知发生了死锁。另外一个事务将继续正常地运行。

1、判断死锁的方式

每隔5秒钟,SQL Server就会检查所有当前的事务,了解他们在等待什么还未被授予的锁。然后再一次重新检查所有打开的锁请求的状态,如果先前请求中有一个还没有被授予,则它会递归地检查所有打开的事务,寻找锁定请求的循环链。如果SQL Server找到这样的村换连,则将会选择一个或更多的死锁牺牲者。

2、选择死锁牺牲者的方式

默认情况下,基于相关事务的"代价",选择死锁牺牲者。SQL Server将会选择回滚代价最低的事务。在一定程度上,可以使用SQL Server中的DEADLOCK_PRIORITY SET选项来重写它。

3、避免死锁

避免死锁的常用规则

  • 按相同的顺序使用对象
  • 使事务尽可能简短并且在一个批处理中。
  • 尽可能使用最低的事务隔离级别。
  • 在同一事务中不允许无限度的中断。
  • 在控制环境中,使用绑定连接。

1、按相同的顺序使用对象

例如有两个表:Suppliers和Products。假设有两个进程将使用这两个表。进程1接受库存输入,用手头新的产品总量更新Products表,接下来用已经购买的产品总量来更新Suppliers表。进程2记录销售数据,它在Supperlier表中更新销售产品的总量,然后在Product中减少库存数量。

如果同时运行这两个进程,那么就有可能碰到麻烦。进程1试图获取Product表上的一个排他锁。进程2将在Suppliers表上获取一个排他锁。然后进程1将试图获取Suppliers表上的一个锁,但是进程1必须等到进程2清除了现有的锁。同时进程2也在等待进程1清除现有锁。

上面的例子是,两个进程用相反的顺序,锁住两个表,这样就很容易发生死锁。

如果我们将进程2改成首先在Products减少库存数量,接着在Suppliers表中更新销售产品的总数量。两个进程以相同的顺序访问两张表,这样就能够减少死锁的发生。

2、使事务尽可能简短

保持事务的简短将不会让你付出任何的代价。在事务中放入想要的内容,把不需要的内容拿出来,就这么简单。它的原理并不复杂-事务打开的时间越长,它触及的内容就越多,那么其他一些进程想要得到正在使用的一个或者多个对象的可能性就越大。如果要保持事务简短,那么就将最小化可能引起死锁的对象的数量,还将减少锁定对象的时间。原理就如此简单。

3、尽可能使用最低的事务隔离级别

使用较低的隔离级别和较高的隔离级别相比,共享锁持续的时间更短,因此会减少锁的竞争。

4、不要采用允许无限中断的事务

当开始执行某种开放式进程时间,不要创建将一直占有资源的锁。通常,指的是用户交互,但它也可能是允许无限等待的任何进程。

到此这篇关于SQL Server锁的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Sql Server如何查看被锁的表及解锁的方法

    查看被锁表: select spId from master..SysProcesses where db_Name(dbID) = '数据库名称' and spId <> @@SpId and dbID <> 0 解除锁: exec ('Kill '+cast(@spid as varchar)) 查看被锁表: select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName f

  • sqlserver锁表、解锁、查看销表的方法

    锁定数据库的一个表 复制代码 代码如下: SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 复制代码 代码如下: SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 复制代码 代码如下: SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SELECT 语句中"加锁选项"的功能说明 SQL Server提供了强大而完备的锁机

  • sqlserver 锁表语句分享

    锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SELECT 语句中"加锁选项"的功能说明 SQL Server提供了强大而完备的锁机制来帮助实现数据库系统的并发性和高性能.用户既能使用SQL Ser

  • SQLServer 中的死锁说明

    两个进程发生死锁的典型例子是:进程T1中获取锁A,申请锁B:进程T2中获取锁B,申请锁A,我们下面动手来演示一下这种情况: 1. 创建一个Database,名为InvDB. 2. 执行下面脚本创建person表并填充两条数据: 3. 在SQL Server Management Studio的两个窗口中同时执行下面的查询: 这段代码在默认的READ COMMITTED隔离级别下运行,两个进程分别在获取一个排它锁的情况下,申请对方的共享锁从而造成死锁. 可见一个进程可以正常更新并显示结果,而另一个

  • SQL Server三种锁定模式的知识讲解

    sql server 锁定模式有三种:共享( S锁),更新(U锁),排他(X锁): S锁是共享锁,如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁.获准共享锁的事务只能读数据,不能修改数据. 个人理解为,对数据A的操作就只能是SELECT ,(联想下,S锁,不就是Select的首字母么),其他事务对A数据的UPDATE ,DELETE都不能进行: U锁是更新锁.用于可更新的资源中.防止当多个会话在读取.锁定以及随后可能进行的资源更新时发生常见形式的死锁. 原理解释: 更

  • sqlserver:查询锁住sql以及解锁方法

    查看被锁表语句 --查看被锁表: SELECT request_session_id spid, OBJECT_NAME( resource_associated_entity_id ) tableName FROM sys.dm_tran_locks WHERE resource_type = 'OBJECT' ORDER BY request_session_id ASC --spid 锁表进程 --tableName 被锁表名 --根据锁表进程查询相应进程互锁的SQL语句 DBCC INP

  • sql server中死锁排查的全过程分享

    前言 记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了. 死锁的四个必要条件: 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用. 请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源. 非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺. 循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻

  • sqlserver2008锁表语句详解(锁定数据库一个表)

    锁定数据库的一个表 复制代码 代码如下: SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 复制代码 代码如下: SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 复制代码 代码如下: SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SELECT 语句中"加锁选项"的功能说明 SQL Server提供了强大而完备的锁机

  • SqlServer表死锁的解决方法分享

    其实不光是上面描述的情况会锁住表,还有很多种场景会使表放生死锁,解锁其实很简单,下面用一个示例来讲解: 1 首先创建一个测试用的表: 复制代码 代码如下: CREATE TABLE Test ( TID INT IDENTITY(1,1) ) 2 执行下面的SQL语句将此表锁住: 复制代码 代码如下: SELECT * FROM Test WITH (TABLOCKX) 3 通过下面的语句可以查看当前库中有哪些表是发生死锁的: 复制代码 代码如下: SELECT request_session_

  • SQL Server中锁的用法

    目录 通过锁可以防止的问题 1.脏读 2.非重复性读取 3.幻读 4.丢失更新 可以锁定的资源 锁升级和锁对性能的影响 锁定模式 1.共享锁 2.排它锁 3.更新锁 4.意向锁 5.模式锁 6.批量更新锁 锁的兼容性 使用Management Studio确定锁 设置隔离级别 1.READ COMMITTED 2.READ UNCOMMITTED 3.REPEATABLE READ 4.SERIALIZABLE 5.SNAPSHOT 处理死锁 1.判断死锁的方式 2.选择死锁牺牲者的方式 3.避

  • SQL Server 中 RAISERROR 的用法详细介绍

    SQL Server 中 RAISERROR 的用法 raiserror 的作用: raiserror 是用于抛出一个错误.[ 以下资料来源于sql server 2005的帮助 ] 其语法如下: RAISERROR ( { msg_id | msg_str | @local_variable } { ,severity ,state } [ ,argument [ ,...n ] ] ) [ WITH option [ ,...n ] ] 简要说明一下: 第一个参数:{ msg_id | ms

  • SQL Server中Sequence对象用法

    一.Sequence简介 Sequence对象对于Oracle用户来说是最熟悉不过的数据库对象了, 在SQL SERVER2012终于也可以看到这个对象了.Sequence是SQL Server2012推出的一个新特性.这个特性允许数据库级别的序列号在多表或多列之间共享. 二.Sequence基本概念 Oracle中有Sequence的功能,SQL server类似的功能要使用identity列实现,但是identity列有很大的局限性.微软终于在2012中添加了Sequence对象.与以往id

  • SQL Server中row_number函数用法入门介绍

    目录 一.SQL Server Row_number函数简介 二.Row_number函数的具体用法 1.使用row_number()函数对结果集进行编号 2.对结果集按照指定列进行分组,并在组内按照指定列排序 3.对结果集按照指定列去重 总结 一.SQL Server Row_number函数简介 ROW_NUMBER()是一个Window函数,它为结果集的分区中的每一行分配一个连续的整数. 行号以每个分区中第一行的行号开头. 语法实例: select *,row_number() over(

  • SQL Server中分区表的用法

    目录 一.分区表简介 二.对表分区的理由 三.分区表的操作步骤 第一步.定义分区函数: 第二步.定义分区构架 第三步.定义分区表 四.分区表的分割 五.分区表的合并 一.分区表简介 分区表是SQL Server2005新引入的概念,这个特性在逻辑上将一个表在物理上分为多个部分.(即它允许将一个表存储在不同的物理磁盘里).在SQL Server2005之前,分区表实际上是分布式视图,也就是多个表做union操作. 分区表在逻辑上是一个表,而物理上是多个表.在用户的角度,分区表和普通表是一样的,用户

  • SQL Server中索引的用法详解

    目录 一.索引的介绍 什么是索引? 1.聚集索引和非聚集索引 2.索引的利弊 3.索引的存储机制 二.设置索引的权衡 1.什么情况下设置索引 2.什么情况下不要设置索引 三.聚集索引 1.使用SSMS创建聚集索引 2.使用T-SQL创建聚集索引 四.非聚集索引 1.SSMS创建方法同上,T-SQL创建方法如下: 2.添加索引选项 五.示例 六.管理索引 一.索引的介绍 什么是索引? 索引是一种磁盘上的数据结构,建立在表或视图的基础上.使用索引可以使数据的获取更快更高校,也会影响其他的一些性能,如

  • SQL Server中row_number分页查询的用法详解

    ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号.在查询时应用了一个排序标准后,只有通过编号才能够保证其顺序是一致的,当使用ROW_NUMBER函数时,也需要专门一列用于预先排序以便于进行编号. ROW_NUMBER() 说明:返回结果集分区内行的序列号,每个分区的第一行从1开始. 语法:ROW_NUMBER () OVER ([ <partition_by_clause> ] <order_by_clause>) . 备注:ORDER

  • Sql Server中Substring函数的用法实例解析

    SQL 中的 substring 函数是用来抓出一个栏位资料中的其中一部分.这个函数的名称在不同的资料库中不完全一样: MySQL: SUBSTR( ), SUBSTRING( ) Oracle: SUBSTR( ) SQL Server: SUBSTRING( ) SQL 中的 substring 函数是用来截取一个栏位资料中的其中一部分. 例如,我们需要将字符串'abdcsef'中的'abd'给提取出来,则可用substring 来实现: select substring('abdcsef'

  • 详解SQL Server中的事务与锁问题

    一  概述 在数据库方面,对于非DBA的程序员来说,事务与锁是一大难点,针对该难点,本篇文章试图采用图文的方式来与大家一起探讨. "浅谈SQL Server 事务与锁"这个专题共分两篇,上篇主讲事务及事务一致性问题,并简略的提及一下锁的种类和锁的控制级别. 下篇主讲SQL Server中的锁机制,锁控制级别和死锁的若干问题. 二   事务 1   何为事务 预览众多书籍,对于事务的定义,不同文献不同作者对其虽有细微差别却大致统一,我们将其抽象概括为: 事务:指封装且执行单个或多个操作的

  • SQL Server中row_number函数的常见用法示例详解

    一.SQL Server Row_number函数简介 ROW_NUMBER()是一个Window函数,它为结果集的分区中的每一行分配一个连续的整数. 行号以每个分区中第一行的行号开头. 以下是ROW_NUMBER()函数的语法实例: select *,row_number() over(partition by column1 order by column2) as n from tablename 在上面语法中: PARTITION BY子句将结果集划分为分区. ROW_NUMBER()函

随机推荐