2

エンティティのすべてのバージョンを簡単にインデックス付けされた方法で保存する必要があり、使用するシステムについて誰かが入力したかどうか疑問に思っていました。

バージョン管理を行わない場合、システムは、たとえば1人あたりの行を持つ単なるリレーショナルデータベースになります。人の状態が変化すると、その行はこれを反映するように変更されます。バージョン管理では、常に前のバージョンに戻ることができるように、エントリを更新する必要があります。時制データベースを使用できれば、これは無料で、「ダブリンに住んでいて30歳の昨日の午後2時の時点でのすべての人々の状態はどうなっているのか」を尋ねることができます。残念ながら、一時的に実行できる成熟したオープンソースプロジェクトはないようです。

これを行うための本当に厄介な方法は、状態の変化ごとに新しい行を挿入することです。人は多くのフィールドを持つことができますが、更新ごとに1つしか変更されないため、これは重複につながります。また、タイムスタンプが与えられたすべての人に正しいバージョンを選択するのは非常に時間がかかります。

理論的には、リレーショナルデータベースとバージョン管理システムを使用して時制データベースを模倣することは可能であるはずですが、これはかなり恐ろしいことのように聞こえます。

それで、誰かが以前に似たようなものに出くわしたことがあり、彼らがそれにどのようにアプローチしたのか疑問に思いましたか?

更新 Aaronによって提案されたように、これが現在使用しているクエリです(mysqlで)。20万行を超えるテーブルでは、間違いなく低速です。(id =テーブルキー、person_id = 1人あたりのID、その人に多くのリビジョンがある場合は複製)

p.id =の人pから名前を選択します(person_id = p.person_idおよびtimestamp<=:timestampの人からmax(id)を選択します)

更新 これを行うための最良の方法は時制データベースを使用することのように見えますが、オープンソースのものがないことを考えると、次善の方法は更新ごとに新しい行を格納することです。唯一の問題は、変更されていない列の重複と遅いクエリです。

4

2 に答える 2

3

これに取り組むには2つの方法があります。どちらも、常に新しい行を挿入することを前提としています。createdいずれの場合も、行が「変更」されたことを示すタイムスタンプ()を挿入する必要があります。

最初のアプローチでは、数値を使用して、既に持っているインスタンスの数をカウントします。主キーは、オブジェクトキーとバージョン番号です。このアプローチの問題はselect max(version)、変更を加える必要があることのようです。実際には、これが問題になることはめったにありません。アプリからのすべての更新について、最初にその人の現在のバージョンをロードし、それを変更(およびバージョンをインクリメント)してから、新しい行を挿入する必要があるためです。したがって、実際の問題は、この設計により、データベースで更新を実行することが困難になることです(たとえば、多くのユーザーにプロパティを割り当てる)。

次のアプローチでは、データベース内のリンクを使用します。複合キーの代わりに、各オブジェクトに新しいキーを指定するとreplacedBy、次のバージョンのキーを含むフィールドがあります。このアプローチにより、現在のバージョンを簡単に見つけることができます(... where replacedBy is NULL)。ただし、新しい行を挿入して既存の行を更新する必要があるため、更新は問題になります。

これを解決するために、バックポインタ(previousVersion)を追加できます。このようにして、新しい行を挿入してから、戻るポインターを使用して前のバージョンを更新できます。

于 2009-11-10T17:36:49.043 に答える
0

時制データベースに関する文献の(やや古い)調査は次のとおりです。http://citeseerx.ist.psu.edu/viewdoc/download?doi = 10.1.1.91.6988&rep = rep1&type = pdf

これらの参考資料やGoogleScholarに腰を下ろしてデータモデルに適したいくつかの優れた手法を見つけてみることをお勧めします。幸運を!

于 2009-11-10T21:37:33.670 に答える