7

この種の質問は以前に行われたことがありますが、私が考えているオプションを比較した質問は見つかりませんでした。なので、ここに投稿します。重複している場合はリンクを投稿してください。

これはかなり長い投稿になりました。時間があれば、質問は最後にありますので、読んでください。

EDIT2:今のところそれが最善の解決策になると思うので、私は答えを受け入れました。しかし、数字の連結についての私の質問に答える他の2つの質問をしたいと思いました。それらはここで見つけることができます:2つの整数を組み合わせて一意の数値を作成し、C#で整数を連結します。番号をエンコードしようとすると(以下の51122222のように)、これは便利だと思います。たぶん、c#でString.Formatのようなものを使用するだけで、私の小さなアプリケーションには十分高速です。

私は現在、同じデータベーススキーマを使用し、他のすべてのデータベースと同期できる1つのマスターデータベースと同期できる分散アプリケーションをセットアップする方法を見つけようとしています。

私が現在計画しているプログラムは、情報を追跡するためのかなり単純なプログラムとして開始されます。最初のバージョンには、ItemsとItemHistoryの2つのテーブルが含まれる場合があります。これは可能なフィールドの例です:

アイテム
ItemID(PK)?
名前文字列
コンテンツ文字列

ItemHistory
ItemHistoryID(PK)?
ItemID(FK)?
EventName String
CreatedOn DateTime

フィールド名とタイプをリストしました。この質問は、PKタイプに何を使用するかについてですので、それらは欠落しています。

最初のバージョンは標準のデスクトップアプリになります。現在、データベースにWPFフロントエンドとSQLiteでC#を使用することを計画しています。最終的には、Androidフォンでも実行できるバージョンを作成したいと思います。これが分散部分の出番です。私は常にシグナルを持っているわけではないので、アプリをオフラインで実行し、再びオンラインになったときに同期できるようにする必要があります。

IDの処理方法についてこれまでに考えたアイデアは次のとおりです。

  1. IDにUUIDを使用して、マージの競合が発生しないようにします
  2. 自動増分フィールドを使用して、アプリの各バージョンの開始番号を一定の増分で設定します。たとえば、最初のアプリの場合は1、2番目の場合は10000、3番目の場合は20000などです。
  3. 数値間の大きなギャップなしで競合を回避するために、オフセット値を持つ自動増分フィールドを使用します(mysqlにはこのためのauto_increment_incrementとauto_increment_offsetがあります)
  4. 各データベースのIDをエンコードする独自のIDを生成して、データベースが独自の自動増分値を持ち、競合を引き起こさないようにします。同じ考えを持っている他の誰かを見つけました:ID列に推奨されるデータ型は何ですか?

オプション1は機能し、過去に使用したことがありますが、UUIDの問題を回避するために他のオプションの可能性を検討したいと思います。デバッグ時に読みやすく、並べ替え可能なソリューションが欲しいです。

オプション2は機能しますが、レコード数に制限を強制します。私の小さなアプリケーションでは、それがそれほど多くなることはほとんどないことを知っていますが、そのような制限を必要としないソリューションがあるかどうかを試してみたいと思います。オプション3は、交互の数字を使用して制限を回避しますが、使用するデータベースの数を知る必要があると思います。そうでない場合は、すべての数字を入力する可能性があります。DB1で1の開始と1の増分を使用し、DB2で2の開始と2の増分を使用すると、すべての数値が交互に使用されます。増分として50を使用することもできますが、別の制限がありますが、それを使用できるアプリケーションの数に制限があります。繰り返しになりますが、私の状況では限界に達することはありませんが、突然非常に人気のあるアプリケーションでは問題になる可能性があることを私は知っています。

オプション4は私にとっては問題を解決できるようですが、実際に機能するかどうかはわかりません。私が持っていたアイデアの1つは、各アプリケーションにプレフィックスを設定できるようにすることでした。これにより、自動インクリメント値で使用できるようになりました。たとえば、PC上のレコードの場合はPC1、PC2、Androidのレコードの場合はPHONE1、PHONE2などです。これは機能しますが、文字列で数値を使用すると、1、11、100が隣り合って表示されるという並べ替えの問題が発生します。つまり、先行ゼロが少なくなり、再び限られた数のレコードに戻ります。

DBIDと自動インクリメントに数字を使用できるかどうか疑問に思いました。たとえば、PC=1およびPHONE=2の場合、PCには11、12、13などがあり、PHONEの11番目のレコードには111、304番目のレコードには2304があります。しかし、これがどのように行われるのか、またはそれが簡単に行われ、値を生成するための過剰なオーバーヘッドを引き起こさないのかどうかはわかりません。

職場では、同様の番号付けシステムを使用しており、この51122222のようなものを使用しています。5は、アプリケーションのインスタンスを参照し、次に2桁の年、最後に自動増分番号を参照します。1年で99999レコードを超えるとどうなるか、まだ明確な答えはありません。彼らはそれが起こらないと考えていたかもしれず、彼らがリスクを計算したことを喜んでいると思います。

最後に質問ですが、並べ替えを可能にし、制限を適用しない分散アプリケーションの主キーシステムを作成する方法はありますか(データ型自体のサイズ(最大整数など)以外)?

編集:これが私が書く予定のアプリに関するもう少しの情報です。取得する可能性のあるほぼすべてのタイプの情報を保存できるものを作成したいと思います。システムには、トピックを検索できるようにエントリにタグを付ける機能が含まれます。私がこれまでに見た情報の種類は、本、DVD、ウェブサイトなどに関する推奨事項である可能性があります。あるいは、私が住んでいる場所に関する地元のヒントかもしれません。全体的なアイデアの1つは、これらの情報をさまざまな形式の複数のコンピューター/ラップトップ/電話に分散させないようにすることです。

4

1 に答える 1

3

大まかに言えば、2つのアプローチがあります。

  1. 順次値を使用します。これらは、グループに分割したり、インターリーブしたりすることができます。これらは最も効率的なアプローチですが、コラボレーションと調整が必要です。

  2. ランダムな値を使用します(これにはUIDが含まれます)。これらははるかに単純ですが、より多くのスペースを必要とします。「誕生日の衝突」から、N個の値を保存する必要がある場合は、ランダムなキーをN * Nの範囲(http://en.wikipedia.org/wiki/Birthday_problem以上)から選択する必要があることがわかっています。逆方向に作業すると、64ビット整数はランダムキーとして使用された場合に約32ビットのデータを保持できます。これは約40億の値です。しかし、それは50%の衝突の可能性のためです。はるかに低い確率が必要なので、実際の制限は約1,000万エントリです。

したがって、簡単に言えば、64ビットキーを使用している場合、ランダムアプローチは約1,000万エントリに対して機能し、シーケンシャルアプローチはさらに多くのエントリに対して機能します。どちらの場合でも、それはおそらくあなたが必要とする以上のものです。

32ビットキーを使用している場合、ランダムアプローチは約1,000の値に対して機能します(上記のように、シーケンシャルアプローチは約40億になります)。

明らかにテキスト値がある場合は、それに応じてこれを変更する必要がありますが、UUIDはとにかく「十分な」値を持つように設計されていますhttp://en.wikipedia.org/wiki/Universally_unique_identifier

通常、データベースはシーケンシャルIDを提供し、必要なのはそれだけです。そうでない場合、64ビットランダムアプローチは通常最も単純で、余分なスペースの価値があります。

于 2011-08-31T16:49:35.190 に答える