如何合并和同步SQL Server数据库文件?

13

我正在为与数据库同步的Windows平板电脑构建C#程序。它们将各自拥有本地的 .MDF SQL Server 数据库,并使用 SQL Server Express 进行交互。

然而,用户会在没有网络连接的情况下更改数据。当其中一个重新连接到包含“主数据库副本”的网络时,我希望将他们的 .MDF 数据库与之同步。然后用新同步的文件替换计算机和平板电脑的数据库文件。

我有一个 uniqueidentifier 列和最后更改该行的 datetime,因此如果存在冲突,我将选择最近的更改。

我已经阅读了一些相关文献,但我想看到一个明确的示例或教程来完成此操作。我知道我想要的是合并复制(Merge Replication),而Microsoft Sync Framework似乎具备我所需的功能。但我仍然不太会实现。或者,您可以推荐其他工具来完成此操作。

提前感谢!


你是否熟悉以下术语“断开的记录集,Delta”?我会在网上做一些研究/搜索,了解如何在离线时同步数据库等。 - MethodMan
不,我不是,非常感谢!第一次在谷歌上搜索这些东西时的挣扎之一是我不知道所有正确的关键词。 - Charles Clayton
4个回答

3

虽然我的回答并不充分,但我相信这可以通过Microsoft Sync Framework来完成。我也相信即使平板电脑离线,您也可以轻松同步数据库。唯一的限制可能是缺少实时同步功能,需要使用Azure服务、WebSockets、Apache MQ或其他技术。抱歉没有更多的信息,我会将其发布为评论,但是我没有足够的积分。


1

MS Merge Replication是一个复杂的系统,但根据您的使用情况,大多数功能您将不需要。我提前警告您,它已知存在问题。在企业中,它不太可靠。虽然它可以工作,但需要仔细监管。如果您不介意服务调用,则可以继续使用。如果您想要一个强大的同步系统(针对您的用例),那么最好是使用审计表自己编写。这并不难做,特别是您已经使用guid作为主键。您还可以从使用顺序guid中受益。随机guid会导致聚集索引的碎片化,严重影响数据库性能。如果您需要实现方面的帮助,请联系我。我已经成功地为客户完成了此项工作。他们每天处理超过一百万条记录,没有出现任何问题。如果您仍想使用MS Merge Replication,我也可以为您提供帮助。


有趣,我没有听说过审计表。我会去看看,谢谢。你对同步框架有什么想法吗? - Charles Clayton
老实说,对于这种用例,我会完全避开MS Sync框架。如果你只想复制数据,可以使用审计表和一个服务来处理待处理的更改。虽然需要更多的前期工作,但最终可以节省大量的服务调用。 - itsben
请提供您其中一个表的“创建表”语句。我将为您生成一个示例。 - itsben

1
如果是Windows Store应用程序(WinRT),您需要使用Sync Framework Toolkit
如果是普通的Windows应用程序(WPF,WinForms等),是的,您可以使用Sync Framework。
两者的想法都是,您的Windows应用程序使用本地数据库(SQL CE,LocalDB,SQLite等)进行CRUD,当您连接到中央服务器时(通过WCF,例如this),偶尔进行同步。

0

大多数现有的工具,如Microsoft Sync和Merge-Replication,似乎过于复杂,而且比它们所值得的更麻烦。

这是我的SQL脚本,用于附加数据库。

CREATE DATABASE LocalDatabase  
ON (Filename = 'C:\ProgramData\Clayton\Database.mdf')
   , (Filename = 'C:\ProgramData\Clayton\Database_log.ldf') 
FOR ATTACH;
GO

EXEC sp_addlinkedserver @server='Server'

然后同步数据库

-- update the client from the master 
MERGE [LocalDatabase].[dbo].[tableName] trgt
using [Server].[ServerDatabase].[dbo].[tableName] src

ON trgt.id = src.id 

WHEN matched AND trgt.lastmodified <= src.lastmodified THEN 
  -- if the master has a row newer than the client
  -- update the client                       
  UPDATE SET trgt.[allColumns]      = src.[allColumns],
             trgt.[id]              = src.[id], 
             trgt.[lastmodified]    = src.[lastmodified] 

-- delete any rows added by a client 
WHEN NOT matched BY source 
THEN 
  DELETE 

-- insert any rows added by the master 
WHEN NOT matched BY target 
THEN 
  INSERT ( [allColumns], 
           [id], 
           [lastmodified]) 
  VALUES (src. [allColumns], 
          src.[id], 
          src.[lastmodified]); 


-- now we update the master from the client
-- Note:
-- because the serverDB is a linked server 
-- we can't use another MERGE statement, otherwise
-- we get the error: "The target of a MERGE statement 
-- cannot be a remote table, a remote view, or a view over remote tables."

UPDATE
    serverDB

SET 
    [allColumns]        = [localDB].[allColumns],
    [id]                = [localDB].[id], 
    [lastmodified]      = [localDB].[lastmodified] 

FROM 
     [Server].[ServerDatabase].[dbo].[tableName] serverDB

INNER JOIN
     [LocalDatabase].[dbo].[tableName] localDB

-- update where the id is the same but the client is newer than the master

ON serverDB.id = localDB.id 
       AND localDB.lastmodified >= serverDB.lastmodified

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接