0

質問

クライアント/サーバー データベースで主キーの競合を回避するにはどうすればよいですか

バックグラウンド

多数のデータベースを相互に同期しています。1 つの中央 SQL Server データベースと多数のクライアント SQL Server データベースがあります。ここで、データベースに主キー ID を持つテーブル X があるとします。

最初のクライアントでは、テーブル X に次の ID があります。

X (クライアント 1)
--------
1|SomeValue
2|SomeValue
3|SomeValue
4|SomeValue

そして私が持っている2番目のクライアントで

X (クライアント 2)
--------
1|SomeValue
2|SomeValue
3|SomeValue
4|SomeValue

同期するとき、クライアントはデータをアップロードするだけで、ダウンロードしないようにします。

最初のクライアントをサーバーと同期すると、(1 .. 4) から主キーが追加されます。ただし、2 番目のクライアントと同期すると、PRIMARY KEY CLASH が発生します。どうすればこの問題を解決できますか?

SQL Server 2008 R2、同期フレームワーク、および C# を使用しています。

レガシ データベースを扱っているため、GUID を主キーとして使用するという考えは既に検討しましたが、これは私の場合には実行できません。また、多少エラーが発生しやすい IDENTITY 値を再シードするという考え方。値を挿入せずに ID 列をインクリメントするにはどうすればよいですか? PS: 主キーは、1 ずつ増加する IDENTITY に設定されています。

4

3 に答える 3

5

レコードを挿入できる分散クライアントをサポートするには、スキーマがクライアント DB による競合のない行の作成をサポートする必要があります。これは、PK の GUID または連結キーを使用することを意味します。(ID + ClientID) *いずれにしても、スキーマの変更。

それ以外の場合、クライアント データベースを手動で同期することは、挿入前に競合する ID をチェックするか、例外を処理してから ID を置き換えるか、競合するレコードの ID を生成できるようにすることを意味します。これは、すべての FK リレーションシップを更新することを意味します。時間がかかり、エラーが発生しやすい。

于 2013-01-05T15:17:23.657 に答える
2

これにはいくつかの方法があります。1 つ目は、アップストリーム データベースとダウンストリーム データベースの両方がそのレコードを参照できる一意のキーが保証されているかどうかです。SQL サーバーの場合、必要なキーの種類は UNIQUEIDENTIFIER (別名 GUID) です。

なんらかの理由で UNIQUEIDENTIFIER を使用できない場合、2 番目に最適なオプションは、場所などの列を追加することです。この列は、レコードが由来する個々のデータベースを識別します。たとえば、最初のクライアントのロケーション ID は 1、2 番目のクライアントのロケーション ID は 2 などです。次に、既存の主キーを変更して、このロケーション ID と現在の ID の複合キーにします。

3 番目のオプションは、クライアント データベースをまったく変更せず、「マスター」データベース内のテーブルに場所 ID 列のみを追加することです。コードで手動で同期している場合、コードはレコードの送信元を考慮し、必要に応じて ID を追加する必要があります。これは難しいかもしれませんが、確かに可能です。

特定の時点で ID 値を開始するには、クライアント データベースを再シードする必要があることを明らかにします。たとえば、クライアント 1 は 1 から 10000 の値を取得し、クライアント 2 は 10001 から 20000 を取得する可能性があります。ただし、ここで失敗の可能性を確認できます。クライアントが許容範囲を超えた場合だけでなく、追加のクライアントをセットアップし、誰かがシード値を台無しにした場合も同様です。また、既存のすべてのクライアントを修正するのは完全な PITA になります。


補足として、マージが必要な分散データベースを持つことがわかっているアプリケーションを構築するときは、ほとんどの場合、単純に GUID を主キーとして使用するのが賢明です。はい、インデックスなどを断片化しますが、この場合、これらの欠点は完全な PITA よりも望ましく、最終的にすべてのデータをマージするときに発生する可能性のあるエラーです。

于 2013-01-05T16:46:38.270 に答える
0

@Chris の 3 番目のオプションに加えて、Sync Framework を使用している場合は、実際にそれを「だまして」、サーバー側の PK 用の列を追加することができます。

参照:パート 1 – クライアントとサーバーのプライマリ キーが異なるアップロード同期

于 2013-01-06T02:56:51.880 に答える