Identity_insert和同步问题
我在当前项目中使用 SQL Server 2008、Visual Studio 2008、linq、ado.net。该项目在网页和桌面上实现。
现在我的问题是网络数据库和桌面数据库之间的数据同步。
这里的同步是这样的:
- 客户端插入的新数据同步到服务器。
- 客户端更新数据同步到服务器。
这里让我向您展示我的表结构。
让我们假设我的表名称是“customer”,其中包含字段
customer
...................
customerno,bigint,主键,不为空,身份为true(从1开始)
名字,...
姓氏,...
现在我将在客户端中拥有相同的表,但主键标识将从 20000 开始。此主键标识取决于客户端系统的数量。让我们考虑以下场景
server = customerno 以 1 开头,表中有 1 条记录
client1 = customerno以20000开头,表中有2条记录
client2 = customerno从30000开始,
现在当我在client1中按下同步时,表中有3条记录,使用以下代码
cmd.CommandText = "set identity_insert " + tableName + " on";
cmd.ExecuteNonQuery();
foreach (string query in this.queries)
{
cmd.CommandText = query; // this is my insert query
cmd.ExecuteNonQuery();
}
cmd.CommandText = "set identity_insert " + tableName + " off";
cmd.ExecuteNonQuery();
,因为linq不支持identity_insert,我
在我的代码中使用ado.net,首先我将identity_insert设置为on,插入数据并最后将identity_insert设置为关闭。
现在我的问题是,从 client1 同步数据后, 并在服务器中插入两条记录,customerno 分别为 20001,20002。
根据 http://msdn.microsoft.com/en-us/library/ms188059 .aspx
服务器中 customerno 列的标识设置为最大值(在本例中为 20002)。
所以现在当我在服务器中插入数据时,它会插入 customerno 作为 20003。
这里我不希望服务器标识列取最大值。
考虑到上述情况,在同步之前,我们在服务器中有1条记录,其id为1,因此在同步(与一个或多个客户端)之后,我希望服务器中的下一个id(customerno)为2,3,4。 ....用于服务器中新插入的数据。
在这里任何客户端都可以在任何时间点与服务器同步数据。
I'm using SQL Server 2008, visual studio 2008, linq, ado.net in my current project. this project is implemented in web and desktop.
now my problem is with synchronization of data between web db and desktop db.
here synchronization is as follow:
- new data inserted in client is synced to server.
- updated data in client is synced to server.
here let me show you my table structure.
let us suppose my table name is "customer" with fields
customer
...................
customerno, bigint, primary key, not null, identity true (starting with 1)
firstname, ...
lastname, ...
now i'll have the same table in client but the primary key identity will start with 20000. this primary key identity depends on the number of client systems. let consider the following scenario
server = customerno starting with 1, with 1 record in table
client1 = customerno starting with 20000, with 2 records in table
client2 = customerno starting with 30000, with 3 records in table
now when i press sync in client1, using the following code
cmd.CommandText = "set identity_insert " + tableName + " on";
cmd.ExecuteNonQuery();
foreach (string query in this.queries)
{
cmd.CommandText = query; // this is my insert query
cmd.ExecuteNonQuery();
}
cmd.CommandText = "set identity_insert " + tableName + " off";
cmd.ExecuteNonQuery();
as linq doesnt support identity_insert, im using ado.net
in my code, first im setting the identity_insert on, inserting the data and finally setting identity_insert off.
now here my problem, after data is synced from client1,
and two records are inserted in server with customerno as 20001,20002.
as per http://msdn.microsoft.com/en-us/library/ms188059.aspx
the identity of customerno column in server is set to the max value (in this case it will be 20002).
so now when i insert data in server, it inserts with customerno as 20003.
here i dont want the server identity column to take the max value.
considering the above case, before sync, we have 1 record in server, and its id is 1, so after sync (with one or more clients), i want the next id(customerno) in server to be 2,3,4..... for newly inserted data in server.
here any client can sync data with server at any point of time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您将一个字段用于两件事。唯一地识别客户并找出信息来源。
您可以使用 uniqueidentifier 作为主键,并使用另一个字段来确定信息的来源。
使用 newid() 作为主键的默认约束。当您进行复制时,您指定要使用的 GUID,并且将使用该 GUID 而不是 newid()。
编辑 1
如果您在替换主键时遇到问题,可以将 GUID 列添加为候选键。那么问题将是,如果您需要更新与 Customers 表相关的表,那么在服务器之间复制数据的逻辑将变得更加复杂。您必须首先插入所有客户,然后查询客户表以找出应在相关表中使用的 FK CustomerID。
You are using one field for two things. Uniquely identifying a customer and to figure out the source of the information.
You can use a uniqueidentifier as the primary key and use another field to determine the source of the information.
Use newid() as a default constraint for your primary key. When you are replicating you specify the GUID to use and that will be used instead of newid().
Edit 1
If you have trouble replacing your primary key you can add the GUID column as a candidate key. The problem then will be that the logic for replicating data between servers will be a lot more complicated if you need to update tables that have a relation to your Customers table. You have to first insert all Customers and then query the Customers table to figure out what FK CustomerID you should use in related tables.
你的处境非常糟糕。如果要分配代理键范围,则不能使用标识列。放弃这个并使用内置的复制技术可能是正确的选择要做的事©。
如果你不能做正确的事情,你可以删除标识列并将其设置为 int。然后您可以创建自己的自动递增算法,但要注意竞争条件(即不要使用 MAX)
You are in a very bad place. If you want to assign ranges of surrogate key you can't use an identity column. Abandoning this and going with the built-in replication technology is probably The Right Thing© to do.
If you can't do the right thing you'll can drop the identity column and make it an int. Then you can create your own auto-incrementing algorithm but watch out for race conditions (i.e. don't use MAX)
我认为你想做的事情是可能的。我并不是说这是最好的想法,但据我所知,以下内容将以阻止同步期间所有数据修改为代价。显然,该方法本身存在固有的问题,但需要准确预测最大可能的客户端数量和每个源的最大插入数量。
What you want to do is possible I think. I'm not suggesting that it is the best idea ever but as far as I can see the following would work at the expense of blocking all data modifications during the synch. Obviously there are inherent problems in the approach itself though in terms of needing to accurately predict maximum possible numbers of client and the maximum number of inserts from each source.