20

知識を広げるために、さまざまなNoSQLオプションを検討し始めました。私が最初に訪れたのはRavenDBで、面白そうです。私はまだ、典型的なRDBMSメンテナンスルーチンとともに、根深い関係の考え方を打ち破ろうとしています。

Entity Frameworkを日常的に扱っているので、DBの変更のスクリプトを作成したり、EFマッピングモデルを更新したりするルーチンを実行します。NoSQL、特にRavenDBではどのように機能しますか?アプリが機能しなくなったら、さまざまなPOCOオブジェクトなどに変更を加えて、本番環境にデプロイするにはどうすればよいでしょうか。古いPOCOクラスに保存されているデータはどうなりますか?

私はまだ深く掘り下げたり、RavenDBを怒りで使用したりしていません。これは一度やれば明らかかもしれませんが、事前に知りたいので、自分自身を隅に追いやることはしません。

ありがとう。

4

4 に答える 4

28

それらはそのままです-もう存在しないプロパティはロード時に無視され(そして変更時に失われ)、欠落しているプロパティはnullとして返されます。

セットベースの操作を使用して、データをオブジェクトモデルとチェックすることをお勧めします。

ああ、私を見てください、私は今コンピューターを使っています!

基本的に、ドキュメントストアに移動すると、一部の機能が失われ、データベースに事前のスキーマが定義されており、そのスキーマと一致しないデータをアップロードしようとすると、ある程度の自由が得られることを認識できます。エラーが発生します。

ただし、ドキュメントにはすべて独自の構造(プロパティ名とプロパティ値を示すキーと値のペア)が含まれているという点で、スキーマレスと構造レスには違いがあることを認識することが重要です。

これは、コードを記述してデータを永続化するという「ただ乗り込む」要素全体に役立ちますが、コード構造の変更を簡単に回避できる場合は、すでに永続化されているデータとの調整が難しくなる可能性があります。

この時点で、いくつかの戦略が提示されます。

  • データを永続化したら、構造を不変にし、クラスをバージョン管理します
  • 構造の変更を許可しますが、セットベースの操作を使用して、新しい構造に一致するようにデータを更新します
  • 構造の変更を許可し、データをロードする際の不整合に対処するためのコードを記述します

3つ目は、保守不可能なコードにつながるため、明らかに悪い考えです。イベントやその他のデータを保存しているだけの場合は、クラスのバージョン管理は機能しますが、ほとんどのシナリオにはあまり適していないため、真ん中のままです。オプション。

まさにそれを実行し、リレーショナルデータベースで先行スキーマを処理するときに従うのと同じ行に沿っていくつかの簡単なルールに従うことをお勧めします。

  • VCSシステムを使用して、デプロイされたバージョン間の変更を判別します
  • あるバージョンから別のバージョンにアップグレードする移行スクリプトを作成する
  • プロパティの名前変更/削除に注意してください-ドキュメントを読み込んで保存すると、それらのプロパティが新しいドキュメントに存在しない場合、データが失われるためです。

等。

これがもっと役立つことを願っています:-)

于 2011-01-23T22:12:30.867 に答える
3

RavenDBは、.NETオブジェクトをJSON形式にシリアル化します。スキーマはありません。

データベースにいくつかのオブジェクトを追加すると、それらはシリアル化されます。シリアル化するタイプにいくつかのプロパティを追加すると、すでに保存されているオブジェクトにはそれらのプロパティが失われます。

于 2011-01-23T22:13:06.373 に答える
3

Ayendeによるこの記事では、1からバージョン2への移行を実行する方法について説明します(この場合、「Name」プロパティを「FirstName」および「LastName」プロパティに変更します。

http://ayende.com/blog/66563/ravendb-migrations-rolling-updates

基本的に、リスナーはDocumentStoreに登録されます。

documentStore.RegisterListener(new CustomerVersion1ToVersion2Converter())

上記の記事から抜粋した実装例:

public class CustomerVersion1ToVersion2Converter : IDocumentConversionListener
{
    public void EntityToDocument(object entity, RavenJObject document, RavenJObject metadata)
    {
        Customer c = entity as Customer;
        if (c == null)
            return;

        metadata["Customer-Schema-Version"] = 2;
        // preserve the old Name property, for now.
        document["Name"] = c.FirstName + " " + c.LastName;
        document["Email"] = c.CustomerEmail;
    }

    public void DocumentToEntity(object entity, RavenJObject document, RavenJObject metadata)
    {
        Customer c = entity as Customer;
        if (c == null)
            return;
        if (metadata.Value<int>("Customer-Schema-Version") >= 2)
            return;

        c.FirstName = document.Value<string>("Name").Split().First();
        c.LastName = document.Value<string>("Name").Split().Last();
        c.CustomerEmail = document.Value<string>("Email");
    }
}
于 2013-12-18T10:57:47.750 に答える
2

コードに移動するほどスキーマ管理がないため、コード内のオブジェクトとデータベース内のオブジェクトの間に不一致が生じることはありません。

変更の処理の最初の部分は、欠落/余分な値を処理できるシリアライザーを使用することを確認することです。フィールドがデータで定義されていない場合は、nullに設定します。データのフィールドがオブジェクトのプロパティと一致しない場合は、無視してください。

ほとんどの変更はそれ以上のことなしに処理できます-新しいフィールドがあり、とにかく既存のレコードのデフォルト値が必要であるか、またはもう気にしない古いフィールドがあります。

フィールドの名前変更/結合やデータ形式の変更などのより複雑な変更については、古いフィールドを削除せずにオブジェクトに新しいフィールドを追加し、loadメソッドに古いフィールドからデータを転送させます。レコードを保存すると、新しい形式になります。このコードは、永続的にそのままにして、必要に応じてデータを更新するか、既存のすべてのオブジェクトに対して同じコードを呼び出す1回限りのプロセスを設定できます。コードは新旧両方の形式を処理できるため、SQLスクリプトとは異なり、大規模なデータセットでの実行に長い時間がかかる場合でも、このタイプの更新にダウンタイムは必要ありません。

于 2011-01-24T00:55:52.117 に答える