3

まともなサイズのオブジェクト指向アプリケーションがあります。アプリ内のオブジェクトが変更されるたびに、オブジェクトの変更が DB に保存されます。しかし、これは理想的とは言えません。

現在、トランザクションはトランザクションと一連の transactionLI として保存されます。

transaction テーブルには、who、what、when、why、foreignKey、foreignTable のフィールドがあります。最初の 4 つは自明です。ForeignKey とforeignTable は、変更されたオブジェクトを特定するために使用されます。

TransactionLI には、timestamp、key、val、oldVal、および transactionID があります。これは基本的にキー/値/oldValue ストレージ システムです。

問題は、これら 2 つのテーブルがアプリケーション内のすべてのオブジェクトに使用されるため、かなり大きなテーブルになっていることです。それらを何かに使用するのは遅いです。インデックスは非常に役立ちます。

そのため、このようなことを行う別の方法を考えています。これまでに検討したこと: - これらのテーブルをタイムスタンプのようなものでシャーディングします。- 2 つのテーブルを非正規化して 1 つにマージします。- 上記の 2 つの組み合わせ。- 変更後に各オブジェクトをシリアル化し、subversion に格納するという行に沿って何かを行う。- おそらく他の何かですが、今は思いつきません。

全体的な問題は、トランザクション データを適切に格納および検索するための何らかのメカニズムが必要なことです。ええ、それをリレーショナル データベースに強制的にフィードすることはできますが、実際には、これはトランザクション データであり、それに応じて保存する必要があります。

他のみんなは何をしているの?

4

4 に答える 4

0

特定のアプリケーションの特性に応じて、エンティティ自体のリビジョンを、リビジョンごとに誰が、何を、なぜ、いつと一緒に、それぞれのテーブルに保持するという代替アプローチがあります。誰が、何を、いつ、外部キーにすることができます。

このアプローチは、エンティティ/エンティティ タイプごとの変更量が比較的少ないアプリケーションでしか実行できないため、慎重に使用します。

于 2008-11-06T15:47:12.493 に答える
0

この種の問題に対する優れた最終的な解決策を見つけたことはありません。DBがパーティショニングをサポートしている場合(または、同じ概念を自分で実装できない場合でも)試すことができるいくつかのことですが、このログテーブルをオブジェクトタイプでパーティショニングし、日付/時刻または別の方法でさらにパーティショニングできますオブジェクト ID (ID が数値の場合、これはうまく機能し、GUID がどのように分割されるかわかりません)。

これにより、テーブルのサイズを維持し、関連するすべてのトランザクションをオブジェクトの単一のインスタンスに保持できます。

検討できるアイデアの 1 つは、各フィールドを名前と値のペア テーブルに格納する代わりに、データを BLOB (テキストまたはバイナリ) として格納することです。たとえば、オブジェクトを Xml にシリアル化し、フィールドに格納します。

これの欠点は、オブジェクトが変更されると、これがすべての履歴データにどのように影響するかを考慮する必要があることです。Xml を使用している場合、履歴の xml 構造を更新する簡単な方法があります。バイナリを使用している場合、方法はありますが、より意識する必要があります。努力の。

私はかなり複雑なオブジェクト モデルを blob として格納することに成功しました (.net の xml シリアライザーはオブジェクト間の関係を処理しませんでした)。バイナリ データを格納している自分を簡単に確認できました。バイナリデータとして保存することの大きな欠点は、MSSQL などの最新のデータベースを使用してデータにアクセスできる場合、Xml を使用してデータベースからデータを取得する必要があることです。

最後のアプローチの 1 つは、2 つのパターンを分割することです。差分スキーマを定義できます (一度に複数のプロパティが変更されると想定しています)。たとえば、次の xml を保存することを想像してください。

<objectDiff>
<field name="firstName" newValue="Josh" oldValue="joshua"/>
<field name="lastName" newValue="Box" oldValue="boxer"/>
</objectDiff>

これにより、行数が軽減されます。また、MSSQL を使用している場合は、XML スキーマを定義して、オブジェクトに関する豊富なクエリ機能を利用できます。テーブルを分割することもできます。

ジョシュ

于 2008-11-06T15:04:54.343 に答える
0

データのクエリが重要な場合、SQL Server のエンタープライズ エディションを使用している場合は、SQL Server 2005 以降で true Partitioning を使用します。年ごとに分割された何百万もの行が、当月の日付まであります。最大 1000 個のパーティションで、アプリケーションの要求に合わせて細分することができます。

または、SQL 2008 を使用している場合は、フィルター処理されたインデックスを調べることができます。

これらは、データのクエリに必要なパフォーマンスを提供しながら、単純化された構造を維持できるようにするソリューションです。

古い変更を分割/アーカイブすることは、明らかに検討する必要があります。

于 2008-12-05T10:37:29.907 に答える