2

スキーマが変更されやすいかなり複雑なリレーショナル データベースの監査証跡を実装しようとしています。私が考えている 1 つの方法は、DVCS を使用して変更を追跡することです。

(私が想像できる利点は、スキーマレスな履歴、システム全体の状態のスナップショット、分析、再生、および移行のための標準ツール、効率的なストレージ、別のシステム、DB をきれいに保つことです。データベースは書き込み負荷が高くなく、履歴はコアではありません。監査証跡を残すためのものです.ああ、私は問題に対してクレイジーな新しいアプローチを試すのが好きです.)

私はこれらのシステムの専門家ではない (基本的な git の知識しかない) ため、実装がどれほど難しいかはわかりません。Mercurial のアプローチを採用することを考えていますが、実際のファイルを使用するのではなく、ファイルの内容/マニフェスト/変更セットをキーと値のデータ ストアに格納する可能性があります。

データ行はjsonにシリアル化され、各「ファイル」は行になる可能性があります。または、テーブル全体を「ファイル」に格納し、各行を主キーに等しい行番号に格納することもできます (テーブルが大きすぎないと仮定すると、すべての行が 4000 行未満になると予想されます。これは、テーブル「ファイル」の残りの部分を調べなくても、変更セットが自動的に生成される可能性があることを意味する場合があります。

(しかし、ファイル全体の SHA-1 ハッシュが必要だと思うので、私はそれを疑っています。ファイルはおそらく予測可能な行数で分割される可能性があります。たとえば0 < primary key < 1000、ファイル 1、1000 < primary key < 2000ファイル 2 などで、それらを小さく保ちます)

このようなアプローチについてコメントできる一般的な DVCS の内部またはデータ構造に精通している人はいますか? どうすればそれを機能させることができますか? また、そもそも実行する必要がありますか?

このようなシステムには 2 つの側面があると思います。1) SQL データを DVCS システムにマッピングし、2) DVCS データをキー/値データ ストア (ファイルではない) に格納して効率を高めます。

(NB json シリアライゼーション ビットは私の ORM でカバーされています)

4

3 に答える 3

2

私はこれを自分で少し調べました。共有するコメントがいくつかあります。

Python から mercurial を使用すると作業が簡単になると思っていましたが、DVCS には不要な機能 (特に分岐、マージ) がたくさんあります。単純にいくつかの設計上の決定を盗み、自分のニーズに合った基本的なシステムを実装する方が簡単だと思います. それで、ここに私が思いついたものがあります。

ブロブ

システムは、アーカイブされるレコードの json 表現を作成し、これの SHA-1 ハッシュ (必要に応じて「ノード ID」) を生成します。このハッシュは、特定の時点でのそのレコードの状態を表し、git の「blob」と同じです。

変更セット

変更は変更セットにグループ化されます。変更セットは、いくつかのメタデータ (タイムスタンプ、コミッターなど) を記録し、親変更セットと現在の「ツリー」にリンクします。

Mercurial の「マニフェスト」アプローチを使用する代わりに、git の「ツリー」構造を採用しました。ツリーは、単なるブロブ (モデル インスタンス) または他のツリーのリストです。最上位では、各データベース テーブルが独自のツリーを取得します。次のレベルはすべてのレコードです。多くのレコードがある場合 (多くの場合あります)、それらをサブツリーに分割できます。

これを行うと、レコードを 1 つだけ変更すると、ツリーはそのままにしておくことができます。また、各レコードが独自の BLOB を持つことができるため、管理がはるかに簡単になります。

保管所

Mercurial の revlog のアイデアが気に入っています。これにより、データ ストレージを最小限に抑え (変更セットのみを保存する)、同時にすばやく取得できる (すべての変更セットが同じデータ構造にある) ためです。これはレコード単位で行われます。

MongoDB のようなシステムがデータの保存に最適だと思います (キーと値である必要があり、Redis はすべてをメモリに保持することに集中しすぎていると思いますが、これはアーカイブにとって重要ではありません)。変更セット、ツリー、revlog を保存します。現在のHEADなどにいくつかの追加のキーを追加して、システムは完成です。

ツリーを使用しているため、参照している正確な "blob" に外部キーを明示的にリンクする必要はないでしょう。主キーを使用するだけで十分です。私は願います!

ユースケース: 1. 変更のアーカイブ

変更が行われるとすぐに、レコードの現在の状態が json にシリアル化され、その状態のハッシュが生成されます。これは、他のすべての関連する変更に対して行われ、変更セットにパッケージ化されます。完了すると、関連する revlog が更新され、新しいツリーとサブツリーが新しいオブジェクト (「ブロブ」) ハッシュで生成され、変更セットがメタ情報で「コミット」されます。

ユースケース 2. 古い状態の取得

関連する変更セットを見つけた後 (MongoDB 検索?)、探している BLOB ID が見つかるまでツリーをトラバースします。revlog に移動して、レコードの状態を取得するか、利用可能なスナップショットと変更セットを使用して生成します。次に、ユーザーは外部キーも取得する必要があるかどうかを決定する必要がありますが、それは簡単です (最初に使用したのと同じチェンジセットを使用します)。

概要

これらの操作はどれもコストがかかりすぎるべきではなく、データベースへのすべての変更をスペース効率よく記述できます。アーカイブは本番データベースとは別に保持されるため、本番データベースでの作業が可能になり、データベース スキーマへの変更を時間の経過とともに行うことができます。

于 2011-06-18T13:55:24.043 に答える
0

データベースが (あなたの言うように) 書き込み負荷が高くない場合、目標を達成する方法で実際のデータベース テーブルを実装してみませんか? たとえば、「バージョン」列を追加します。次に、この特別な列を除いて、行を更新または削除しないでください。これは、NULL に設定して「現在」を意味し、1 に設定して「最も古い既知」を意味し、そこから上に移動できます。行を更新する場合は、そのバージョンを 1 つ上のバージョンに設定し、バージョンのない新しい行を挿入します。次に、クエリを実行するときに、空のバージョンの行を選択するだけです。

于 2011-06-17T02:03:03.770 に答える
0

cqrs と Greg Young のイベントソーシングを見てください。また、ビジネス イベントの川の中でスキーマの変更点を特定するメタ イベントでの作業についてのブログ投稿もあります。

http://adventuresinagile.blogspot.com/2009/09/rewind-button-for-your-application.html

私のブログを見ると、バージョン スクリプト スキームも見つかり、それらをソース コードで管理できます。

于 2011-06-17T06:12:40.350 に答える