若天明 发表于 2015-1-16 22:17:53

MSSQL网页编程之分析SQL Server 2005查询关照之基本篇

这里我们讨论用binlog来实现闪回的方案。在本系列文章中,我们将深切切磋怎样把.NET2.0和SQLServer2005的查询关照特性团结起来,以便关照使用程序什么时候关头数据产生变更进而到达打消重复查询数据库的目标。
1、弁言
数据库使用程序的典范成绩之一是更新陈腐的数据。
假想有一个典范的显现产物及其分类的电子商务网站。一个供给商的产物列表极可能其实不常常产生变更,而其分类列表乃至更不会频仍变动。但是,在用户每次扫瞄该网站时,必需从数据库中重复查询这些列表。这明显是一种典范的低效资本使用,开辟者和架构师都在挖空心思想举措以削减这类华侈。
缓冲手艺恰是“最小化”对这类几近“停止”的数据举行反复查询的手艺之一。这类数据能够被举行一次性查询并存储在一个缓冲区中,并且使用程序能够从缓存中反复地存取数据。偶然情形下,才更新缓存以失掉新数据。可是,环绕更新缓存的工夫调剂方面呈现了几个成绩。该多长工夫操纵一次呢?比方,你每隔多长工夫但愿你的产物分类改动一次?每隔几个月一次?每隔两个月革新一次该缓冲区怎样?你晓得会产生甚么吗?就在你革新缓存以后,分类被更新,并且鄙人一次革新前在两个月的工夫里它将坚持陈腐。
查询关照,是微软的ADO.NET和SQLServer小组合作开辟的新功效。简言之,查询关照同意你缓冲数据而且仅在SQLServer中的数据产生变更时才收回关照。一旦接到关照,你就能够革新你的缓冲区大概接纳你必要的任何措施。
在SQLServer2005中引进的一种新特性“ServiceBroker”使得查询关照成为大概。ServiceBroker把行列机制引进到数据库办理中,它利用一组行列与服务举行通信,而服务反过去也晓得怎样往回通信以挪用响应的实体。实在,这些行列和服务都是一些与表、视图和存储历程一样的类工具。只管完整能够在SQLServer内利用ServiceBroker,可是ADO.NET晓得怎样与ServiceBroker举行通信以触发这类机制而且从ServiceBroker中检索回关照。
注重当SQLServer中的数据产生改动时,查询关照同意你缓冲数据而且关照你。
在.NET一端,存在良多种“钩进”这类功效的体例。ADO.NET2.0供应了System.Data.SqlClient.SqlDependency和System.Data.Sql.SqlNotificationRequest类。SqlDependency是SqlNotificationRequest的一种初级完成,而且是当利用ADO.NET2.0时你最有大概利用的类。ASP.NET2.0也经由过程System.Web.Caching.SqlCache-Dependency类(它供应了一个针对SqlDependency的包装器)与ServiceBroker举行通信,并且这是间接经由过程在一个ASP.NET页面中利用<%OutputCache>指令以声明体例供应的功效完成的。这同意ASP.NET开辟者简单地完成使依附于SQLServer中的数据中的缓存有效。
2、.NET与ServiceBroker的通信
下面这些手艺是怎样团结到一同来办理“缓冲之谜”的呢?只管你能够接纳良多的措施以同意SQLServer把服务供应给.NET;可是,关头还在于,发送到SQLServer的查询具有一个依靠到它们的标记以便告知SQLServer,除前往了局集外,SQLServer还应当把该查询(及其哀求者)注册到ServiceBroker。为此,你要创立一个感知该查询的行列和一个依靠到该行列的服务,而且晓得怎样前往到客户端。假如该了局会合的任何一行在数据库中失掉更新,那末在相干行列中的项将触发,而且反过去,把一条动静发送到它的服务,然后把一个关照发送回初始化该哀求的使用程序。
是SQLServerManagementStudio的一个快照,它显现了在数据库的ServiceBroker部分中的行列(Queues)和服务(Services)。

.该图显现了.NET的查询关照所利用的Pubs数据库中的缺省行列和服务。
上面是了解这一历程的一些有关主要内容:
·存在一些划定规矩以指出SQLServer吸收哪些范例的查询。
·一旦SQLServer发送回关照,行列和服务即被删除。这意味着,你仅能在每次哀求中失掉一个关照。一个典范的使用程序会从头查询数据库而且,在同时,哀求在ServiceBroker中创立一种新的依附性。
·前往到使用程序的信息也不外是“somethingchanged”。该使用程序其实不被关照改动了甚么(请参考本文中的SQLNotificationEventArgs
节懂得更多的信息)。
·只管依附性被绑定到从查询中前往的行上;可是,它其实不被查询中的单个列加以过滤。假如你有一个查询—它前往你的构造的基础成员姓名和那些单个改动之一的地点(可是,其姓名其实不改动),这将触发一个改动关照。很但愿,这类特别举动在将来的版本中会有所改动。
·关照被前往,经由过程一个专门针对这一目标创建的SqlConnection。这个毗连其实不到场毗连池中。
3、什么时候利用查询关照
查询关照是针关于其实不常常改动的数据而计划的。最好把它使用于服务器真个使用程序(比方ASP.NET或remoting)而不是客户端使用程序(比方Windows表单使用程序)。记着,每个关照哀求都要在SQLServer中注册。假如你具有大批的都有关照哀求的客户端使用程序,那末这大概会招致你的服务器发生资本成绩。微软保举,关于客户端使用程序,你应当限定查询关照利用为未几于十个并行用户。
关于年夜范围使用程序来讲,查询关照多是一种强无力的匡助,而不必复杂地增加愈来愈多的服务器以满意请求。假想,有一家年夜型的为成千上百万用户供应在线软件更新服务的软件公司。不是使每个用户的更新操纵都触发服务器上的另外一个查询来断定必要哪些组件,而是可以缓冲查询了局而且能够间接从该缓存中服务婚配的查询。
注重:关于客户端使用程序来讲,应当限定你的查询关照利用—未几于十个并发用户。
关于较小范围的情形而言,下拉式列表框是另外一种典范的数据集;此时该数据集更新的次数其实不如哀求的次数多。产物列表、州列表、国度列表、供给商、发卖人,乃至更多不太必要频仍改动的信息恰是利用关照的较好候选。
4、为利用查询关照作筹办
由于默许情形下SQLServer2005处于高度平安的形态,以是你必要“翻开”一些功效才干利用查询关照。起首,你要利用的每个数据库都必要启动ServiceBroker功效。为此,你能够在T-SQL中利用以下命令完成:
USEmydatabase
ALTERDATABASEmydbSETENABLE_BROKER
别的,你必要授与一些SQLServer权限以同意非办理员帐户可以介入利用查询关照。
5、SqlDependency.Start和Stop
SqlDependency和SqlCacheDependency都请求,在任何关照哀求前先挪用静态办法SqlDependency.Start()。这个办法卖力创立一个SqlConnection以完成在数据改动时吸收关照。注重,你仅必要在一个使用程序的性命周期的入手下手创建这些内容。比方,在一个ASP.NET使用程序中,global.asax文件的Application_Start事务处置器就是完成这一功效的好中央。
注重,对包括在关照中的每个毗连都应当挪用Start办法。因而,假如你在使用程序中存取多个数据库,那末你必要为每个数据库挪用Start。鄙人列示例中,有一个针对Pubs数据库的毗连串pubsConn,它在这个使用程序的web.config文件中界说。
为了割断这个毗连,你可使用SqlDependency.Stop(),这也是一个静态办法。
以下为援用的内容:
SubApplication_Start(ByValsenderasObject,_
ByValeasEventArgs)
System.Data.SqlClient.SqlDependency.Start_
(System.Configuration.ConfigurationManager._
Connectionstrings("pubsConn").ConnectionString)
EndSub
SubApplication_End(ByValsenderasObject,
ByValeasEventArgs)
System.Data.SqlClient.SqlDependency.Stop_
(System.Configuration.ConfigurationManager._
Connectionstrings("pubsConn").ConnectionString)
EndSub
假如你在挪用Start和Stop的同时察看SQLServerProfiler,那末你会看到很多风趣的信息。当挪用Start时,使用程序运转一个查询以确保撑持ServiceBroker,然后创立一个存储历程备今后用于扫除在ServiceBroker基本布局中的SqlDependency行列和服务。最初,它运转一个SQLServer2005WaitFor命令,该命令卖力查询在NotificationService部分的出口。这就是假如你利用ADO.NET的初级SqlNotificationRequest工具的话一切你必要显式完成的事变。
在全部的.NET2.0的计划过程当中,SqlDependency底层架构从一种推形式(来自SQLServer)改动为一种拉形式(来自.NET)。如许做的缘故原由是为懂得决第一次计划时所招致的一些平安成绩。微软的SushilChordia在MSDN上宣布了一篇有关于这类改善的文章,该文具体形貌了这一改善的内涵机理。
6、你的第一个关照
上面,让我们入手下手利用SqlDependency来剖析一下一切下面这些是怎样协同事情的。
起首,我们创立一个类NotificationTest来存取你的数据。在这个类中,还要创立一个典范的函数以便从Pubs数据库的Authors表中查询一些数据并前往一个SqlDataReader。
以下为援用的内容:
ImportsSystem.Data.SqlClient
PublicClassNotificationTest
PublicFunctionDepTest()AsSqlDataReader
DimconnAsNewSqlConnection(connstring)
conn.Open()
DimcmdAsNewSqlCommand(
"SELECT*FROMauthors(",conn)")
DimrdrAsSqlDataReader
rdr=cmd.ExecuteReader()
Returnrdr
EndFunction
EndClass
如今,让我们修正代码来到场这类依附性。起首,声明一个名为SqlDependency的工具。为了使之用于该类中的别的函数中,我把它界说为一个类变量。
然后,你必要改动这个查询。查询关照请求你显式地枚举在你的查询中的列,和老是利用一种“两部分”的表名。注重一下在修正后的代码示例中的新的查询文本。
然后,实例化新的SqlDependency而且把它依靠到命令中。
就是这些。当实行命令时,依附性跟着它直到数据库。在它处置查询的同时,SQLServer可以看到这一依附性而且把它发送到ServiceBroker以注册它。
以下为援用的内容:
ImportsSystem.Data.SqlClient
PublicClassNotificationTest
DimdepAsSqlDependency
PublicFunctionDepTest()AsSqlDataReader
DimconnAsNewSqlConnection(connstring)
conn.Open()
DimcmdAsNewSqlCommand(_
"SELECTau_id,au_lname,au_fname"&_
"FROMdbo.authors",conn)
dep=NewSqlDependency(cmd)
DimrdrAsSqlDataReader
rdr=cmd.ExecuteReader()
Returnrdr
EndFunction
EndClass
如今,你已注册了依附性,可是当关照前往到使用程序时你还基本没有捕捉它。不外,SqlDependency类供应了两种体例来懂得一个关照。一种体例是经由过程OnChange事务,你能够经由过程创立一个代办署理来捕捉它;另外一种体例是经由过程属性HasChanges,你能够在你的使用程序逻辑中对之举行测试。鄙人列代码中,我在OnDepChange事务中增加了代码以便在前面的某个时分测试关照。
以下为援用的内容:
ImportsSystem.Data.SqlClient
PublicClassNotificationTest
DimdepAsSqlDependency
PublicFunctionDepTest()AsSqlDataReader
DimconnAsNewSqlConnection(connstring)
conn.Open()
DimcmdAsNewSqlCommand(_
"SELECTau_id,au_lname,au_fnameFROM"+_
"dbo.authors",conn)
dep=NewSqlDependency(cmd)
AddHandlerdep.OnChange,AddressOfOnDepChange
DimrdrAsSqlDataReader
rdr=cmd.ExecuteReader()
Returnrdr
EndFunction
处置器办法
PublicSubOnDepChange(ByValsenderAsObject,_
ByValeAsSqlNotificationEventArgs)
DimDepInfoAsString=e.Info.ToString
做一些事变以呼应关照
EndSub
PublicReadOnlyPropertyHasChanges()AsBoolean
Get
Returndep.HasChanges
EndGet
EndProperty
EndClass

如今,我们来看一下其事情道理。起首,把一个断点放到OnDepChange事务的EndSub代码行。然后,从你喜好的网页、表单程序或把持台程序中挪用DepTest函数来举行测试。在前往SqlDataReader后,在VisualStudio2005的ServerExplorer或在SQLServerManagementStudio中翻开Authors表而且编纂某一个字段内容。比方,一旦锁定这一改动,那末,当你把光标挪动到表中的一个新行时,断点应当被激活。
7、SQLNotificationEventArgs
当你看到关照切实其实从数据库中传来时,你能够剖析一下响应变量的值,它是一个SqlNotificationEventArgs工具。SqlDependency老是跟着OnChange事务前往这个工具,并且它是很有效的。个中,SqlNotificationInfo是一个具有18种大概值的列举范例。个中,一些值对应情形一般,而另外一些显现出了成绩。这些列举中有Update,Insert和Delete—告知你在数据中产生了甚么范例的变更。另有别的一些值即便在事务产生时也不会被发送。比方,从头启动服务器将引发一切的关照;而列举值Drop或Truncate告知你已对依附的表完成了某种操纵。
别的,还存在一些依附性乃至还不克不及被注册的情况,比方假如你试图对一个UPDATE查询设置一个依附性将前往Invalid。而前往值Query显现你的查询语法其实不切合关照的严厉划定规矩。下面列举表中的最初两个列举值,另有别的几个与不克不及注册查询相干的列举值在实行该命令时被当即前往。
经由过程查找MSDN库中的有关SqlNotificationInfo列举文档,你能够失掉这些列举的完整列表。
当我一些场所上议论查询关照时,人们老是问我:“关照是不是会告知你产生了甚么事变?”。回覆是“不会”。
总之,SQLNotificationEventArgs可以向你给出一个关照中最为具体的信息,而这些信息在调试排错时长短常有效的。

从理论上讲,完全可以为数据表里的每个字段分别建一个索引,但MySQL把同一个数据表里的索引总数限制为16个。

分手快乐 发表于 2015-1-19 06:55:25

SP4是一个累积性的ServicePack,包含自以前的ServicePack发布以来所有的修补程序(包括MS03-031安全公告)。

灵魂腐蚀 发表于 2015-1-24 15:40:23

如果处理少量数据,比如几百条记录的数据,我不知道这两种情况哪个效率更高,如果处理大量数据呢?比如有表中有20万条记录.

若天明 发表于 2015-2-1 23:50:26

发几份SQL课件,以飨阅者

蒙在股里 发表于 2015-2-7 16:35:20

如安全管理、备份恢复、性能监控和调优等,SQL只要熟悉基本操作就可以,只要程序设计部分只要稍加了解即可(如存储过程、触发器等)。

谁可相欹 发表于 2015-2-22 16:25:16

多加的系统视图和实时系统信息这些东西对DBA挑优非常有帮助,但是感觉粒度还是不太细。

简单生活 发表于 2015-3-7 01:37:47

比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。

变相怪杰 发表于 2015-3-14 06:28:59

发几份SQL课件,以飨阅者

不帅 发表于 2015-3-21 01:21:51

另一个是把SQL语句写到服务器端,就是所谓的SP(存储过程);
页: [1]
查看完整版本: MSSQL网页编程之分析SQL Server 2005查询关照之基本篇