Database design RavenDB数据模型高效可扩展性设计选择

Database design RavenDB数据模型高效可扩展性设计选择,database-design,mapreduce,scalability,ravendb,Database Design,Mapreduce,Scalability,Ravendb,我在一个正在开发的项目中使用RavenDB,所以还没有用户。在这个项目之前,我的背景一直是关系数据库,但总体上我更喜欢NoSQL方法。然而,我还没有任何在NoSQL数据库上构建的、流量大的站点上工作或管理的经验。我开始了解Map/Reduce索引,并在解决方案中包含了一些索引,但我想知道: 关于何时创建映射/减少索引以及何时不创建索引,我是否应该遵循任何设计经验规则? 我知道这在很大程度上取决于我系统中的业务对象以及它们之间的交互方式。我想我只是在努力了解我可能正在进行的哪些查询应该使用索引,哪

我在一个正在开发的项目中使用RavenDB,所以还没有用户。在这个项目之前,我的背景一直是关系数据库,但总体上我更喜欢NoSQL方法。然而,我还没有任何在NoSQL数据库上构建的、流量大的站点上工作或管理的经验。我开始了解Map/Reduce索引,并在解决方案中包含了一些索引,但我想知道:

关于何时创建映射/减少索引以及何时不创建索引,我是否应该遵循任何设计经验规则?

我知道这在很大程度上取决于我系统中的业务对象以及它们之间的交互方式。我想我只是在努力了解我可能正在进行的哪些查询应该使用索引,哪些查询可以直接查询对象

下面是我的部分业务领域以及我已经创建索引的地方的快速概述:

我的系统主要由品牌和消费者组成。每一家都有许多社交媒体账户。当用户通过他们的社交媒体帐户登录时,我有索引,
BrandsBySocialCount
ConsumerBySocialCount
,它们将这些集合展平,并将它们与品牌或消费者的
用户ID
关联。一旦我有了
UserId
,我就可以检索相关的品牌或消费者记录,然后离开

一个品牌可以创造许多活动。我这里还有另一个索引,
activitsbybrand
。还需要跟踪消费者与活动的交互方式,因此活动可以有许多跟踪条目,用于跟踪他们与活动的不同交互。例如,他们可以在外部跟踪活动页面的链接,或者从网站本身中发现活动页面。正如我所解释的,这里显然需要索引。每个交互都有一个索引(
ClickLinkTrackingEntriesByCampaign
ViewDetailsTrackingEntriesByCampaign
)或一个包含交互的索引(
TrackingEntriesByCampaign
)。这里的多个索引是不是太过分了?可能是。目前有4种类型的交互,稍后可能会介绍其他类型的交互。当我有一些记录时,这些查询非常快。但是,当有数十万甚至数百万条记录时,它们是否仍会尽可能快


从总体设计来看,对于每个具有集合属性的对象(可能需要由该集合上的属性查询),我应该创建Map/Reduce索引。这是一个很好的经验法则吗?还有其他的吗?“如果您有这些类型的对象交互,您应该考虑创建这些类型的索引”

首先,如果您还没有,请确保查看文档

您需要明确的要点有:

  • 直接从文档存储中检索文档不需要索引,应尽可能使用索引。这可通过以下任一方法完成:
    • session.Load()
    • session.Advanced.LoadStartingWith()
    • documentStore.DatabaseCommands.Get()


  • 每当您使用
    session.query()
    session.Advanced.LuceneQuery()
    进行查询时,您总是在使用索引。如果未指定静态索引,则会为您创建一个。在许多情况下,创建动态索引所涉及的延迟不太理想,因此用静态索引替换动态索引通常是一个好主意

  • 索引越多,服务器必须做的工作就越多,消耗的存储也就越多。因此,您将希望尽可能合并索引。通常,同一索引可以用于多种目的。你应该仔细设计你的索引——不要把它们做得太窄而没有用处,也不要把它们做得太宽而昂贵

    假设我有一个对象,有时需要按字段
    A
    查询,有时需要按字段
    B
    查询。当然,我可以创建两个不同的索引,但这将是浪费。如果有一个索引同时映射
    a
    B
    字段,则效率会更高。现在,两个不同的查询可以由同一个索引提供服务。我敦促你们尽可能合并你们的索引

    一个典型的坏例子是映射文档中的每个字段,并为所有字段打开字段存储,只是因为您认为您可能希望在某个时候从索引中投影它们。在大多数情况下,你不需要走这么远。有几个地方这样做是合适的,但你会希望做得非常节省

  • 所有索引都有一个映射,但在它们也有一个reduce部分之前,我们不称它们为“Map/reduce”索引。您将创建的大多数索引都不是映射/减少索引

    Map/Reduce索引几乎总是为某种类型的聚合计算保留的。例如,在您的域中,您可能有一个按品牌划分的
    社会帐户的m/r索引,或者在销售域中,您可能有一些更复杂的索引,如
    TopCustomers ByTotalSalerMonth

  • 我不同意你的评估,如果一个对象有一个集合属性,它需要在该集合上建立一个索引。在许多情况下,您的域中的其他地方也会有类似的数据,可以达到相同的目的。当然,具体细节会因您想做什么而有所不同。但一般来说,如果您发现您正在创建大量这些索引,那么最好将这些数据重构到自己的文档中

    例如,如果我有一个如下的类:

    (故意树立坏榜样——不要真的这样做)

    公共类客户
    {
    公共str
    
    public class Customer
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public List<Order> Orders { get; set; }
    }