我应该如何在MongoDB中实现这个模式?

我正在尝试编写一个跟踪脚本,并且在确定数据库应该如何工作时遇到问题。

在MySQL中,我会创建一个类似于的表

User:
   username_name: string

Campaign:
   title: string
   description: string
   link: string

UserCampaign:
   user_id: integer
   camp_id: integer

Click:
   os: text
   referer: text
   camp_id: integer
   user_id: integer

我需要能够:

  • 查看来自IP,Referer,OS等每个点击的信息
  • 查看X IP,X Referer,X OS的点击次数
  • 将每次点击与用户和广告系列相关联
  • 如果我按照...的方式做一些事情

    User {
         Campaigns: [
             {
               Clicks: []
             }
         ]
    }
    

    我碰到两个问题:

  • 它为每个用户创建一个新的活动对象,这是一个问题,因为如果我需要更新我的活动,我需要为每个用户更新对象
  • 我期望Clicks数组包含大量的数据,我觉得让它成为User对象的一部分会使查询非常慢

  • 好吧,我认为你需要把它分解成基本的“品种”。

    你有两个“实体”风格的对象:

  • User
  • Campaign
  • 你有一个“映射”风格的对象:

  • UserCampaign
  • 你有一个“事务性”风格的对象:

  • Click
  • 第1步:实体

    让我们从简单的开始: UserCampaign 。 这些确实是两个单独的对象,它们的存在都不依赖于其他对象。 这两者之间也没有明显的过渡性:用户不属于广告系列,广告系列也不属于用户。

    当你有两个这样的顶级对象时,他们通常会获得他们自己的集合。 所以你需要一个Users集合和一个Camapaigns集合。

    第2步:映射

    UserCampaign目前用于表示一个N到M的映射。 现在,一般来说,当你有N对1的映射时,你可以把N放在1的内部。但是,用N到M的映射,你通常必须“选择一边”。

    从理论上讲,您可以执行以下任一操作:

  • 在每个User放置一个Campaign ID列表
  • 在每个Campaign放置Users ID列表
  • 就我个人而言,我会做#1。 您可能有更多的用户使用该广告系列,并且您可能希望将该数组放在更短的位置。

    第3步:交易

    点击确实是一个完全不同的野兽。 在对象方面,您可以考虑以下内容: Clicks “属于” UserClicks “属于” Campaign 。 因此,从理论上讲,您可以将商店点击作为这些对象的一部分。 很容易认为点击属于用户或广告系列。

    但是,如果你真的深入了解,上述简化实际上是有缺陷的。 在您的系统中, Clicks确实是一个中心对象。 实际上,您甚至可以说用户和广告系列实际上只是“与”点击相关联。

    看看你问的问题/疑问。 所有这些问题都是以点击为中心的。 用户和广告系列不是数据中的核心对象,点击是。

    此外,点击将成为您系统中最丰富的数据。 您将拥有比其他任何方式更多的点击次数。

    当为这样的数据设计模式时,这是最大的困难。 有时候,当他们不是最重要的事情时,你需要推掉“父母”对象。 想象一下建立一个简单的电子商务系统。 很明显, orders将“属于” users ,但orders对系统至关重要,因此它将成为“顶级”对象。

    把它包起来

    你可能会需要三个集合:

  • 用户 - >有campaign._id列表
  • 运动
  • 点击 - >包含user._id,campaign._id
  • 这应该满足您的所有查询需求:

    查看来自IP,Referer,OS等每个点击的信息

    db.clicks.find()
    

    查看X IP,X Referer,X OS的点击次数

    db.clicks.group()或运行Map-Reduce。

    将每次点击与用户和广告系列相关联

    db.clicks.find({user_id : blah})也可以将点击ID添加到用户和广告系列中(如果有意义的话)。

    请注意,如果您有大量的点击次数,那么您将不得不分析最常用的查询。 您无法在每个字段上编制索引,因此您通常需要运行Map-Reduces来“汇总”这些查询的数据。


    我在这里看到的主要问题是您正试图将关系数据库概念应用于面向文档的数据库。 两者之间的主要区别在于,您不必担心NOSQL数据库中的模式或结构,而是关于收集和文档。

    理解在SQL的许多NOSQL实现中没有连接概念是非常重要/必要的。 这意味着,如果您将数据分布到集合中,那么稍后您需要做大量工作来粘合它。 同样,通过在SQL数据库的规范化过程中将数据分布到集合中也没有其他收益。 你需要考虑哪些数据是你的文档的一部分,以及它适用于哪个集合,并且从不担心NOSQL数据库下的实现。 所以对于你的问题,答案可能会是..并且会支持你所要求的所有...

    db.trackclicks ==>集合
    trackclick = {操作系统:XP,用户:John Doe,广告系列:{title:test,desc:test,link:url},推荐人:google.com}


  • 如果某公司的某些内容发生更改,mongodb更新大量文档并不是问题。

  • 嵌套收集还是没有真正取决于收集中有多少数据。 在你的情况下,如果你知道'点击'收藏将包含'大量的数据',你需要创建一个单独的集合。 因为对于'点击'肯定会需要分页,过滤等,而且用户将会'轻'收集。

  • 所以我建议如下:

    User {
         Campaigns: []
    }
    
    Clicks {
     user_id,
     camp_id
    }
    
    链接地址: http://www.djcxy.com/p/86417.html

    上一篇: How should I implement this schema in MongoDB?

    下一篇: C# redis vs mongodb performance