<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
在大型的数据库应用中,经常会遇到部分数据的脱机和多个数据库的合并问题。比如现在有一个全省范围使用的应用程序,每个市都部署了单独的相同的应用
程序服务器和数据库服务器,每个月需要将全省所有市的数据全部汇总起来用于出全省的报表,这是一种很常见的数据库合并问题。再比如我们做了一个
SmartClient的应用程序,每个客户端都有应用程序和数据库,另外还有一个中心数据库用于汇总所有客户端的数据。每个智能客户端上都可以对自己的
数据库进行增删改查,一旦智能客户端连接到网络上时,系统就将客户端数据库中的数据更改全部应用到中心数据库中,这种偶尔连接的应用程序也是需要数据库的
同步的。
对于前面说到的这些应用,最简单的同步方法就是删除原有数据,然后重新填充新的数据,对于小数据量的表来说这并没有什么问题,但是如果每个市都有几
百万几千万条数据,那么要将省数据库中的数据删除了再把每个市中的数据全部填充到省数据库中显然是不可行的。这种情况下应该使用跟踪数据更改的方法,将每
个市这个月的数据更改应用到省数据库中(感觉有点像是差异备份一样,只记录更改的)。在SQL Server 2008中提供了两种跟踪数据更改的方案:
- 变更数据捕获(Change Data Capture)
- 更改跟踪(Chang Tracking)
今天我主要说的是更改跟踪,变更数据捕获在以后进行讲解。
启用更改跟踪
更改跟踪是SQL Server
2008的一个新特性,默认情况下是没启用的。更改跟踪可以应用跟踪到具体一个数据库中的具体表甚至是具体的列。更改跟踪并不会创建触发器之类的对象,只
是在用户对启用了更改跟踪的表进行了增加、修改和删除操作时,系统自动将该操作生成一个版本号,记录下操作的时间戳、操作的类型、受影响的数据的主键等信
息。启用更改跟踪后对数据操作的性能影响不是很大。这些信息是记录到SQL Server系统表中的,系统自动负责清理和维护。
要使用更改跟踪需要启用数据库的更改跟踪功能和表的更改跟踪功能。在SSMS中数据库的属性窗口中可以启用数据库的更改跟踪:
这里将更改跟踪选项设置为true既可启用更改跟踪。另外3个选项就是跟踪的数据自动清理的开关和清理的时间,这个自动清理的时间必须大于我们要同
步数据的周期,比如我们的数据是一个月同步一次,那么这个保持期就应该大于31天,如果设置保持期太短,那么我们的跟踪数据还没来得及同步就被自动清理
了。
这里只是启用了数据库的更改跟踪,接下来是要启用表的更改跟踪。这里我们创建一个新的表t1并初始化几条数据:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CREATETABLEt1
(
c1INTIDENTITYPRIMARYKEY,
c2VARCHAR(50)NOTNULL,
c3DATETIMENOTNULL,
c4VARCHAR(max)
)
GO
INSERTINTOt1VALUES('test1','2009-1-1','www.cnblogs.com/studyzy')
INSERTINTOt1VALUES('test2','2009-1-1','www.cnblogs.com/studyzy')
INSERTINTOt1VALUES('test3','2009-1-2','www.cnblogs.com/studyzy')
接下来在SSMS中查看表t1的属性窗口,可以在属性窗口中启用该表的更改跟踪功能:
其中第二个选项“跟踪已更新的列”是表示是否将更改跟踪细化到列上。对于一般的表来说,我们只需要知道具体哪些行进行了更改,然后在合并数据时将整
行数据更新到中心数据库既可,但是如果表中有大对象列(text image varchar(max) varbinary(max)
xml等数据类型的列)时,将整行进行更新可能非常慢,所以我们可以启用“跟踪已更新的列”将具体更新了哪些列记录下来,这样在合并数据时就直接更新这些
列既可。
更改跟踪常用函数
在更改跟踪中最重要的一点就是版本号,版本号从0开始一直递增,对表的每一次更改操作都会产生一个新的版本号。使用
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->SELECTCHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('dbo.t1'))
可以获得t1表最小版本号,由于是刚创建更改跟踪,所以这里返回的是0,如果我们进行了大量的操作以后,而且这些操作的时间已经超过了数据库更改跟踪中设置的保持期时间,那么过期的版本就会被系统自动清理,清理后最小版本就不是0了,而是保留的可用的最早版本。
SELECT CHANGE_TRACKING_CURRENT_VERSION()可以获得当前数据库的更改跟踪的最新版本。这里由于我们启用更改跟踪后还没有进行数据库操作,所以返回的也是0。
现在我们向表t1中插入一条数据,然后查看当前最新版本:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->INSERTINTOt1VALUES('test','2009-1-4','www.cnblogs.com/studyzy')
SELECTCHANGE_TRACKING_CURRENT_VERSION()--返回1
现在返回的版本号就是1了。
接下来我们再修改2条数据和删除1条数据,再查看版本号:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->UPDATEt1SETc3=GETDATE()WHEREc1<3--受影响2条数据
DELETEFROMt1WHEREc2='test3'--受影响1条数据
SELECTCHANGE_TRACKING_CURRENT_VERSION()--返回3
这里我们总共影响了4条数据,但是版本号为3说明版本号并不是以受影响的行实来定的,一次更新操作中不管影响了好多条数据(当然这里不能为0条)版本号只增加1。
现在版本号有了,接下来就是查询出这段时间t1的更改情况,需要使用表值函数:CHANGETABLE(CHANGES [要查询更改跟踪的表名], 从哪个版本开始的更改)。这里要查询t1表从0版本开始到现在的所有数据更改,那么对应的查询语句是:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->SELECT*
FROMCHANGETABLE(CHANGESdbo.t1,0)asct
系统返回结果:
SYS_CHANGE_VERSION |
SYS_CHANGE_CREATION_VERSION |
SYS_CHANGE_OPERATION |
SYS_CHANGE_COLUMNS |
SYS_CHANGE_CONTEXT |
c1 |
2 |
NULL |
U |
0x0000000003000000 |
NULL |
1 |
2 |
NULL |
U |
0x0000000003000000 |
NULL |
2 |
3 |
NULL |
D |
NULL |
NULL |
3 |
1 |
1 |
I |
NULL |
NULL |
4 |
这里每个列的数据类型、含义等在联机丛书里面解释的很清楚,我这里只简单介绍下返回的这个表:
在版本号为1的数据更改操作中是插入了一条数据,插入数据的主键c1=4;在版本号2的操作中更新了2条数据,分别是c1=1和c1=2的行;在版本3的操作中删除了c1=3的一条数据。
根据更改跟踪同步数据
现在所有的更改已经查询出来了,接下来就可以根据查询出来的这个结果同步数据了。为了演示方便,我这里将在同一个实例中建立TestDB1数据库并初始化t1表用于表示中心数据库。那么同步数据的操作应该是:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->--首先将新增的数据插入到中心数据库中:
SETIDENTITY_INSERTTestDB1.dbo.t1ON
INSERTINTOTestDB1.dbo.t1(c1,c2,c3,c4)
SELECTt1.*
FROMCHANGETABLE(CHANGESdbo.t1,0)ASct
INNERJOINt1
ONct.c1=t1.c1
WHEREct.SYS_CHANGE_OPERATION='I'
--接下来将更改的数据应用到中心数据库中:
UPDATETestDB1.dbo.t1
SETc2=newt1.c2,c3=newt1.c3,c4=newt1.c4
FROMCHANGETABLE(CHANGESdbo.t1,0)ASct
INNERJOINdbo.t1ASnewt1
ONct.c1=newt1.c1
WHEREct.SYS_CHANGE_OPERATION='U'ANDt1.c1=newt1.c1
--将删除的数据从中心数据库删除:
DELETEFROMTestDB1.dbo.t1
WHEREc1IN(
SELECTc1
FROMCHANGETABLE(CHANGESdbo.t1,0)ASct
WHEREct.SYS_CHANGE_OPERATION='D')
这样我们就使用更改跟踪实现了数据库的同步。该同步操作时的版本号是3,这个版本号必须要单独记下来,那么下次再进行同步是就从3开始查询。
通过更改跟踪更新列
前面的同步脚本中关于数据update操作是:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->UPDATETestDB1.dbo.t1
SETc2=newt1.c2,c3=newt1.c3,c4=newt1.c4
由于c4是大对象数据类型,如果里面存放了几十兆或者更大的数据,而实际上我们更新的并不是c4列,那么这种更新方式必然很浪费时间和资源。前面我们对t1表已经启用了“跟踪已更新的列”,那么就可以根据实际更新的列来更新数据。
使用CHANGE_TRACKING_IS_COLUMN_IN_MASK()函数可以判断一个列是否发生了更改,如果发生了更改则返回1,没有更改则返回0。比如查询c2是否发生更改:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->SELECT*,CHANGE_TRACKING_IS_COLUMN_IN_MASK(COLUMNPROPERTY(OBJECT_ID('dbo.t1'),'c2','ColumnId'),SYS_CHANGE_COLUMNS)
FROMCHANGETABLE(CHANGESdbo.t1,0)ASct
WHEREct.SYS_CHANGE_OPERATION='U'
这里返回0说明没有更改c2列,同样的方法可以判断出c3列发生了更改。
既然可以判断哪些列发生了更改,那么就可以根据发生更改的列来更新该列的数据,比如对于c2的更新语句就是:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->UPDATETestDB1.dbo.t1
SETc2=newt1.c2--更新c2列
FROMCHANGETABLE(CHANGESdbo.t1,0)ASct
INNERJOINdbo.t1ASnewt1
ONct.c1=newt1.c1
WHEREct.SYS_CHANGE_OPERATION='U'ANDt1.c1=newt1.c1
ANDCHANGE_TRACKING_IS_COLUMN_IN_MASK(COLUMNPROPERTY(OBJECT_ID('dbo.t1'),'c2','ColumnId'),ct.SYS_CHANGE_COLUMNS)=1--发生更改时才更新
同样的方法可以写出c3列、c4列的更新语句。如果觉得这样重复的写很麻烦,那么可以写一个存储过程,传入列名,检查该列是否更改,如果更改了则更新。
总结
更改跟踪是在偶尔连接的数据库应用和同步数据时非常有用的一个特性。更改跟踪里面的核心就是版本号,每次在同步数据时记录下当前的版本号,下次再同步时CHANGETABLE函数就传入上次同步的版本号,这样可以避免重复同步。
更改跟踪的跟踪记录数据是保存到系统表中的,由系统来维护,在开启数据库的更改跟踪时可以设置自动清除的时间,从而保证系统不会因为记录太多的跟踪数据而导致数据库文件大小急剧膨胀。
更改跟踪启用后对一般的DML操作(增删改)是不会有影响的,所有的DML SQL语句照常使用,而且启用更改跟踪后并不会对系统性能造成明细影响。
分享到:
相关推荐
SQL Server 2008 包含了一系列的新特性,比如改进的安全性、增强的数据类型支持以及对XML数据的支持等。 #### 二、SQL Server 2008 的安装步骤 1. **下载安装包**:首先需要从微软官方网站或其他可靠来源下载SQL ...
是指在Windows 10环境下,为了通过Navicat连接并管理SQL Server 2008数据库,需要安装特定的客户端组件——Microsoft SQL Server 2008 Native Client。 Microsoft SQL Server 2008 Native Client是微软官方推出的一...
SQL Server 2008 Reporting Services揭秘——SSRS更改使改进的需求更加迫切.pdf
探索SQL Server的安全特性,如登录、用户、角色和权限,理解如何为不同的用户分配访问和操作数据库的权限,是保护数据安全的重要步骤。 8. **性能优化**: 最后,你可以通过监控和调整索引、统计信息和查询计划,...
这一章主要介绍了SQL Server 2008的基本概念、版本信息以及新特性。包括Express、Standard、Enterprise等不同版本的区别,以及增强的数据加密、备份恢复、性能优化等方面的改进。 第二章:安装与配置SQL Server ...
遇到SQL Server 2008中修改数据表不允许保存的问题时,首先需要理解其背后的原理——SSMS为防止数据丢失而默认启用的安全机制。通过简单的配置调整,可以轻松解决这一问题。然而,在处理包含大量数据的表时,还需要...
【SQL Server课程设计报告——图书馆管理系统】 在本次课程设计中,我们构建了一个基于SQL Server的图书馆管理系统,旨在解决图书馆管理中的各种挑战。该系统通过数据库技术实现图书、图书类型、借阅者信息的有效...
SQL Server 2008 是一个功能强大且广泛应用的关系数据库管理系统,它提供了强大的数据存储和管理功能。然而,在实际应用中,我们经常需要对数据库进行维护和管理,包括修改 sa 密码。那么,如何修改 SQL Server 2008...
### PHP安装连接SQLSERVER扩展方法 #### 背景与目的 在开发基于Web的应用程序时,PHP(Hypertext Preprocessor)作为一种广泛使用的开源服务器端脚本语言,经常需要与各种数据库进行交互来实现数据存储和检索等...
本系统——"C#下结合Sqlserver2008的学生信息管理系统",就是一个典型的案例,它旨在帮助学校高效地管理学生信息,同时也兼顾了教师和管理员的需求。 C#,全称C Sharp,是微软推出的一种面向对象的编程语言,以其...
SQL Server 2008 数据库管理系统引入了数据压缩功能,这项新功能旨在帮助数据库管理员和开发人员节省磁盘存储空间、增加RAM可用数据量,并通过减少I/O操作来提升数据库查询的性能。本文将详细介绍SQL Server 2008中...
用户可以根据需要卸载SQL Server或者更改安装时所选择的特性组件。 这份指南的内容虽然主要以SQL Server 2012为例,但其安装和配置方法对SQL Server 2008及2012家族的其他版本也有很强的适用性。文档针对的是波士顿...
综上所述,这份"sqlserver2008教案"不仅覆盖了T-SQL的基本语法和高级特性,还通过实例和案例教学,使你能够掌握SQL Server 2008的实战应用。无论你是初学者还是有一定基础的数据库管理员,都能从中受益匪浅,提升你...
SQL Server 2014引入了诸多创新特性,其中最引人注目的是名为“Hekaton”的内存数据库引擎。这一特性并非对SQL Server的替换,而是作为现有功能的补充,旨在利用现代硬件的进步,尤其是内存容量的显著增长。内存...
SQL Server 2008以其三大核心特性——可信任的、高效的和智能的,满足了企业对关键任务应用程序的需求,同时降低了管理成本。 1. **可信任的** - **数据加密**:SQL Server 2008实现了全库、数据文件和日志文件的...
SQL Server 课程设计——图书馆管理系统数据库设计 本文档主要介绍了一个基于 SQL Server 的图书馆管理系统数据库设计,旨在解决传统的人工方式管理图书馆中的混乱和低效问题。该系统主要包括图书、图书类型、借阅...
【ASP+SQL+Server+程序代码系统——图书管理】是一个基于Web的图书管理应用程序,它利用Active Server Pages(ASP)技术、SQL Server数据库管理和Microsoft Server Web服务器的强大功能,实现高效、安全的图书信息...
《C#与SQL Server数据库:构建简易图书管理系统》 在信息技术领域,开发一个图书管理系统是一项常见的练习,它有助于我们理解数据库操作和客户端应用程序的交互。本项目以C#编程语言和SQL Server数据库为核心,实现...
实验1:数据库的定义实验——使用SQL Server企业管理器创建数据库、索引和修改表结构,并学会使用查询分析器,接收T—SQL语句和进行结果分析。 实验2:数据库的查询实验——掌握SQL Server查询分析器的使用方法,...