Step6: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) 列。
Step6:SQL Server 数据变更时间戳(timestamp)在复制中的运用的更多相关文章
- 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]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
- ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据
下载地址:https://www.apexsql.com/download.aspx 如何从意外UPDATE和DELETE操作中恢复SQL Server数据 ApexSQL Log 从意外UPDATE ...
- Docker-compose搭建ELK环境并同步MS SQL Server数据
前言 本文作为学习记录,供大家参考:一次使用阿里云(Aliyun)1核2G centos7.5 云主机搭建Docker下的ELK环境,并导入MS SQL Server的商品数据以供Kibana展示的配 ...
- SQL server数据缓存依赖
SQL server数据缓存依赖有两种实现模式,轮询模式,通知模式. 1 轮询模式实现步骤 此模式需要SQL SERVER 7.0/2000/2005版本以上版本都支持 主要包含以下几 ...
- 两台SQL Server数据同步解决方案
复制的概念 复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式.使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可 ...
随机推荐
- OC UITextField只允许输入两位小数
//只能输入两位小数 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range r ...
- Python3学习之路~3.2 递归、函数式编程、高阶函数、匿名函数、嵌套函数
1 递归 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. def calc(n): print(n) if int(n / 2) == 0: return n r ...
- 006-UDP用户数据报文协议
一.概述 用户数据报协议(英语:User Datagram Protocol,缩写为UDP),又称用户数据报文协议,是一个简单的面向数据报的传输层协议,正式规范为RFC 768. 在TCP/IP模型中 ...
- C# List去重的三种方法
三种去重的方法 1.List中的元素实现IEquatabe接口,并提供Equals方法和GetHashCode方法. 2.使用表达式 users.Where((x,i)=>users.FindI ...
- 用PE系统安装原版XP
方法:直接运行Winnt32程序进行XP原版系统安装. [1].在PE系统中将XP SP3系统镜像ISO文件从U盘上复制到硬盘的非系统分区后,用PE所带WinRAR程序将该ISO镜像中的I386 ...
- Redis入门到高可用(五)—— 单线程
一.单线程为何这么快 1)绝大部分请求是纯粹的内存操作(非常快速) 2)采用单线程,避免了不必要的上下文切换和竞争条件 3)非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框 ...
- [Shapefile C Library]读写shp图形(C++&.net Wapper)
ShapeLib的.net Wapper版可以在官网下载到,在WorldWind中也有使用.ORG据说也是使用的ShapeLib实现的shp文件的读写. 官网:http://shapelib.mapt ...
- 使用awk处理文本
http://blog.wuxu92.com/using-awk/ 在Liux下我们经常需要对一些文本文档做一些处理,尤其像从日志里提取一些数据,这是我们一般会用awk工具和sed工具去实现需求,这里 ...
- JS快速入门
字符串 模板字符串 需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果: var s = 'Test'; s[0] = 'X'; alert(s); ...
- 20个Java练手项目,献给嗜学如狂的人
给大家推荐一条由浅入深的JAVA学习路径,首先完成 Java基础.JDK.JDBC.正则表达式等基础实验,然后进阶到 J2SE 和 SSH 框架学习.最后再通过有趣的练手项目进行巩固. JAVA基础 ...