SQL Server 数据变更时间戳(timestamp)在复制中的运用
一.本文所涉及的内容(Contents)
二.背景(Contexts)
SQL Server数据库中Basic与Group两个表需要提供部分字段给其它程序读取,程序把这两个表的数据缓存到内存中,但是程序想知道这两个表数据的变更信息,包括:Insert/Update/Delete,有什么方式可以实现呢?
三.方案(Solution)
上面的场景,使用SQL Server复制(Replication)是无可厚非的,但是如何及时获取变更信息呢?
方案一:
使用变更数据捕获CDC这个功能,在数据库订阅库使用CDC,再创建一个存储过程;通过向存储过程传入最后一次记录(程序自己保存)的日志序列号(LSN),返回表变更的数据列表,程序先从内存中删掉这些ID值,再把变更数据插回内存,这个逻辑可以简化对Insert/Update/Delete的所有处理;

(Figure1:变更数据捕获)
方案二:
使用更改跟踪(Chang Tracking)这个功能,更改跟踪会包括跟踪表的唯一值,还有字段SYS_CHANGE_OPERATION,枚举值(I=Insert、U=Update、D=Delete),还有DML操作的版本号:SYS_CHANGE_VERSION,它是每进行一次DML,都会递增一个版本号,所以你可以针对I=Insert、U=Update、D=Delete不同的类型加上版本号过滤,就可以找到那些数据进行了更新;

(Figure2:更改跟踪)
方案三:
使用timestamp,在订阅的两个表中加入这个字段,timestamp记录的是数据变更的时间,在程序中读取大于这个timestamp的数据进行操作(操作如想法一所示);但是有个缺点,这种方式没有办法记录到删除的记录,除非表中有个字段是用来标识是否删除的,发布库是不存在Delete操作的,只能有Insert和Update。
需要同步的字段如下:
Basic表:ID,Name,Category,overseas,GroupID,Delete;
Group表:ID,NAME,Delete;
CDC的基本使用可以参考:SQL Server 变更数据捕获(CDC)监控表数据,更改跟踪可以参考:SQL Server 更改跟踪(Chang Tracking)监控表数据,下面我讲讲想法三的具体实现;
四.实现过程(Process)
(一) 环境信息
系统环境:Windows Server 2008 + SQL Server 2008 R2
发布服务器:192.168.1.152,服务器名称:USER-H2B2
订阅服务器:192.168.1.151,服务器名称:USER-FJMO
发布数据库:Task
订阅数据库:TaskSiteInfo
(二) 实现概述
首先是通过Task发布、TaskSiteInfo进行订阅数据,在这两个表中是有一个Delete的字段,用来标识数据是否给删除的,另外需要在TaskSiteInfo数据库的两个表都加入timestamp字段,加入这个字段的目的是由程序记录查询的最大的timestamp,通过这个timestamp返回大于某个时间的数据。
(三) 搭建步骤
A. 搭建复制的过程请参考文档:SQL Server 复制:事务发布,在订阅服务器查看表的信息,如下图所示:

(Figure3:表数据)
B. 接下来我们修改Basic和Group表结构,为每个表添加一个timestamp类型的字段;
--修改表结构
ALTER TABLE [dbo].[Basic] ADD
timestamp timestamp NOT NULL --修改表结构
ALTER TABLE [dbo].[Group] ADD
timestamp timestamp NOT NULL
C. 为这个timestamp类型的字段分别创建索引;
--创建索引
CREATE NONCLUSTERED INDEX IX_Basic_TimeStamp ON [dbo].[Basic]
(
timestamp
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO CREATE NONCLUSTERED INDEX IX_Group_TimeStamp ON [dbo].[Group]
(
timestamp
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
D. 通过timestamp字段查询变更数据,假如上次保存的时间戳的值是:0x0000000000163E30,那么我们通过下面的SQL脚本就能获取到这个时间戳之后变更的记录,获取到这里数据就可以更新内存数据了;
--返回某时间戳之后的数据
SELECT * FROM [dbo].[Basic]
WHERE timestamp > 0x0000000000163E30

(Figure4:某时间戳之后变更的记录)
五.注意事项(Attention)
1. 每个数据库都有一个计数器,当对数据库中包含 timestamp 列的表执行插入或更新操作时,该计数器值就会增加。 该计数器是数据库时间戳;
2. 一个表只能有一个 timestamp 列;
3. 注意删除数据操作是没有办法记录时间戳的,所以你删除记录的逻辑应该是用一个字段标识这行记录已经被删除;
4. 这一属性使 timestamp 列不适合作为键使用,尤其是不能作为主键使用;
5. 如果该列属于索引键,则对数据行的所有更新还将导致索引更新;
6. 若要返回数据库的当前时间戳值:SELECT @@DBTS
7. 在 DDL 语句,请尽量使用 rowversion 而不是 timestamp,在SSMS设计表的时候是没有rowversion数据类型的;
8. 在 CREATE TABLE 或 ALTER TABLE 语句中,不必为 timestamp 数据类型指定列名,如果不指定列名,则 Microsoft SQL Server 数据库引擎将生成 timestamp 列名;但 rowversion 同义词不具有这样的行为。 在使用 rowversion 时,必须指定列名。
9. 不可为空的 rowversion 列在语义上等同于 binary(8) 列。 可为空的 rowversion 列在语义上等同于 varbinary(8) 列。
六.参考文献(References)
SQL Server 数据变更时间戳(timestamp)在复制中的运用的更多相关文章
- Step6:SQL Server 数据变更时间戳(timestamp)在复制中的运用
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 方案(Solution) 方案一(Solution One) 方案二(Solution Two ...
- SQL Server数据库(时间戳timestamp)类型
1.公开数据库中自动生成的唯一二进制数字的数据类型. 2.timestamp 通常用作给表行加版本戳的机制. 3.存储大小为 8 个字节. 不可为空的 timestamp 列在语义上等价于 binar ...
- SQL Server数据库(时间戳timestamp)类型 (转载)
timestamp介绍 公开数据库中自动生成的唯一二进制数字的数据类型. timestamp 通常用作给表行加版本戳的机制. 存储大小为 8 个字节. 不可为空的 timestamp 列在语义上等价于 ...
- 【SQL Server数据迁移】把csv文件中的数据导入SQL Server的方法
[sql] view plaincopy --1.修改系统参数 --修改高级参数 sp_configure 'show advanced options',1 go --允许即席分布式查询 sp_co ...
- SQL Server 复制 - 发布订阅(SQL Server 数据同步)
原文:SQL Server 复制 - 发布订阅(SQL Server 数据同步) SQL Server的同步是通过SQL Server自带的复制工具来实现的,分发布和订阅2大步. A,复制-发布 发布 ...
- 两台SQL Server数据同步解决方案
复制的概念 复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式.使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可 ...
- [SQL]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
- 浅谈SQL Server数据内部表现形式
在上篇文章 浅谈SQL Server内部运行机制 中,与大家分享了SQL Server内部运行机制,通过上次的分享,相信大家已经能解决如下几个问题: 1.SQL Server 体系结构由哪几部分组成? ...
- ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据
下载地址:https://www.apexsql.com/download.aspx 如何从意外UPDATE和DELETE操作中恢复SQL Server数据 ApexSQL Log 从意外UPDATE ...
随机推荐
- direct path read
在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了. 在10g中,都是通过gc buffer来读的,所以不存在direct pa ...
- [LeetCode] Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- ubuntu安装vim时提示 没有可用的软件包 vim,但是它被其它的软件包引用了 解决办法
ubuntu安装vim时提示 没有可用的软件包 vim-gtk3,但是它被其它的软件包引用了 解决办法 本人在ubuntu系统安装vim 输入 sudo apt-get install vim 提示 ...
- 听大神说:https和http有何区别?(转)
在做雅虎的时候,发现用第三方工具截取不到客户端与服务端的通讯,以前重来没碰到过这种情况,仔细看了看,它的url请求时基于https的,gg了下发现原来https协议和http有着很大的区别.总的来说, ...
- JavaScript高级程序设计-(1)html中使用JavaScript
html中使用JavaScript 1.延迟脚本 script标签定义了defer属性,脚本会被延迟到整个页面都解析完毕后运行 详细内容如下: 2.异步脚本 script标签定义了async属性,as ...
- 基于暗通道优先算法的去雾应用(Matlab/C++)
基于暗通道优先的单幅图像去雾算法(Matlab/C++) 算法原理: 参见论文:Single Image Haze Removal Using Dark Channel Pri ...
- 转:Delphi的类与继承(VB与delphi比较)
既然已经做出了com程序用delphi来开发的决定,那当然就要对delphi进行一些深入的了解.有人说delphi是一个用控件堆砌起来的工具,和vb没什么两样:也有人说dephi实际上是面向过程的,他 ...
- 北京电子科技学院(BESTI)实验报告4
北京电子科技学院(BESTI)实验报告4 课程: 信息安全系统设计基础 班级:1452.1453 姓名:(按贡献大小排名)周恩德 .郑凯杰 学号:(按贡献大小排名)20145217 .201453 指 ...
- PHP 分页函数
如果如下:
- PHP用户注册与登录【1】
需求分析 主要功能分为 用户注册.用户登录.用户退出.用户中心 四个部分. 用户注册 用户注册主要功能有: 注册信息表单填写界面 javascript 脚本初步检测用户输入的注册信息. 注册处理模块检 ...