php – SQL INSERT INTO SELECT并返回SELECT数据以创建行视图计
所以我正在创建一个系统,它将从表中一次拉出50-150条记录并将它们显示给用户,并且我正在尝试为每条记录保留一个视图计数.
我认为最有效的方法是创建一个MEMORY表,我使用INSERT INTO将行的ID拉入,然后有一个cron函数定期运行以聚合视图ID计数并清除内存表,更新具有最新视图的原始计数.这样可以避免不断更新最可能被访问的表,因此我不会在每次查询时一次锁定150行(如果我使用的是MyISAM,则不是整个表). 基本上,该方法解释了here. 但是,我当然希望在我提取记录信息以供查看的同时执行此操作,并且我希望避免运行第二个单独的查询,以便为其计数获取相同的数据集. 有没有办法选择数据集,返回该数据集,同时将该数据集中的单个列插入另一个表? 看起来PostgreSQL可能有类似于我想要的RETURNING关键字,但我正在使用MySQL.
首先,我不会在Main表中添加计数器列.我将创建一个单独的Audit表,该表将保留Main表中项的ID以及请求该ID时的至少时间戳.实质上,Audit表将存储请求的历史记录.在这种方法中,您可以轻松生成更有趣的报告.您始终可以计算每个项目的总计,还可以按每个项目或所有项目按天,周,月等计算摘要.根据数据量,您可以定期删除超过某个阈值(一个月,一年等)的审核条目.
此外,您可以根据需要在Audit表中轻松存储更多信息,例如,用户ID来计算每个用户的统计信息. 要“自动”填充Audit表,我将创建一个存储过程.客户端代码将调用此存储过程而不是执行原始SELECT.存储过程将返回与原始SELECT完全相同的结果,但也会向Audit表透明地向客户端代码添加必要的详细信息. 所以,我们假设Audit表看起来像这样: CREATE TABLE AuditTable ( ID int IDENTITY -- SQL Server SERIAL -- Postgres AUTO_INCREMENT -- MySQL NOT NULL,ItemID int NOT NULL,RequestDateTime datetime NOT NULL ) 你的主要SELECT看起来像这样: SELECT ItemID,Col1,Col2,... FROM MainTable WHERE <complex criteria> 要在SQL Server中的一个语句中执行INSERT和SELECT,我将使用OUTPUT子句,在Postgres – RETURNING子句中,在MySQL中 – ???我不认为它有这样的东西.所以,MySQL程序会有几个单独的语句. MySQL的 首先执行SELECT并将结果插入到temporary(可能是内存)表中.然后将项目ID从临时表复制到Audit表中.然后从临时表中选择SELECT以将结果返回给客户端. CREATE TEMPORARY TABLE TempTable ( ItemID int NOT NULL,Col1 ...,Col2 ...,... ) ENGINE = MEMORY SELECT ItemID,... FROM MainTable WHERE <complex criteria> ; INSERT INTO AuditTable (ItemID,RequestDateTime) SELECT ItemID,NOW() FROM TempTable; SELECT ItemID,... FROM TempTable ORDER BY ...; SQL Server(只是为了取笑你.这个单个语句同时执行INSERT和SELECT) MERGE INTO AuditTable USING ( SELECT ItemID,... FROM MainTable WHERE <complex criteria> ) AS Src ON 1 = 0 WHEN NOT MATCHED BY TARGET THEN INSERT (ItemID,RequestDateTime) VALUES (Src.ItemID,GETDATE()) OUTPUT Src.ItemID,Src.Col1,Src.Col2,... ; 您可以按原样保留Audit表,也可以设置cron以定期对其进行汇总.这实际上取决于数据量.在我们的系统中,我们存储了一周的单个行,另外我们总结了每小时的统计数据并将其保留了6周,此外我们将每日摘要保存18个月.但是,重要的是,所有这些摘要都是单独的审计表,我们不会在主表中保留审计信息,因此我们不需要更新它. Joe Celko在SQL Style Habits: Attack of the Skeuomorphs年解释得非常好:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |