因此,我正在创建一个系统,该系统将一次从表中提取 50-150 条记录并将它们显示给用户,并且我试图为每条记录保留一个 View 计数。
我认为最有效的方法是创建一个 MEMORY 表,我使用 INSERT INTO 将行的 ID 拉入其中,然后有一个 cron 函数定期运行以聚合 View ID 计数并清除内存表,用最新的 View 计数更新原始表。这避免了不断更新可能最常访问的表,因此我不会在每个查询中一次锁定 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
,我会在 Postgres 中使用 OUTPUT
子句 - RETURNING
子句,在 MySQL 中 - ???我不认为它有这样的东西。因此,MySQL 过程将有几个单独的语句。
MySQL
首先执行您的SELECT
并将结果插入temporary (可能是内存)表。然后将项目 ID 从临时表复制到 Audit
表中。然后从临时表中SELECT
返回结果给客户端。
CREATE TEMPORARY TABLE TempTable
(
ItemID int NOT NULL,
Col1 ...,
Col2 ...,
...
)
ENGINE = MEMORY
SELECT ItemID, Col1, Col2, ...
FROM MainTable
WHERE <complex criteria>
;
INSERT INTO AuditTable (ItemID, RequestDateTime)
SELECT ItemID, NOW()
FROM TempTable;
SELECT ItemID, Col1, Col2, ...
FROM TempTable
ORDER BY ...;
SQL Server(只是逗你玩。这个语句同时执行 INSERT
和 SELECT
)
MERGE INTO AuditTable
USING
(
SELECT ItemID, Col1, Col2, ...
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 个月。但是,重要的是,所有这些摘要都是单独的 Audit
表,我们不会在 Main
表中保留审计信息,因此我们不需要更新它。
Joe Celko 在 SQL Style Habits: Attack of the Skeuomorphs 中解释得很好:
Now go to any SQL Forum text search the postings. You will find thousands of postings with DDL that include columns named
createdby
,createddate
,modifiedby
andmodifieddate
with that particular meta data on the end of the row declaration. It is the old mag tape header label written in a new language! Deja Vu!The header records appeared only once on a tape. But these meta data values appear over and over on every row in the table. One of the main reasons for using databases (not just SQL) was to remove redundancy from the data; this just adds more redundancy. But now think about what happens to the audit trail when a row is deleted? What happens to the audit trail when a row is updated? The trail is destroyed. The audit data should be separated from the schema. Would you put the log file on the same disk drive as the database? Would an accountant let the same person approve and receive a payment?
关于php - SQL INSERT INTO SELECT 并返回 SELECT 数据以创建行 View 计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32281469/