0

目前我建立了一个网站,其中将包含大量的活动和非活动内容。发布内容时,它处于活动状态,一段时间后变为非活动状态。我想跟踪在活动期间打开内容的所有用户。将这些信息存储在数据库中的最佳方式是什么?

我需要查询数据库以下问题: 1. 哪些用户打开了特定的内容?这很少被管理员查询,每个内容可能会被管理员查询两到三遍。2. 特定用户打开了哪些活动内容?3. 特定用户打开了哪些非活动内容(内容,打开时处于活动状态,同时处于非活动状态)?这两个查询比第一个查询更频繁(可能每两到三周)。用户可以在他/她的个人资料中查看他/她打开了哪些内容。

首先,我想到了一个包含三列的数据库表:“用户 ID”、“内容 ID”、“状态”。其中“状态”对于活动内容为真,对于非活动内容为假。“用户 ID”和“内容 ID”是主键,“状态”是来自内容表的外键。但后来我想到了这张桌子的大小。在某些年份(希望)可能有 200 万个节点和 25 万个用户,因此可能有 5000 亿行……我认为,这会严重降低性能。

于是我想到了另一种方式:我创建了两个数据库表,一个叫做“content_opened_by_users”,另一个叫做“user_opened_content”。前者将包含两个列:“content id”和“users”。其中“users”是一个包含所有用户id的序列化数组,它在同一行中打开了相应的内容id。第二个表将包含三列:“用户 ID”、“活动内容”、“非活动内容”。其中“活动内容”和“非活动内容”也是序列化数组,其中包含相应用户打开的活动/非活动内容的内容 ID。因此,每当用户打开内容时,服务器都会从“content_opened_by_users”加载相应的“users”数组 表和“user_opened_content”表中相应的“活动内容”数组。如果用户 id 不存在于“users”-array 中,它将被添加,如果 content id 不存在于“active content”-array 中,它也将被添加。然后两个数组都将在数据库中被覆盖。现在,如果我查询所有打开某个内容的用户,我会从“content_opened_by_users”表中得到一个数组。如果我查询由特定用户打开的所有活动/非活动节点,我会从“user_opened_content”表中获得“活动内容”和“非活动内容”数组。然后我检查“活动内容”数组是否包含一些内容 ID,这些内容 ID 同时处于非活动状态并将它们转移到“非活动内容”

我知道,我在这两个表中创建了冗余数据,但我希望这会提高性能。

那么,这是一种方便的方式来完成用户跟踪吗?或者可能有另一种更有效的方法?

我会欢迎每一个建议!非常感谢你。丹尼尔

4

1 回答 1

0

首先,您可能想阅读有关数据库规范化的信息。

为了跟踪您描述的信息,我会为用户、内容和访问使用单独的表格,如下所示:

table    | columns
-------------------
users    | id, login, ...
content  | id, title, active, ...
access   | id, user_id, content_id, timestamp, ...

然后,无论谁打开了哪个项目,您都可以存储用户和内容项目。该access表包含关于哪个用户在哪个时间打开了哪个内容项的条目。这使您可以跟踪大量统计信息,而无需存储有关打开项目的用户的任何信息。

主要查询是:

  1. 哪些用户打开了一个项目

    SELECT DISTINCT users.login FROM access JOIN users ON access.user_id = users.id JOIN content ON access.content_id = content.id WHERE content.title LIKE '%test%'
    
  2. 用户打开的活动内容

    SELECT DISTINCT content.title FROM access JOIN users ON access.user_id = users.id JOIN content ON access.content_id = content.id WHERE content.active = true AND user.login = 'testuser'
    
  3. 用户打开的非活动内容

    SELECT DISTINCT content.title FROM access JOIN users ON access.user_id = users.id JOIN content ON access.content_id = content.id WHERE content.active = false AND user.login = 'testuser'
    

    假设访问只能发生在活动内容上。要跟踪状态更改的时间,请添加另一个表,您可以使用该表查找上次更改的时间戳并与访问条目进行比较。

请注意,这些查询根本没有优化。您还应该添加相应的FOREIGN KEY 约束以确保数据一致性,并考虑添加额外的索引以提高性能。

于 2014-11-02T16:49:26.080 回答