'who viewed this item also viewed..' 的数据库

Database for 'who viewed this item also viewed..'

我想创建像 Amazon 或 Ebay 这样的功能 'who viewed this item also viewed'。我在 MySql 和 MongoDB 等非关系数据库之间做出决定。

编辑:在 MySql 中实现此功能似乎很简单。我的猜测是创建 'viewed' table,其中保存了 userId、itemId 和查看时间。因此,当尝试推荐用户正在查看的当前项目时,我会 Sub = (SELECT userId FROM viewed WHERE itemId == currentItemId) 然后,SELECT itemId FROM viewed INNER JOIN Sub on viewed.userId = Sub.userId

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

对于非关系数据库,我觉得用User嵌入所有用户或者用Item嵌入所有User都不对。所以,我想让每个用户都拥有一个他查看过的 itemId 列表,每个 Item 都包含一个被查看过的 userId 列表。而且我不确定下一步该怎么做。我走的路对吗?

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

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

如果您只存储大量查看历史记录(例如,"user x looked at item y"),则必须查看查看某个项目的用户,然后查看这些用户查看的所有项目。这一切都可以在单个数据库 table 上完成。但是最终可能会得到非常大的结果集。

使用 "connected" 项目的图形结构可能会更容易,这些项目在运行时不断更新,然后很容易查询。

初步反应

It seems to be straightforward to implement this feature in MySql by just calling JOIN on Item and User table.

是的。

But, how fast or slow the database call will be to gather entire viewing history of 100,000 users at once?

一根绳子有多长?

这取决于您的关系数据库实施的标准和质量。如果您的所有文件上都有 ID 字段,它不会具有关系完整性、功能或速度,它会有 1970 年代的 ISAM 记录归档系统速度。

在一个 Sybase ASE 服务器上,在一个小的 Unix 机器上,一个 SELECT 在一个有 160 亿行的 table(不是文件)上有类似的意图 returns 100 行在12 毫秒。

For non-relational database, I don't feel it is right to have User to embed all users or Item to embed all Users. So, I'm thinking to have each User holds a list of item ids he looked at and each Item holds a list of user ids seen by.

我无法回答 MangoDb。

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

  • 有一个很大的不同:这两个列表是在一个 table

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

所以它似乎是关系思维......实现了 Mango 风格,这需要 100% 数据和 table 重复 。我不知道这在 MongoDb 中是好是坏,因为它很可能是事物“执行”所需要的。丑得像罪过。

And I'm not sure what to do next. Am I on the right path here?

Relational 的权利(只要您对两个“列表”使用一个 table)。如果您不明白这一点,请提出更具体的问题。

If not, could you suggest a good way to implement this feature in non-relational database? And, does this suggestion have advantage in speed compared to MySql?

抱歉,我无法回答。

但是非关系数据库不太可能存储和检索经典关系数据库的信息,比 MySQL 等半关系记录归档系统更快。当然,所有事情都是平等的。真正的 SQL 平台会更快。

对评论的回应

首先你有:

So, I'm thinking to have each User holds a list of item ids he looked at and each Item holds a list of user ids seen by.

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

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

I didn't fully understand what you meant by 'use one table for the two list'. My interpretation is create 'viewed' table in which userId, itemId, and time of viewing are saved.

太好了,你现在有了一份清单。

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

  • User Item Data Model

  • 如果您不习惯标准符号,请注意每一个小刻度、缺口和标记,实线与虚线,方角与圆角,都具有非常具体的含义。参考IDEF1X Notation.

So, when trying to recommend off of a current item a user is looking at, I would Sub = (SELECT userId FROM viewed WHERE itemId == currentItemId). Then, SELECT itemId FROM viewed INNER JOIN Sub on viewed.userId = Sub.userId. Is this what you mean?

我确实对 table 做出了声明和警告,但我没有给出任何关于非 SQL 编码的指示,所以没有。

我绝不会建议分两步做某事,那可以一步完成。 SQL 有它的问题,但是很难使用 单个关系从一组关系 table 中获取信息(即 derived 关系) 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
            )

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

Wouldn't it be too much for 100,000 users who viewed 100 pages this month? Sorry for long question.

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

您正在尝试解决您尚未遇到的性能问题。考虑到物理定律、依赖性以及我们无法逆转时间顺序,这是不可能的;等等 因此,我建议您停止 activity.

与此同时,回到农场,需要喂奶牛。先设计数据库,再编码app,然后ifonly if,有性能问题,可以解决。 IT专业人士可以做出科学的估计,但我不能在这里给你一个教程。

每月 10,000,000 次页面浏览。你没有说物品的编号,所以这个大数字吓死人了。如果你告诉我有多少物品;用户;每个会话查看的平均项目;以及你希望覆盖的持续时间(例如一个月),我可以给你更具体的建议。

据我了解,一位用户查看了 1(一)个项目。作为销售功能,您希望系统识别“查看此项目的人还查看了...”的项目列表。这似乎只是 10,000,000 次浏览量的一小部分。每个 table 都有一个索引,是吗?因此,您正在使用的非 SQL 程序不会读取 10,000,000 次查看以找到该部分,它会导航索引,并且仅读取包含该部分的页面。

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

  • 虽然我很感激没有为您描述的文件提供完整的定义,但到目前为止,由于我提供的是模型,所以我必须提供一个完整且正确的模型, 不是部分的。

  • 由于用户不止一次查看项目,我提供了一个允许这样做的 table,并跟踪查看次数和上次查看日期。永远是每 User::Item 一行。如果您想要 table 每个 User::Item 视图支持一行,请询问,我会提供。

从我目前所掌握的事实来看,10,000,000 这个数字并不重要。