查看此项目的数据库也已查看过。'

时间:2015-04-28 15:45:50

标签: mysql mongodb database-design relational-database database

我想创建功能'谁看过这个项目也看过'像亚马逊或Ebay。我在MySql和非关系型数据库之间做出决定,比如MongoDB。

编辑:在MySql中实现此功能似乎很简单。我的猜测是创造“观看”。保存userId,itemId和查看时间的表。因此,当试图推荐用户正在查看的当前项时,我会Sub =(SELECT userId FROM查看WHERE itemId == currentItemId)然后,SELECT itemId FROM查看INNER JOIN Sub on seen.userId = Sub.userId < / p>

对于本月浏览过100页的100,000名用户来说,这会不会太多?

对于非关系数据库,我觉得让用户嵌入所有用户或项目来嵌入所有用户是不对的。因此,我想让每个用户都拥有他查看的itemIds列表,每个Item都包含一个userIds列表。而且我不确定下一步该做什么。我在正确的道路上吗?

如果没有,您能否建议在非关系数据库中实现此功能的好方法?而且,与MySql相比,这个建议在速度上有优势吗?

2 个答案:

答案 0 :(得分:2)

初步回复

  

通过在Item和User表上调用JOIN,在MySql中实现此功能似乎很简单。

  

但是,数据库调用有多快或多慢一次收集100,000个用户的整个观看历史记录?

一根绳子有多长?

这取决于Relational Database实现的标准和质量。如果您的所有文件都有ID个字段,那么它就没有关系完整性,功能或速度,它将具有1970年代ISAM记录文件系统的速度。

在Sybase ASE服务器上,在小型Unix机器上,对具有160亿行的表(非文件)的类似意图的SELECT在12毫秒内返回100行。

  

对于非关系型数据库,我觉得让用户嵌入所有用户或项目来嵌入所有用户是不对的。因此,我想让每个用户都拥有他查看的项目ID列表,每个项目都包含一个用户ID列表。

我无法回答MangoDb。

但对于关系数据库,我们就是这样实现的。

  • 有一个很大的区别:这两个列表在一个表中实现

  • 每一行都是从两个方面看到[抱歉]的一个事实(用户查看了一个项目的事实,与用户查看了一个项目相同)

所以它似乎是关系思维......实现了Mango风格,需要 100%数据和表重复。我不知道MongoDb中的好坏,从某种意义上说,它很可能是事物所需要的&#34;执行&#34;。像罪一样丑陋。

  

我不知道下一步该做什么。我在正确的道路上吗?

关系的权利(只要你为两个&#34;列表&#34;使用一个表)。如果您不理解这一点,请提出更具体的问题。

  

如果没有,您是否可以建议在非关系数据库中实现此功能的好方法?而且,与MySql相比,这个建议在速度上有优势吗?

抱歉,我无法回答这个问题。

但非关系型Db不太可能存储和检索经典Relational的信息,比半关系记录文件系统(如myNONsql)更快。当然,一切都是平等的。一个真正的SQL平台会更快。

对评论的回应

首先你有:

  

所以,我想让每个用户都拥有他查看的项目ID列表,每个项目都包含一个用户ID列表。

这是两个清单。这不好,因为第二个列表是第一个列表的100%重复。

现在你有了(在问题和新评论中编辑过):

  

我没有完全理解你的意思,并且在两个列表中使用一个表格&#39;。我的解释是创造&#39;观看&#39;保存userId,itemId和查看时间的表。

这很好,你现在有一个清单。

为了清楚我们正在讨论的数据库,让我建立一个模型,让你确认一下。

  • User Item Data Model

  • 如果您不习惯标准符号,请注意每个小刻度,缺口和标记,实线与虚线,方形与圆角,意味着非常具体。请参阅IDEF1X Notation

  

因此,当试图推荐用户正在查看的当前项时,我会Sub =(SELECT userId FROM查看WHERE itemId == currentItemId)。然后,SELECT itemId FROM查看INNER JOIN Sub on seen.userId = Sub.userId。这是你的意思吗?

我确实对表格做了声明和警告,但我没有给出NONsql编码的任何指示,所以没有。

我绝不会建议分两步完成任务,这可以一步完成。 SQL有它的问题,但是使用单个SELECT 从一组关系表(即派生的关系)获取信息的困难绝对不是其中之一。

SUB不是SQL。虽然我可以猜测它的作用,但我可能错了,因此我无法对该代码发表评论。

对于我提供的模型,在ISO / IEC / ANSI标准SQL平台上,我会使用:

    SELECT  DISTINCT ItemId     -- Items viewed by ...
        FROM UserItem
        WHERE UserId = (
            SELECT  UserId      -- Users who viewed Item
                FROM UserItem
                WHERE ItemId = @CurrentItemId
            )

您必须将其转换为您的平台所需的NONsql。

  

对于本月浏览过100页的100,000名用户来说,这不是太多了吗?很抱歉很长的问题。

我在最初的回复中已经回答了这个问题。请再读一遍。

您正在尝试解决尚未的性能问题。鉴于物理定律,依赖性,我们无法逆转年表,这是不可能的;因此,我建议你停止这项活动。

同时,回到农场,奶牛需要喂食。首先设计数据库,然后设置应用程序代码,然后如果,有性能问题,您可以解决它们。 IT专业人员可以进行科学估算,但我不能在这里给你一个教程。

每月10,000,000次页面浏览量。你还没有说过物品的号码,所以这个大人物太可怕了。如果你告诉我有多少物品;用户;每次会议查看的平均项目;和你想要报道的持续时间(例如月份),我可以给你更具体的建议。

据我了解,用户查看1(一)项。作为一种销售功能,您希望系统识别人物列表中的人物#34;谁也查看了此项目...&#34;。这似乎只是10,000,000次观看的一小部分。你的每张桌子都有索引,是吗?因此,您使用的NONsql程序将不会读取10,000,000个视图来查找该分数,它将导航索引,并且只读取包含该分数的页面。

  • 一些NONsqls需要第二个索引来执行真正的SQL平台使用一个索引执行的操作。我在模型中给出了第二个索引。

  • 虽然我很欣赏你没有为你描述的文件提供完整的定义,但到目前为止,因为我提供了一个模型,我必须提供一个完整而正确的文件,而不是部分一。

  • 由于用户多次查看项目,因此我提供了一个允许该项目的表格,并跟踪了视图数量和上次查看日期。每个User :: Item都是一行。如果您希望每个User :: Item视图支持一行的表,请询问,我将提供。

从我所处的位置,根据迄今为止确定的事实,10,000,000的数字并不受关注。

答案 1 :(得分:0)

这可能更多地取决于您如何实现此功能而不是使用的数据库类型。

如果您只存储了大量的观看记录(例如,“用户x查看了项目y”),则必须查看查看项目的用户,然后查看用户查看的所有项目。这一切都可以在一个数据库表上完成。但最终可能会得到非常大的结果集。

使用“连接”项目的图形结构可能更容易,这些项目在运行时期间不断更新,然后轻松查询。