博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server 中心订阅模型(多发布单订阅)
阅读量:6823 次
发布时间:2019-06-26

本文共 2334 字,大约阅读时间需要 7 分钟。

原文:

大多数SQL Server 复制拓扑都是基于中心发布模型,它是由一个发布复制到一个或者多个订阅。另一个复制模型是中心订阅模型,它使用事务复制由多个发布复制到一个订阅中。

中心订阅模型用于从多个数据源中合并数据,例如:

》从多个数据仓库中汇总库存到企业总部的中心服务器;

》同一个公司中从持续发送远程办公数据到中心办公系统中;

》合并订单信息到同一个地方集中处理。

默认情况下,订阅通过快照代理初始化生成快照并被分发代理应用。当快照被应用时,默认情况 项目(article)属性
“名称已被使用时的操作(Action if name is in use)" 设置为
"删除先有对象并重新创建(Drop existing object and create a new one)" ,意思是当订阅中存在目标表对象时将被删除,并重新创建该对象。在中心订阅模型中,当从多个发布中应用快照时这种设置是有问题的。第一个快照应用是正常的,后续的快照应用时将会清除掉前一个快照的数据。

解决这个问题的方法是水平分区,设置静态行筛选器,设置属性 “名称已被使用时的操作”为 “删除数据,如果目标有行筛选器,仅删除与该筛选器匹配的数据(Delete data,If article has a row filter, delete only data that matches the filter)

现在,本人使用2个分库数据,合并到另一个数据库中:

【设置水平分区标志】

默认情况下,表结构如下:

CREATE TABLE [dbo].[DemoTab](	[id] [int] IDENTITY(1,1) NOT NULL,	[name] [varchar](10) NOT NULL,	[value] [decimal](18, 4) NULL,	CONSTRAINT [PK_DemoTab] PRIMARY KEY CLUSTERED ([id] ASC))GO
如果这样,id 自增量肯定有重复键,因此增加一个标志列 [LocationID],并如 id 列作为组合键。如下,分别在两个发布数据表中创建表。

--数据库:[TestDBSubA]USE [TestDBSubA]GOCREATE TABLE [dbo].[DemoTab](	[id] [int] IDENTITY(1,1) NOT NULL,	[name] [varchar](10) NOT NULL,	[value] [decimal](18, 4) NULL,	[LocationID] INT NOT NULL DEFAULT(1)	CONSTRAINT [PK_DemoTab] PRIMARY KEY CLUSTERED ([id] ASC,[LocationID] ASC))GO--数据库:[TestDBSubB]USE [TestDBSubB]GOCREATE TABLE [dbo].[DemoTab](	[id] [int] IDENTITY(1,1) NOT NULL,	[name] [varchar](10) NOT NULL,	[value] [decimal](18, 4) NULL,	[LocationID] INT NOT NULL DEFAULT(2)	CONSTRAINT [PK_DemoTab] PRIMARY KEY CLUSTERED ([id] ASC,[LocationID] ASC))GO
此时就可以使用字段 [LocationID] 来确定是不同数据库的数据了,在同一个订阅表中就不会有主键重复问题了。但是当在其中一个发布初始化时,或者操作数据时,怎么区分来自不同的发布数据库的数据呢?接下来设置静态行筛选器,非常重要!

【设置静态行筛选器】

此时可以在 数据库 [TestDBSubA] 或 [TestDBSubB] 的服务器中创建发布了,使用的是事务复制,选择需要发布的表,如下图:

下一步,设置行筛选器,筛选条件为 [LocationID]=1(这个是数据库 [TestDBSubA] 的发布),同理设置 [TestDBSubB] 的发布!

接下来一步步完成即可。还有一步重要的设置,发布表对象的属性。其实在上一步在操作中也可以设置。

【设置表项目的应用属性】

右键刚创建完成的发布,选择属性,选择项目,可以选择设置一个表或者所有表。如图:

选择设置所有表,设置属性 “名称已被使用时的操作”为 “删除数据,如果目标有行筛选器,仅删除与该筛选器匹配的数据(Delete data,If article has a row filter, delete only data that matches the filter)

设置完成后确定推出!

同理设置 [TestDBSubB] 的发布!(注意 [LocationID] = 2)

订阅正常设置,两个发布的订阅都是同一个数据库。

先后分别初始化应用快照,正常!

现在测试,分别在两发布数据库中插入数据。

INSERT INTO [TestDBSubA].[dbo].[DemoTab]([name],[value]) SELECT 'TestDBSubA',0INSERT INTO [TestDBSubB].[dbo].[DemoTab]([name],[value]) SELECT 'TestDBSubB',0SELECT * FROM [TestDB].[dbo].[DemoTab]

结果合并了!!所有DML操作正常同步!数据可以正常操作同步,但是字段增删改则有问题!!

你可能感兴趣的文章
文字排版中的设计四原则(三)
查看>>
我的友情链接
查看>>
JavaSE 学习参考:常量
查看>>
netapp 2个控制器spare盘分配
查看>>
我的友情链接
查看>>
华为AR2220E-S 设置限制上网时间
查看>>
实现cell的点击高亮
查看>>
如何用腾讯云打造一款微视频APP
查看>>
linux内核中的hook函数详解
查看>>
调用手机GPS实现当前位置定位并展现百度地图上
查看>>
Dota2卡牌游戏《Artifact》登陆Windows/Mac/Linux
查看>>
ruby向数据库用语句插入数据
查看>>
个人--IT业的职业细分
查看>>
“赋能开发者”高峰论坛暨葡萄城联合龙头企业共建模板库正式启动
查看>>
CentOS内核参数优化参考
查看>>
2017年大数据分析领域的六大发展趋势
查看>>
删除Jenkins的构建次数(基于Jmeter的Maven项目)
查看>>
springboot中配置文件配置各种随机数
查看>>
scala----函数和构造函数区别
查看>>
Linux平台的boost安装方法
查看>>