質問

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

これは以前にも行われたことは知っていますが、この特定のモデルの経験がないだけであることに注意してください。

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

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

この種のシステムを使用した経験はありますか?この問題をどのように解決しましたか?

ありがとう!
ダニエル

役に立ちましたか?

解決

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

注意しなければならないのは、人間が判読できる識別子です。GUID を人間が交換することはできません。GUID の場合、電話で注文番号を確認しようとすることを想像できますか?したがって、オフラインのシナリオでは、引き続き生成する必要がある場合があります。 何か - 発行者 (ワークステーション/ユーザー) ID とシーケンス番号のようなものなので、注文番号は 123-5678 になる可能性があります。

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

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

他のヒント

@SqlMenace

GUID には他にも問題があります。GUID は連続していないため、挿入があちこちに分散され、ページ分割とインデックスの断片化が発生します。

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

クラスター化インデックスが別の列である場合 (「inserted_on」が思い浮かびます)、挿入は順次行われ、ページ分割や過度の断片化は発生しません。

これは GUID の完全に優れた使用法です。唯一の欠点は、INT よりも GUID を操作する際の若干の複雑さと、わずかなサイズの違い (16 バイトと 4 バイト) です。

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

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

GUID には他にも問題があります。GUID は連続していないため、挿入があちこちに分散され、ページ分割とインデックスの断片化が発生します。

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

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

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

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

個人的には、複合キーは外部キーとしては非常に面倒だと思うので、最初のアプローチを好みます。人間が読みやすいという苦情は誇張されていると思います。いずれにせよ、エンドユーザーはキーについて何も知る必要はありません。

必ず guid.comb を利用してください - インデックス作成を処理します。その後、パフォーマンスの問題に対処している場合は、すぐにスケーリングの専門家になるでしょう。

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

ただ、あなたに指摘したいのは、 Sequential Guid は標準 Guid と比べてどのようなパフォーマンスの向上がありますか?, 、GUID の話について説明します。

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

ただし、個人的には SGUID の答えが気に入っています。

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

GUID を使用すると、一連の問題全体が簡素化されますが、その代償としてパフォーマンスとデバッグ性が犠牲になります。テスト クエリに GUID を入力すると、すぐに古くなってしまいます。

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

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

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

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

@サイモン、

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

これを実現するには、SQL Server Compact Edition を検討してみます。あらゆる問題の解決に役立ちます。

SQL Server 2005 Compact Edition を使用したデータ ストレージ アーキテクチャ

のために特別に設計されています

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

ユーザーは、バックエンドネットワークから切断されている間、クライアントの場所、道路、空港、自宅からのサイトから切断されている間、ジョブ機能を実行できるようにします。

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

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

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

MS が ADO​​ レコードセット モデルを現在の DataSet モデルに変更し、オフラインでも問題なく動作するようにしたと読んだ気がします。そして、これもあります ADO.NET の同期サービス

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

お役に立てれば。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top