CRUD以外のアプローチの例はありますか?


14

私はプログラマーですが、アーキビストとしても働いています。アーキビストとして、データを保持することが重要です。

データの操作に関しては、同僚と議論することがよくあります。CRUDのUとDはあまり好きではありません。レコードを更新するのではなく、新しいレコードを追加して、古いレコードへの参照を作成することをお勧めします。そのようにして、変更の履歴を作成します。また、レコードを削除するのも嫌いですが、非アクティブとしてマークします。

これに用語はありますか?基本的にデータの作成と読み取りのみですか?このアプローチの例はありますか?


1
Is there a term for this? Basically only creating and reading data?確かにあります:CR; P
ヤニス

7
ユーザーの観点から見ると、それはまだCRUDです。私はその実装スタイルの特定のラベルを認識していませんが、多くのアプリケーションで一般的だと思います。(スタック交換は良い例です...)
マークE.ヘイス


+1ある時点で、誰かがレポートを必要とし、存在しない「更新」されたために存在しないデータに関するレポートを作成することは非常に困難です。あなたのアプローチはとても前向きだと思います。
チャックコンウェイ

2
ダトミックに関する講演もご覧ください:infoq.com/presentations/The-Design-of-Datomic
Marjan Venema

回答:


16

レコードを削除済みとしてマークすることは、ソフト削除と呼ばれます。更新のための代替フレーズは聞いたことがありませんが、それは古いレコードをソフト削除して新しいレコードを作成する原因になると思います。

これは議論の余地のある手法であることに注意してください。リンク:Con vs Proをご覧ください。


11

変更履歴を保持する際の問題の1つは、データベースが乱雑になり、サイズが劇的に増加する可能性があることです(使用パターンによって異なります)。そのため、監査証跡を別の場所に保存し、実際のアプリケーションテーブルに関連データのみを格納することをお勧めします。したがって、CRUD操作がアプリケーションによって実行されるたびに、変更が監査テーブルに記録され、CRUD操作がアプリケーションテーブルに対して実行されます(ソフト削除は行われません)。

監査証跡を分離しておくことにより、アプリケーションとやり取りするための元のデータストアが提供されますが、必要に応じて変更履歴を保持します。また、ビジネス要件に応じて、監査証跡を個別にアーカイブしたり、破棄したりすることもできます。


3
この。また、参照整合性は悪夢になります。「削除済みとマークされていないこの一意でないキーを持つこのテーブルの1つのレコード」に外部キーを指定することはできません。この問題を回避するには、この「作業用コピー」を新しいデータで更新する前に、別のテーブルに更新されるレコードのコピーのデータを永続化しますが、それでも大量のデータを処理する必要があります。
キース

5

EventSourcingは、あなたが探しているパターンのように聞こえます。

の色を追跡したい単純な「car」オブジェクトを使用して例を見てみましょう(疑似C#コードが続きます)。

public class Car {
  public string Color { get; set; }
  public Car() { this.Color = "Blue"; }
}

CRUD実装では、車の色を更新すると、以前の色が失われます。

MyCar.Color = "Red";
MyCar.Save();  // Persist the update to the database and lose the previous data

この情報の損失は、あなたが最も避けたいもののように聞こえます(したがって、CRUDパターンの一部を更新および削除することが嫌いです)。

変更を更新するときに代わりにイベントに応答するようにcarクラスを書き直すと、次のようになります。

public class Car {
    public string Color { get; private set; } // Cannot be set from outside the class

    public void ApplyEvent(CarColorChangedEvent e) {
      this.Color = e.Color;
    }
}

次に、このオブジェクトの色をどのように更新しますか?CarColorChangedイベントを作成できます!

var evnt = new CarColorChangedEvent("Red");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

実際のモデルオブジェクトに保存がないことに注意してください。これは、モデルを直接永続化する代わりに、モデルを現在の状態にするイベントを永続化するためです。これらのイベントは不変である必要があります。

早送りして、色をさらに数回変更しましょう。

var evnt = new CarColorChangedEvent("Green");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

var evnt = new CarColorChangedEvent("Purple");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

イベントストレージ(リレーションデータベース、ファイルベースなど)を見ると、自動車オブジェクトに関連する一連のイベントが表示されます。

CarColorChangedEvent => Red
CarColorChangedEvent => Green
CarColorChangedEvent => Purple

その自動車オブジェクトを再構築したい場合は、新しい自動車オブジェクトを作成し、イベントストアからのイベントをそのオブジェクトに適用するだけで再構築できます。

var MyCar = new Car();
var events = MyDatabase.SelectEventsForCar("CarIdentifierHere");
foreach(var e in events) {
  MyCar.ApplyEvent(e);
}
Console.WriteLine(MyCar.Color); // Purple

イベントのストリームを使用して、新しい自動車オブジェクトを作成し、必要なイベントのみを適用するだけで、自動車の状態を前の期間にロールバックできます。

var MyCar = new Car();
var event = MyDatabase.GetFirstEventForCar("CarIdentifierHere");
MyCar.ApplyEvent(e);
Console.WriteLine(MyCar.Color); // Red

5

イベントソーシングは今後の方法であり、グレッグヤングがそれについて何と言っているかを確認する必要があります。

http://goodenoughsoftware.net/

彼のデータベース(イベントストア)でこのプレゼンテーションをご覧ください。他のビデオも見つけることができます。

http://oredev.org/2012/sessions/a-deep-look-into-the-event-store

削除されたアイテムを検索できるようにする必要がある場合を除き、「ソフト削除」の回答は求めませんが、削除されたアイテムではなく、アーカイブされたアイテムと考える必要はありません。ここでは用語が非常に重要だと思います。

「バージョンテーブル」も維持したくないでしょう。私が今まで見たすべての「バージョンテーブル」(現時点でクリーンアップしようとしているものを含む-バグのために7年間のデータが破損しています...履歴データがあるにもかかわらずそれを戻す方法はありません。)これは同じように破損しているためコードのバグが原因で破損し、最終的には、破損が台無しになったデータに戻って再作成できないため、データが失われます。

イベントソーシングモデルでは、これは当てはまりません。ユーザーがしたことをいつでも正確に再生できます。これは、CRUDとイベントソーシングの非常に重要な違いです。イベントソーシングアーキテクチャは、データオブジェクトやドメインモデルオブジェクトではなく、イベントをイベントストアに保存します。イベントは、複数のオブジェクトに簡単に影響を与える可能性があります。ショッピングカート内の各商品を実際の注文に変換するショッピングカートソリューションを考えてみてください。1つのイベントは、注文オブジェクトに変換されるショッピングカートオブジェクトだけでなく、すべてのアイテムオブジェクトに影響を与えます。

データベース内のすべてのテーブルの各行のバージョン付きコピーを保持している場合、そのバージョンテーブルを維持する際の非常に多くのスペースとパフォーマンスオーバーヘッドは言うまでもなく、特定のタイムスタンプまで巻き戻さなければならないという恐怖を想像してください。

イベントソーシングを使用すると、特定の時点までイベントを再生するだけで、簡単に巻き戻すことができます。スナップショットを使用して早送りを行うことができますが、それはすべて実装の問題です。

しかし、私があなたが好きだと思う本当の利点は、データを失わないことに特に興味があるので、このデータを保存するコードのバグを発見した場合、戻ってデータをクリーンアップする必要がないことです(データはほとんど完全ではないため、これは多くの場合不可能です)。代わりに、バグを修正して、すべてのイベントを再生します。その後、適切なデータが格納されたデータベースが作成されます。

デバッグの場合、ユーザーに何をしたかをどのくらい頻繁に尋ねましたか...なぜ彼らがしたことを再生してからコードをステップスルーするだけではありません!かなり気の利いたハァッ。

お役に立てれば。


2

正確な例ではありませんが、古い金融システムではWORMストレージがありました。「更新」する必要がある場合、新しいレコードを作成し、最後のレコードを常に最新として参照しましたが、コミットされたデータは上書きできません。

多くの人がそのアイデアを後のシステムに持ち込みました。WORMテーブルと呼ばれるあなたの説明を聞いたことがありますが、それはそれらのサークルでのみです。


2

はい、エンタープライズシステムでは一般的に2つのアプローチがあります。

  • すべてのレコードに有効な開始タイムスタンプと有効なタイムスタンプが含まれる「bi-時間的」(有効な終了日が「永久」-「null」、「9999-12-31」またはそのような高い値を持つ「現在の」レコード)。代わりに、レコードは削除されず、「有効」日付が現在の時刻に設定され、更新の場合、現在の時刻の有効な開始日と永久に有効な新しいレコードが挿入されます。
  • 「履歴テーブル」-レコードが変更されるたびに、古いレコードのコピーがイベントのタイムスタンプとともに履歴/ログテーブルにダンプされます。

両方のアプローチの粒度には大きなばらつきがあります。たとえば、注文アイテムのウィジェットの数量が変更された場合、注文全体またはその1つのアイテムのみの履歴を保持しますか?

一般的に、「バイテンポラル」は多くの余分な作業であり、「監査人が12月31日の時点で注文ステータスを取得する」などのユースケースが多い場合にのみ価値があります。



-2

基本的には、これらの4つのことなしにはクラッドを完成できません。Crudとは、作成、読み取り、更新、削除を意味するため、データの読み取りのみを行う場合は、そのための簡単なクエリを使用できますが、これら3つのすべては、データベースの単純な概念に関連付けられています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.