10

私の状況は次のとおりです。

  1. ローカル DB を使用している多数のクライアント アプリケーションがあります (MS SQL、MS Access - 申し訳ありませんが、これはエンタープライズ システムです。レガシーをサポートする必要があります...)
  2. クライアントの傾向については何も知りません。現在は ~10 ですが、1 年で ~100 になる可能性があります。
  3. これらのテーブルからのデータが中央サーバーに送られ、1 つの共通テーブルに配置されます
  4. 既存の (クライアント) データが変更されることがあります - 更新/削除操作を実行する必要があります
  5. GUID (.NET タイプ) を使用したくないSystem.Guid- MS Access で簡単に実装してサポートするのは難しい。その上、それはパフォーマンスに適していません
  6. その共通テーブルで高速検索が必要なので、PK として使用するか、intまたは使用するとよいでしょう。long int

だから、私は欲しい:

  1. 衝突を避けるための固有のもの (PK として使用されます)
  2. うまくいけば、intまたはlong int
  3. 挿入される前にクライアント側で割り当て可能である必要があります

私の現在の解決策は、次の連結からCRCを取得することです。

  • プロセス ID
  • バイオス日付
  • ユーザー名 (文字列、ハードウェア\ユーザー関連データ)
  • DateTime.Now (UNC)

現在、それは私にとってはうまくいきますが、私の目標を達成するためのより良いアプローチがあるでしょうか? コメント、提案、例、またはあなた自身の経験はありますか?

UPDATE : クライアントとサーバー間の同期は定期的なアクションであるため、1 日に 2 ~ 3 回発生する可能性があります (構成変数です)。

4

4 に答える 4

2

複数のテーブルからのデータが 1 つの中央テーブルに送られ、これらのレコードの変更に対処する必要がある場合、中央テーブルの PK として 2 つの列を使用することをお勧めします。1 つの列はクライアントからの ID フィールド (一意ではない) であり、もう 1 つの列はクライアント アプリに割り当てられたクライアント コード (一意ではない) である可能性があります。ID とクライアント コードからの集計が PK になります

このソリューションには、クライアント側のアプリを変更する必要がないという利点があります (おそらく、何らかのセキュリティ対策に使用できる中央サーバーに送信する ID コード)。各クライアントに割り当てられた一元化されたコード テーブル。2 つの数字 (または ID コードの短い文字列) を使用しているため、中央のテーブルでの検索は問題になりません。

于 2012-05-29T21:14:58.100 に答える
1

キーテーブルを実装できます。

基本的に、キーテーブルは、次に使用可能な整数キーという1つのレコードを持つテーブルです。プログラムがキーを生成する必要がある場合、キーテーブルのキーをインクリメントします。これで、以前に使用可能だったキーが予約されました。そのキーを好きなものに割り当てることができ、同じ方法でプルされた他のキーと競合しないことが保証されます。これは、LightSpeedORMがデフォルトでどのように機能するかです。組み込みのID列を使用する場合の利点は、データベースに挿入する前にアイテムIDを割り当てることができるため、すべてのアイテムを一度に挿入する前にアイテムの関係を定義できることです。

競合が心配な場合は、次に使用可能なキーを読み取ってインクリメントする前に、キーテーブルをロック/ロック解除できます。一度に複数のアイテムを挿入する必要があることがわかっている場合は、キーを1回以上ではなく、その分だけインクリメントできます。アプリケーションの将来のある時点で特定の数のキーが必要になると推測している場合は、シーケンシャルキーのブロックを予約し、それらを内部で追跡できます。すべてを割り当てないと、キーが無駄になる可能性がありますが、データベースへの過度の呼び出しは防止されます。

于 2012-05-29T20:40:05.977 に答える
1

数値である PK 列をいつでも追加でき、(使用している DB に応じて) それを処理するためのシーケンスまたは ID をセットアップできます。

検索を高速化するために、現在必要な複数の列にインデックスを作成することもできます。

于 2012-05-29T20:28:44.037 に答える
1

int64 キーを使用するだけです。クライアント側では 0 から負方向に増加する数値 (-1 から開始) を使用し、サーバー側では同期後に正方向に増加する数値を使用します。クライアントからサーバーにデータを同期するときは、新しい正のサーバー側の数値を返します。レコードのキーを更新するのは簡単だと思います。そうでない場合は、古いものを削除して、値を含む新しいものを挿入するだけです。

これは、クライアント側の一意のキーと更新可能なデータを保持するための非常に簡単な方法であり、ソリューションによって引き起こされる問題を実際に心配する必要はありません。

GUID の使用に反対している場合 ( System.Guid.NewGuid() のMSDNは、値の一部としてその MAC アドレスを示し、それらを非常に一意にする)、答えは複合キーです (1 ベースではありません)。複合キーの crc で!); エントロピーが 128 ビット GUID よりも大きい場合を除き、CRC ソリューションは GUID よりも衝突の可能性が低いと考える間違いに陥らないでください。

私が指摘したように、int64 空間には、同期されていない一時的な一意の ID 番号を識別するために使用できる負のスペクトル全体があります。そうすれば、中央サーバーへの書き込み時にクラスター化インデックスの追加の潜在的な利点を得ることができます.

したがって、クライアント側のデータ キーが次のようになっているとします。

-5, -4, 76, 78, 79

つまり、-4 と -5 を中央の場所に挿入し、それらの ID を新しい値に更新する必要があります (この例ではそう80です81)。

GUID の一意性と衝突の可能性についてさらに読みたい場合は、このトピックに関する Eric Lippert の最近のブログ記事を読むことを勧めます。Access 側については、.ToString() だけでテキスト キーに変換できます。しかし、int / int64 空間で機能するソリューションを提供したので、これは必要ありません。

于 2012-05-29T21:07:34.253 に答える