我正在尝试编写跟踪脚本,但在弄清楚数据库应如何工作时遇到了麻烦。

在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,引荐来源网址,操作系统等
  • 查看X IP,X Referer和X OS上有多少次点击
  • 将每次点击与用户和广告系列相关联

  • 如果我按照
    User {
         Campaigns: [
             {
               Clicks: []
             }
         ]
    }
    

    我遇到两个问题:
  • 它为每个用户创建一个新的广告系列对象,这是一个问题,因为如果我需要更新广告系列,则需要为每个用户更新对象
  • 我希望Clicks数组包含大量数据,我觉得将它作为User对象的一部分会使查询
  • 的速度非常慢

    最佳答案

    好的,我认为您需要将其分解为基本的“多样性”。

    您有两个“实体”样式的对象:

  • User
  • Campaign

  • 您有一个“映射”样式的对象:
  • UserCampaign

  • 您有一个“事务”样式的对象:
  • Click

  • 步骤1:实体

    让我们从简单的开始:UserCampaign。这些确实是两个单独的对象,它们的存在都不依赖于另一个。两者之间也没有隐式的层次结构:用户不属于Campaigns,Campaign也不属于Users。

    当您有两个这样的顶级对象时,它们通常会获得自己的收藏。因此,您需要一个Users集合和一个Camapaigns集合。

    步骤2:映射
    UserCampaign当前用于表示从N到M的映射。现在,通常,当您具有N对1映射时,可以将N放在1的内部。但是,使用N对M映射时,通常必须“拾取侧面”。

    从理论上讲,您可以执行以下操作之一:
  • 在每个Campaign ID内放入一个User列表
  • 在每个Users ID内放入一个Campaign列表

  • 就个人而言,我会做#1。您可能拥有更多的用户来进行广告 Activity ,并且您可能希望将数组放置在较短的位置。

    步骤3:事务性

    点击确实是完全不同的野兽。用对象术语,您可能会想到以下内容:Clicks“属于” UserClicks“属于” Campaign。因此,从理论上讲,您可以只将点击存储在这些对象中的任何一个中。容易想到点击属于用户或广告系列。

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

    查看您要问的问题/查询。所有这些问题实际上都围绕点击。 用户和广告系列不是数据中的中心对象,而点击是。

    此外,点击将是您系统中最丰富的数据。您将获得更多的点击次数。

    在为此类数据设计架构时,这是最大的麻烦。有时,当您不是最重要的对象时,您需要推下“父”对象。想象一下构建一个简单的电子商务系统。显然,orders将“属于” users,但是orders在系统中如此重要,以至于将成为“顶级”对象。

    将其包装成

    您可能需要三个集合:
  • 用户->具有广告系列列表。_id
  • 广告系列
  • 点击次数->包含user._id,campaign._id

  • 这应该可以满足您的所有查询需求:


    db.clicks.find()
    


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


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

    请注意,如果您有很多点击,那么您实际上必须分析您最常运行的查询。您无法在每个字段上建立索引,因此,您通常需要运行Map-Reduces以“汇总”这些查询的数据。

    关于database-design - 我应该如何在MongoDB中实现此架构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4662530/

    10-09 04:42