Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
存储用户活动?PHP、MySQL与数据库设计_Php_Mysql_Sql_Database_Database Design - Fatal编程技术网

存储用户活动?PHP、MySQL与数据库设计

存储用户活动?PHP、MySQL与数据库设计,php,mysql,sql,database,database-design,Php,Mysql,Sql,Database,Database Design,好的,所以一个用户来到我的web应用程序,并获得活动的分数等,有点类似于(但没有这么复杂)这个网站。他们可以投票、评论、提交、收藏、为评论投票、写描述等 目前,我将用户操作存储在一个表中,日期如下 Table user_actions action_id - PK AI int user_id - PK int action_type - varchar(20) date_of_action - datetime 例如,如果

好的,所以一个用户来到我的web应用程序,并获得活动的分数等,有点类似于(但没有这么复杂)这个网站。他们可以投票、评论、提交、收藏、为评论投票、写描述等

目前,我将用户操作存储在一个表中,日期如下

Table user_actions
    action_id       - PK AI int
    user_id         - PK int
    action_type     - varchar(20)
    date_of_action  - datetime
例如,如果一个用户出现并留下一条评论或对一条评论进行投票,那么这些行将如下所示

    action_id       = 4
    user_id         = 25
    action_type     = 'new_comment'
    date_of_action  = '2011-11-21 14:12:12';

    action_id       = 4
    user_id         = 25
    action_type     = 'user_comment_vote'
    date_of_action  = '2011-12-01 14:12:12';
我听到你说的都很好,但不是很好,记住这些行将位于
user\u actions
表中,该表与存储注释和用户注释投票的表不同。

那么,我如何知道哪些注释链接到
user\u actions
中的哪一行呢

我可以在comments表中将惟一的
comment\u id
链接到
user\u actions
表中名为
target\u primary\u key

没有。不能这样做,因为该操作可能同样是一个具有复合键(双键)的
用户\u评论\u投票

所以我剩下的想法是,我是否只需在列中添加主键并用逗号消除它们,然后让PHP解析出来?


以上面的示例为例,下面的几行显示了如何存储目标主键

new_comment
target_primary_keys - 12 // the unique comment_id from the comments table 

user_comment_vote
target_primary_keys - 22,12 // the unique comment_id from the comments table 


因此,基本上是一个用户执行一个操作,
user\u actions
会更新,特定的
表也会更新,但是如何在允许多个键的情况下链接这两个操作呢

以前是否有人有过存储用户活动的经验


欢迎任何想法,这里没有错误的答案

最简单的答案是只使用另一个表,该表可以包含任意键的多个匹配项,并允许伟大的索引选项:

create table users_to_actions (
   user_id int(20) not null,
   action_id int(20) not null,
   action_type varchar(25) not null,
   category_or_other_criteria ...
);

create index(uta_u_a) on users_to_actions(user_id, action_id);
若要对此稍作扩展,您可以通过将项目与此表连接来选择项目:

select
  *
from
  users_to_actions as uta join comments as c using(action_id)
where
  uta.action_type = 'comment' and user_id = 25
order by
  c.post_date
或者根据您的需要使用嵌套查询:

  select * from users where user_id in(
      select
         user_id
      from 
         users_to_actions
      where
         uta.action_type = 'comment'
  );

您不需要用户操作表。 要计算“分数”,您可以在多个表上运行一个查询,并将匹配评论、评分等的计数乘以乘数(评论25分,评分10分,…)

为了加快页面速度,您可以将总分存储在额外的表或用户表中,并在分数发生变化时使用触发器刷新总分

如果您想显示评级或评论的数量,也可以这样做


从现有表格中获取详细信息,并将评论和评级的总数存储在一个额外的表格中。

我不确定您的答案与我的问题有何不同?我就是想不出存储多个密钥的最佳方法。如果没有难看的空列,则需要使用索引表,该表可以包含多个用户、键等;复合密钥是愚蠢的,并且违背了RMDB的目的;您的索引表(在我的示例中,users\u to\u actions)将用作您的复合键,并包含所有关系。我认为您可能理解错误。存储键后连接表的过程不是问题。简单地说,当键可能在1到3列之间时,我如何存储多个键?我认为这比您想象的要简单:)您只需将所有键列都放在数据库中。如果您需要匹配缺少的键部分,只需尝试
where(part_1='abc'或part_1为null)和(part_2>123或part_2=0)
等等。我想我看不出空列有什么问题。;)他们有什么难看的?他们当然比试图处理散列和定界符以及其他避免简单连接的复杂而愚蠢的方法要好得多。如果某个用户删除了一条评论,而您希望清除该活动,则可能会遇到问题。如果在(操作类型、目标主键)上放置索引,则不会遇到键“双键问题”。连接数据的最合适的关系方式是通过intersect表。因此,在您的情况下,您可能会有一个
user\u comment\u has\u user\u action
表,该表将
user\u comment\u id
链接到
user\u action\u id
(反之亦然)。如果这些关系并不重要,就不用麻烦了,用你现有的或者某种程序化的方式来删除动作。是的,这就是我和凯文的斗争。这是一个尴尬的问题。因为可能有10个不同的
用户操作
,这将导致10个以上的表。我想,我可能会继续,让PHP解析它,这就是问题所在。我知道我的模型不是最好的,但就目前情况而言,我已经花了两天时间思考这个问题。相信我,PHP看起来越来越像一个更好的选择Sean,如果你只是使用这些信息来建立一个点方案,也许你不需要动作表或交叉点,只需要一个视图来显示代表编号?