mysql / php - 确定数据的来源

时间:2012-08-19 00:33:29

标签: php mysql

我需要确定新闻Feed的表格数据。 Feed必须说“人已上传视频”或“人已更新其生物”。因此,我需要确定数据的来源,因为不同类型的数据显然位于不同的表中。我希望你能用SQL做到这一点,但可能不是这样,PHP是可选的。我不知道如何做到这一点所以只需指向正确的方向。

我将简要描述数据库,因为我没有时间制作图表。

1.有一个名为会员的表格,其中包含电子邮件,密码和身份证等所有基本信息。 ID是主键。

  1. 所有其他表都有用于链接到members表中ID的ID的外键。

  2. 其他表包括;曲目,状态,图片,视频。所有这些都非常自我解释。

  3. 我需要以某种方式确定更新数据来自哪个表,以便我可以告诉用户这样做了什么。最好我只想要整个feed的一个SQL语句,所以所有的表都通过时间戳连接和排序,使得一切对我来说都更简单。希望我能做到这两点,但正如我所说,我真的不确定。

    该陈述的基本概要,将会更长,但已经简化;

    SELECT N.article,  N.ID, A.ID, A.name,a.url, N.timestamp
    FROM news N
    LEFT JOIN artists A ON N.ID = A.ID
    WHERE N.ID = A.ID
    ORDER BY N.timestamp DESC
    LIMIT 10
    

    会员表;

    CREATE TABLE `members` (
    `ID` int(111) NOT NULL AUTO_INCREMENT,
    `email` varchar(100) COLLATE latin1_general_ci NOT NULL,
    `password` varchar(100) COLLATE latin1_general_ci NOT NULL,
    `FNAME` varchar(100) COLLATE latin1_general_ci NOT NULL,
    `SURNAME` varchar(100) COLLATE latin1_general_ci NOT NULL,
    `timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`ID`),
    UNIQUE KEY `email` (`email`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
    

    跟踪表,所有其他表几乎相同;

    CREATE TABLE `tracks` (
    `ID` int(11) NOT NULL,
    `url` varchar(200) COLLATE latin1_general_ci NOT NULL,
    `name` varchar(100) COLLATE latin1_general_ci NOT NULL,
    `timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
    `track_ID` int(11) NOT NULL AUTO_INCREMENT,
     PRIMARY KEY (`track_ID`),
     UNIQUE KEY `url` (`url`),
     UNIQUE KEY `track_ID` (`track_ID`),
     KEY `ID` (`ID`),
     CONSTRAINT `tracks_ibfk_1` FOREIGN KEY (`ID`) REFERENCES `members` (`ID`)
     ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
    

    在我尝试对每个表使用mysql查询并将所有内容放入数组并将其回显之前。这看起来很漫长而且很无聊,我没有运气。我现在已经删除了所有代码,因为它已经过了一周左右。

    请不要觉得你必须深入了解这一点,只是指出我正确的方向。

    此外:

    这是我为建议的触发器做的sql查询。不确定之前从未使用过触发器有什么问题。将某些内容插入曲目时会出现此错误

    #1054 - Unknown column 'test' in 'field list' 
    

    查询中的值仅用于测试

     delimiter $$
    
     CREATE
    
     TRIGGER tracks_event AFTER INSERT
     ON tracks FOR EACH ROW 
    
       BEGIN
    
    INSERT into events(ID, action)
        VALUES (3, test);
    
       END$$
    delimiter ;
    

    UPDATE!

    我现在已经根据建议创建了一个名为events的表,并使用触发器在多个表中的一个表中插入后更新它。

    这是我尝试过的查询,但这是错误的。查询需要从所有其他表中获取事件表中引用的信息,并按时间戳排序。

    SELECT T.url, E.ID, T.ID, E.action, T.name, T.timestamp
    FROM tracks T
    LEFT JOIN events E ON T.ID = E.ID
    WHERE T.ID = E.ID
    ORDER BY T.timestamp DESC
    

    在该查询中,为了简单起见,我只包括事件和轨道表,因为问题仍然存在。会有更多的表格,所以问题会更加严重。

    很难描述问题,但主要是因为每个表中都有一个ID而一个ID可以执行多个操作,操作可能会显示错误的结果,在本例中为url。

    我将解释事件表和轨道表中的内容,并给出结果以进一步解释。

    在事件表中;

          4 has uploaded a track.
          3 has some news.
          4 has become an NBS artist.
    

    在赛道上;

          2 uploads/abc.wav Cannonballs & Stones    2012-08-20 23:59:59 1
          3 uploads/19c9aa51c821952c81be46ca9b2e9056.mp3    test    2012-08-31 23:59:59 2
          4 uploads/2b412dd197d464fedcecb1e244e18faf.mp3    testing 2012-08-31 00:32:56 3
          4 111 111111  0000-00-00 00:00:00 111111
    

    查询结果;

    uploads/19c9aa51c821952c81be46ca9b2e9056.mp3    3   3   has some news.  test    2012-08-31 23:59:59    
    uploads/2b412dd197d464fedcecb1e244e18faf.mp3    4   4   has uploaded a track.   testing 2012-08-31 00:32:56
    uploads/2b412dd197d464fedcecb1e244e18faf.mp3    4   4   has become an NBS artist.   testing 2012-08-31 00:32:56
    111 4   4   has become an NBS artist.   111111  0000-00-00 00:00:00
    111 4   4   has uploaded a track.   111111  0000-00-00 00:00:00
    

    正如您所看到的,查询会产生不需要的结果。每个URL的操作都在每个URL上给出,因此URL可以多次显示并且操作错误。因为该查询中只有曲目表,我想要显示的唯一操作是“已上传曲目。”

1 个答案:

答案 0 :(得分:2)

如果没有架构的完整详细信息,很难提供所需的语句。例如,问题涉及新闻表和艺术家表,但不提供这些表的模式,或指示包含这些引用的语句如何与问题中提到的任何其他表相关。

尽管如此,我认为你想要的东西可以完全在MySQL中完成,没有任何有趣的PHP技巧,特别是如果每​​个表中都有共同的字段。

但首先:这可能不是您真正想要的答案,但在各种表格上使用触发器来更新“事件提要”表可能是最佳解决方案。即,当在“状态”表上发生插入或更新时,在状态表上具有触发器,该触发器将“人”的ID及其动作类型插入“事件馈送”表中。您可以使用单独的插入和更新触发器来指示相同数据类型的不同事件。

然后有一个事件提要非常容易,因为您只是直接从该事件提要表中选择。

查看create trigger语法。

尽管如此,我想您可以查看CASEUNION个关键字。

然后,您可以构造一个查询,该查询从所有表中获取数据并输出指示某些内容的字符串。然后,您可以turn that query into a view,并将其用作“事件订阅源”表,直接从中选择。

假设您有一个成员列表(您这样做),以及包含这些成员操作的各种表(即曲目,状态,图片,视频),这些表都有一个指向您的成员表的键。您不需要从成员中选择生成活动列表,然后;您可以UNION将具有特定事件的表格放在一起。

SELECT
    events.member_id
  , events.table_id
  , events.table
  , events.action
  , events.when_it_happened
  , CASE
      WHEN events.table = "tracks" THEN "Did something with tracks"
      WHEN events.table = "status" THEN "Did something with status"
    END
    AS feed_description
FROM (
  SELECT
      tracks.ID AS member_id
    , tracks.track_ID AS table_id
    , "tracks" AS table
    , CONCAT(tracks.url, ' ', tracks.name) AS action
    , tracks.timestamp AS when_it_happened
  ORDER BY tracks.timestamp DESC
  LIMIT 10

  UNION

  SELECT
      status.ID as member_id
    , status.status_id AS table_id
    , "status" AS table
    , status.value AS action
    , status.timestamp AS when_it_happened
  ORDER BY status.timestamp DESC
  LIMIT 10

  UNION
  ...

) events
ORDER BY events.when_it_happened DESC

我仍然认为你最好创建一个由触发器构建的feed表,因为如果你比生成事件更频繁地查询feed,它会表现得更好。