0

我需要确定新闻提要的表格数据来自什么。提要必须显示“人员已上传视频”或“人员已更新其个人简介”之类的内容。因此,很明显,我需要确定数据来自哪里,因为不同类型的数据位于不同的表中。我希望你可以用 SQL 做到这一点,但可能不是这样 PHP 是选项。我不知道如何做到这一点,所以只需要指出正确的方向。

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

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

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

  2. 其他表格包括;曲目,状态,图片,视频。从那里开始,一切都非常不言自明。

我需要以某种方式确定更新数据来自哪个表,以便我可以告诉用户某某做了什么。最好我只需要一个用于整个提要的 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 ;

更新!

我现在按照建议创建了一个名为 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

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

4

1 回答 1

2

如果没有架构的完整详细信息,很难提供您想要的语句。例如,该问题引用了一个 news 表和一个 Artists 表,但没有提供这些表的架构,也没有说明包含这些引用的语句与问题中提到的任何其他表的关系。

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

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

那么拥有一个事件源会非常容易,因为您只是直接从该事件源表中选择。

查看创建触发器语法。

也就是说,我想你可能会看看CASEUNION关键字。

然后,您可以构建一个查询,从所有表中获取数据并输出指示某些内容的字符串。然后,您可以将该查询转换为视图,并将其用作“事件提要”表以直接从中进行选择。

假设您有一个成员列表(您这样做),以及包含来自这些成员的操作(即,曲目、状态、图片、视频)的各种表,它们都有一个指向您的成员表的键。然后,您无需从成员中进行选择来生成活动列表;您可以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

我仍然认为您最好创建一个由触发器构建的提要表,因为如果您更频繁地查询提要而不是生成事件,它将执行得更好。

于 2012-08-19T03:00:57.113 回答