Php 数据库结构跟踪用户是否打开特定内容的最佳实践?

Php 数据库结构跟踪用户是否打开特定内容的最佳实践?,php,mysql,database,user-tracking,Php,Mysql,Database,User Tracking,目前,我建立了一个网站,将包含大量的活动和非活动的内容。发布内容时,该内容处于活动状态,一段时间后变为非活动状态。我想跟踪在活动期间打开内容的所有用户。在数据库中存储这些信息的最佳方式是什么 我需要查询以下问题的数据库: 1.哪些用户打开了特定内容?这是很少见的,管理员可能会对每个内容查询两三次。 2.特定用户打开了哪些活动内容? 3.特定用户打开了哪些非活动内容(打开时处于活动状态,同时处于非活动状态的内容)?两个查询比第一个查询更频繁(可能每两周或三周查询一次)。用户可以签入他/她的个人资料

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

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

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

因此,我考虑了另一种方法:创建两个数据库表,一个称为“content\u opened\u by\u users”,另一个称为“user\u opened\u content”。前者将包含两个合谋:“内容id”和“用户”。其中“users”是一个包含所有用户id的序列化数组,它在同一行中打开了相应的内容id。第二个表将包含三列:“用户id”、“活动内容”、“非活动内容”。其中,“活动内容”和“非活动内容”也是序列化数组,其中包含相应用户打开的活动/非活动内容的内容ID。 因此,每当用户打开内容时,服务器都会从“用户打开的内容”表加载相应的“用户”数组,并从“用户打开的内容”表加载相应的“活动内容”数组。如果用户id在“用户”数组中不存在,则将添加该用户id;如果内容id在“活动内容”数组中不存在,则也将添加该内容id。然后这两个数组将在数据库中被覆盖。 现在,如果我查询打开某个内容的所有用户,我会从“content\u opened\u by\u users”表中得到一个数组。如果我查询由特定用户打开的所有活动/非活动节点,我将从“user\u opened\u content”表中获得“active content”和“inactive content”数组。然后我检查“活动内容”数组是否包含一些同时处于非活动状态的内容ID,并将它们传输到“非活动内容”数组,然后将它们传回数据库

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

那么,这是一种方便的方法来完成用户跟踪吗?或者有没有其他更有效的方法

我欢迎大家的建议! 非常感谢你。
丹尼尔

首先,你可能想了解一下

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

table    | columns
-------------------
users    | id, login, ...
content  | id, title, active, ...
access   | id, user_id, content_id, timestamp, ...
然后,无论是谁打开了哪个项目,都可以存储用户和内容项目。
access
表包含关于哪个用户在哪个时间打开了哪个内容项的条目。这允许您跟踪大量统计信息,而无需存储有关未打开项目的用户的任何信息

主要问题是:

  • 哪些用户打开了一个项目

    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%'
    
  • 用户打开的活动内容

    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'
    
  • 用户打开的非活动内容

    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'
    
    假设访问只能发生在活动内容上。要跟踪状态更改的时间,请添加另一个表,用于查找上次更改的时间戳并与访问条目进行比较


  • 请注意,这些查询根本没有经过优化。您还应该添加相应的数据,以确保数据一致性,并考虑添加额外的索引以提高性能。对不起,我没有提到,我还有两个单独的用户和内容表。因此,所有与用户/内容管理相关的东西总体上都已经可以正常工作了。您关于访问表的建议似乎与我的第一个想法相似。正如我所提到的,我担心性能。比如说,在某些年份,有数百万个项目和数千个用户。如果每个用户都打开了每个项目(好吧,这完全是不现实的,但我只是想做好准备),那么访问表中将有几十亿个条目。。。。。。我猜,这会严重降低性能,对吗?这取决于。。。MySQL的最大行数非常高。因此,只要添加正确的索引,每天有数百次访问的数千个用户都不是问题。我真的需要访问表中的索引吗?我会将user_id和content_id设置为主键,所以我不需要access_id字段。并且主键总是被索引。。。或者我应该分别为用户id和内容id编制索引?access表中的列应该具有需要索引才能工作的索引。mysql使用它们来匹配来自不同表的数据。然而,以后更改索引并不是一个大问题。顺便说一句:像这样的框架将自动生成这些约束。