5

私たちは通常OLTP(購入システムを考えてください)であるアプリケーションの設計に取り組んでいます。ただし、これは特に一部のユーザーがオフラインになる必要があるため、ユーザーはDBを自分のマシンにダウンロードして作業し、LANに接続したら同期し直す必要があります。

私はこれが以前に行われたことを知っていることに注意したいのですが、私はこの特定のモデルの経験がありません。

私が考えたアイデアの1つは、GUIDをテーブルキーとして使用することでした。したがって、たとえば、発注書には番号(自動数値)ではなくGUIDが含まれるため、すべてのオフラインクライアントがそれらを生成でき、DBに接続し直したときに衝突が発生することはありません。

これは何らかの理由で悪い考えですか?GUIDキーを介したこれらのテーブルへのアクセスは遅くなりますか?

これらのタイプのシステムの経験はありますか?この問題をどのように解決しましたか?

ありがとう!
ダニエル

4

15 に答える 15

8

Guidを主キーとして使用することは許容され、それらを検討しているのと同じ理由で、かなり標準的な方法と見なされます。それらは使いすぎてデバッグや管理が少し面倒になる可能性があるため、可能な限りコードテーブルやその他の参照データから除外するようにしてください。

自分で気にする必要があるのは、人間が読める形式の識別子です。GUIDを他の人が交換することはできません-GUIDの場合、電話で注文番号を確認しようとすることを想像できますか?したがって、オフラインシナリオでも、発行元(ワークステーション/ユーザー)IDやシーケンス番号などを生成する必要がある場合があるため、注文番号は123-5678になる可能性があります

ただし、これは連番を持つというビジネス要件を満たさない場合があります。実際、規制要件は影響を与える可能性があり、影響を与える可能性があります。一部の規制(SOXの場合もあります)では、請求書番号が連続している必要があります。このような場合、システムが同期するときに後で修正される一種のプロフォーマ番号を生成する必要がある場合があります。OrderId(Guid)、OrderNo(int)、ProformaOrderNo(varchar)を持つテーブルにたどり着く可能性があります-ある程度の複雑さが忍び寄る可能性があります。

少なくとも主キーとしてGUIDを使用するということは、同期が最終的に行われるときに、カスケード更新を大量に行う必要がないことを意味します。つまり、人間が読める形式の数値を更新するだけです。

于 2008-09-02T18:56:50.063 に答える
3

@SqlMenace

GUIDには他にも問題があります。GUIDがシーケンシャルではないため、挿入がいたるところに散らばり、ページの分割やインデックスの断片化が発生します。

違います。主キー!=クラスター化インデックス。

クラスタ化インデックスが別の列である場合(「inserted_on」が頭に浮かぶ)、挿入はシーケンシャルになり、ページ分割や過度の断片化は発生しません。

于 2008-09-03T02:14:23.600 に答える
2

これは、GUIDの完全に適切な使用法です。唯一の欠点は、INTを介したGUIDの操作のわずかな複雑さと、わずかなサイズの違い(16バイトと4バイト)です。

どちらも大したことではないと思います。

于 2008-09-02T18:41:55.297 に答える
1

これは古い問題であり、2つの標準的な解決策があります。

  • 主キーとして一意の識別子を使用します。読みやすさが気になる場合は、GUIDを使用する代わりに、独自の一意の識別子を使用できることに注意してください。一意の識別子は、日付とマシンに関する情報を使用して一意の値を生成します。

  • 'Actor'+識別子の複合キーを使用します。すべてのユーザーは数値のアクターIDを取得し、新しく挿入された行のキーは、アクターIDと次に使用可能な識別子を使用します。したがって、2人のアクターが両方ともID「100」の新しい行を挿入した場合、主キーの制約に違反することはありません。

個人的には、複合キーは外部キーとして本当に退屈だと思うので、最初のアプローチを好みます。人間の可読性に関する苦情は誇張されていると思います。とにかく、エンドユーザーはあなたのキーについて何も知る必要はありません。

于 2008-09-03T02:21:22.943 に答える
1

必ずguid.combを利用してください-インデックス作成を担当します。その後、パフォーマンスの問題に対処する場合は、簡単に言えば、スケーリングの専門家になります。

GUIDを使用するもう1つの理由は、データベースのリファクタリングを有効にすることです。ポリモーフィズムや継承などをCustomersエンティティに適用することにしたとします。ここで、顧客と従業員がPersonから派生し、テーブルを共有するようにします。本当に一意の識別子があると、データの移行が簡単になります。戦うシーケンスや整数IDフィールドはありません。

于 2008-09-03T02:25:53.247 に答える
1

GUIDキーを介したこれらのテーブルへのアクセスは遅くなりますか?

GUIDには他にも問題があります。GUIDがシーケンシャルではないため、挿入がいたるところに散らばり、ページの分割やインデックスの断片化が発生します。

SQL Server 2005では、MSがこれを修正するためにNEWSEQUENTIALID()を導入しました。唯一の問題は、テーブルのデフォルト値としてNEWSEQUENTIALIDしか使用できないことです。

于 2008-09-02T18:54:46.963 に答える
1

標準Guidに対する Sequential Guid のパフォーマンスの向上は何ですか? で、GUID の話が取り上げられています。

人間が読みやすいように、マシン ID を割り当ててから、可能性としてそれらのマシンの連続番号を使用することを検討してください。ただし、これにはマシン ID の割り当てを管理する必要があります。1 つまたは 2 つの列で実行できます。

ただし、個人的には SGUID の回答が好きです。

于 2009-08-19T16:52:40.460 に答える
0

@Portmanデフォルトでは、PK ==クラスター化インデックスです。主キー制約を作成すると、クラスター化インデックスが自動的に作成されます。クラスター化したくない場合は、非クラスター化を指定する必要があります。

于 2008-09-03T02:24:41.313 に答える
0

GUIDは確かに標準の整数キーよりも遅くなります(そしてより多くのメモリを使用します)が、それが問題になるかどうかは、システムに表示される負荷の種類によって異なります。バックエンドDBによっては、GUIDフィールドのインデックス作成に問題がある場合があります。

GUIDを使用すると、問題のクラス全体が単純化されますが、パフォーマンスとデバッグ可能性の一部を支払う必要があります。これらのテストクエリにGUIDを入力すると、非常に早く古くなります。

于 2008-09-02T18:41:09.197 に答える
0

バックエンドはSQLServer2005フロントエンドになります
/アプリケーションロジックは.Netになります

GUIDの他に、オフラインコンピューターが新しいデータを中央データベースに同期するときに発生する「マージ」を解決する他の方法を考えられますか?
つまり、キーがINTの場合、基本的にインポートするときにすべての番号を付け直す必要があります。GUIDはそれを免れます。

于 2008-09-02T18:47:31.990 に答える
0

GUIDを使用すると、2つのデータベースを1つにマージする必要があるときに多くの作業を節約できました。

于 2008-09-02T18:48:23.907 に答える
0

データベースがラップトップにダウンロードしてオフラインで操作できるほど小さい場合は、intとGuidのパフォーマンスの違いについてあまり心配する必要はありません。ただし、システムの開発とトラブルシューティングを行うときに、intがどれほど役立つかを過小評価しないでください。Guidを使用しているかどうかに関係なく、かなり複雑なインポート/同期ロジックを考え出す必要があるため、Guidは思ったほど役に立たない可能性があります。

于 2008-09-02T18:51:23.167 に答える
0

@サイモン、

あなたは非常に良い点を挙げています。オフライン中に生成し、同期時に再作成する「一時的な」「人間が読み取れる」数値についてはすでに考えていました。しかし、外部キーなどを使用することは避けたかった.

于 2008-09-02T19:54:19.613 に答える
0

これについては、SQL Server Compact Edition を検討し始めます。それはあなたの問題のすべてに役立ちます。

SQL Server 2005 Compact Edition のデータ ストレージ アーキテクチャ

それは特別に設計された

フィールド フォース アプリケーション (FFA)。FFA は通常、次の属性の 1 つ以上を共有します。

これにより、ユーザーは、バックエンド ネットワークから切断されている間 (クライアントの場所、移動中、空港、または自宅など) でジョブ機能を実行できます。

通常、FFA は一時的な接続用に設計されています。つまり、ユーザーがクライアント アプリケーションを実行しているときは、いかなる種類のネットワーク接続も必要ありません。FFA には、接続モードと非接続モードの両方で、バックエンド データベースのデータに同時にアクセスして使用できる複数のクライアントが関与することがよくあります。

FFA は、オフライン サポートのために、バックエンド データベースからクライアント データベースにデータを複製できる必要があります。また、アプリケーションがネットワークに接続できるときに、変更、追加、または削除されたデータ レコードをクライアントからサーバーに複製できる必要があります。

于 2008-09-02T20:01:57.863 に答える
0

頭に浮かぶ最初の考え: MS は、このようなシナリオをサポートするために DataSet および DataAdapter モデルを設計していませんか?

私は、MS が ADO​​ レコードセット モデルを現在の DataSet モデルに変更したため、オフラインでもうまく機能することを読んだと思います。また、このSync Services for ADO.NETもあります。

外部キーも使用する DataSet モデルを利用するコードを見たことがあると思いますが、DataAdapter を使用すると完全に同期します。ただし、同期サービスを試したことはありませんが、それからも恩恵を受けることができると思います.

お役に立てれば。

于 2008-09-02T20:06:43.047 に答える