php - mysql/php - 确定数据来自哪里

标签 php mysql

我需要确定新闻源的表数据来自哪个表。提要必须显示“此人已上传视频”或“此人已更新其个人简介”之类的内容。因此,显然,我需要确定数据来自哪里,因为不同类型的数据位于不同的表中。我希望您可以使用 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

Tracks 表,所有其他表几乎相同;

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 可能会多次显示且操作错误。因为该查询中只有轨道表,所以我想要显示的唯一操作是“已上传轨道”。

最佳答案

如果没有架构的完整详细信息,就很难提供您想要的语句。例如,问题引用了新闻表和艺术家表,但没有提供这些表的架构,也没有指出包含这些引用的语句如何与问题中提到的任何其他表相关。

不过,我认为您想要的事情可以完全在 MySQL 中完成,不需要任何有趣的 PHP 技巧,特别是如果每​​个表中都有公共(public)字段。

但首先:这可能不是您真正想要的答案,但在各个表上使用触发器来更新“事件源”表可能是最好的解决方案。即,当“状态”表上发生插入或更新时,在状态表上有一个触发器,将人员的 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 而不是生成事件,它的性能会好得多。

关于php - mysql/php - 确定数据来自哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12023315/

相关文章:

php - "Notice: Undefined variable"、 "Notice: Undefined index"、 "Warning: Undefined array key"和 "Notice: Undefined offset"使用 PHP

PHP DRUPAL : How to detect changes to table in database

php - 从多维数组的子数组中删除不需要的元素

mysql - .NET Core 2.0 与 MySQL : Specified key was too long; max key length is 3072 bytes

mysql - mysql中如何处理非标准日期格式?

mysql - 使用 SQL 或 PHP 选择值

php - Ajax登录脚本头问题

php - 抛出异常后分配的资源会怎样?

mysql - 带有 SUM 条件的 SELECT

mysql - 在单个查询中更新多个数据库记录(使用条件更新查询),具有相同的列值但不同的 ID