1

現在開発中のプロジェクトでRavenDBを使用しているため、まだユーザーがいません。私のバックグラウンドは、このプロジェクトまで常にリレーショナルデータベースでしたが、一般的にはNoSQLアプローチの方がはるかに好きです。ただし、トラフィックの多いNoSQLデータベース上に構築されたサイトでの作業や管理の経験はまだありません。Map / Reduceインデックスについて理解し始めており、ソリューションにいくつか含まれていますが、疑問に思っています。

Map / Reduceインデックスを作成する場合と作成しない場合について、従う必要のある経験則はありますか?

私はそれが私のシステムにあるビジネスオブジェクトとそれらが互いにどのように相互作用するかに非常に依存していることを知っています。インデックスを使用する必要があるクエリと、オブジェクトに直接クエリを実行できるクエリの全体像を把握するのに苦労していると思います。

これが私のビジネスドメインの一部の概要と、すでにインデックスを作成した場所です。

私のシステムは主にブランドと消費者で構成されています。それらのそれぞれは多くのソーシャルメディアアカウントを持っています。ユーザーがソーシャルメディアアカウントを介してサインインすると、インデックスとが表示されます。BrandsBySocialAccountこれらのコレクションは、それらのコレクションをフラット化し、ブランドまたは消費者のConsumersBySocialAccountコレクションに関連付けます。UserId取得したらUserId、関連するブランドまたは消費者の記録を取得して、離れることができます。

ブランドは多くのキャンペーンを作成できます。ここに別のインデックスがありますCampaignsByBrand。消費者がキャンペーンとどのように相互作用するかを追跡するための要件もあるため、キャンペーンには、キャンペーンで実行できるさまざまな相互作用の多くの追跡エントリを含めることができます。たとえば、外部からキャンペーンページへのリンクをたどったり、サイト自体からキャンペーンページを見つけたりすることができます。これを説明すると、ここにインデックスが必要なことは明らかです。インタラクションごとのインデックス(ClickLinkTrackingEntriesByCampaignおよびViewDetailsTrackingEntriesByCampaign)または1つのインデックス(TrackingEntriesByCampaign)相互作用が含まれています。ここでは複数のインデックスが過剰ですか?そうかも知れない。現在、4種類のインタラクションがあり、後で導入される可能性があります。レコードがいくつかある場合、これらのクエリは非常に高速です。しかし、数十万、さらには数百万のレコードがある場合でも、可能な限り高速になりますか?

全体的なデザインを見ると、コレクションのプロパティによってクエリされる必要がある可能性のあるコレクションプロパティを持つすべてのオブジェクトについて、Map/Reduceインデックスを作成する必要があるようです。それは従うべき経験則ですか?他にありますか-「これらのタイプのオブジェクトの相互作用がある場合は、これらの種類のインデックスの作成を検討する必要があります」

4

1 に答える 1

2

まず、静的インデックスに関するドキュメントをまだ確認していない場合は、必ず確認してください。

明確にしておく必要がある主なポイントは次のとおりです。

  1. ドキュメント ストアからドキュメントを直接取得する場合、インデックスは必要ないため、可能な限りインデックスを使用する必要があります。これは、次のいずれかを使用して行われます。
    • session.Load()
    • session.Advanced.LoadStartingWith()
    • documentStore.DatabaseCommands.Get()

  2. session.Query()またはを使用してクエリを実行するsession.Advanced.LuceneQuery()ときは常に、インデックスを使用しています。静的インデックス インデックスを指定しない場合は、動的インデックスが作成されます。多くの場合、動的インデックスの作成に伴う遅延は望ましくないため、通常は動的インデックスを静的インデックスに置き換えることをお勧めします。

  3. インデックスが多いほど、サーバーが実行しなければならない作業が増え、より多くのストレージを消費します。したがって、可能な限りインデックスを統合する必要があります。多くの場合、同じインデックスを複数の目的に使用できます。インデックスは慎重に作成する必要があります。インデックスを狭すぎて役に立たないものにしたり、広範で高価なものにしたりしないでください。

    A場合によってはフィールドでクエリを実行し、別の場合にはフィールドでクエリを実行する必要があるオブジェクトがあるとしますB。もちろん、2 つの異なるインデックスを作成することもできますが、これは無駄です。ABフィールドの両方をマップする単一のインデックスを使用する方がはるかに効率的です。これで、2 つの異なるクエリを同じインデックスで処理できるようになりました。可能な限りインデックスを統合することをお勧めします。

    典型的な悪い例は、文書内のすべてのフィールドをマップし、すべてのフィールドに対してフィールド ストレージをオンにすることです。これは、ある時点でそれらをインデックスから射影したいと考えるからです。ほとんどの場合、ここまで行く必要はありません。これが適切な場所がいくつかありますが、慎重に行う必要があります。

  4. すべてのインデックスにはMapがありますが、 Reduceセクションもあるまでは「マップ/リデュース」インデックスとは呼びません。作成するほとんどのインデックスは、map/reduce インデックスではありません。

    Map/Reduce インデックスは、ほとんどの場合、何らかの集計計算用に予約されています。たとえば、SocialAccountsCountByBrandドメインに am/r インデックスがある場合や、販売ドメインに のようなもっと複雑なものがある場合がありますTopCustomersByTotalSalesPerMonth

  5. オブジェクトにコレクション プロパティがある場合、そのコレクションのインデックスが必要であるというあなたの評価には同意しません。多くの場合、ドメイン内の別の場所に、同じ目的を果たすことができる同様のデータがあります。もちろん、具体的には何をしたいのかによって異なります。しかし、一般的に、これらのインデックスを多数作成している場合は、そのデータを独自のドキュメントにリファクタリングした方がよい場合があります。

    たとえば、次のようなクラスがあるとします。

    (意図的に悪い例 - 実際にはこれを行わないでください)

    public class Customer
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public List<Order> Orders { get; set; }
    }
    

    明らかに、すべての注文がオブジェクトに埋め込まれているCustomer場合、そのコレクションに対して頻繁にクエリを実行することになります。それぞれを独自のドキュメントにまとめて、参照によって顧客を参照することで、はるかに良いサービスが得られます。OrderCustomerId

  6. 最後に、結果の形状に基づいてインデックスについて考えないようにしてください。代わりに、クエリの対象に基づいてそれらを考えてください。つまり、クエリのWhereOrderBy、または句で指定するフィールドは何ですか?Search

    確かに、ライブ プロジェクションTransformResultsなどの手法はありますが、これらは慎重に使用する必要があります。関連ドキュメントのインデックス作成などのより強力な機能が用意されているため、ほとんどすべての変換の必要性に反対することができます。いくつかのマイナーなインデックス プロジェクションが役立つ場合もありますが、多くの場合、独自のコードで結果を操作するだけで、そこから抜け出すことができます。予測は、結果のインデックスからのデータが実際に必要な場合にのみ使用してください。必要なデータがすべてドキュメントに含まれている場合は、投影する必要はありません。

    UI の ViewModel に基づいてインデックスを設計する多くのケースを見てきたため、この点を取り上げます。これは、UI に配慮してインデックスを作成する必要があるため、好ましくありません。代わりに、結果自体の形について考えるべきです。クエリに回答するためのすべての情報が含まれている場合は、UI を含むがこれに限定されない、さまざまな方法で使用できます。

これがあなたの質問に答えることを願っています。他にもありましたらコメントでお答えください。ありがとう。

于 2013-02-13T16:44:39.347 に答える