SQL仅插入表,如何仅选择最新条目

cru*_*ush 2 mysql sql

出于速度和维护历史记录的目的,我创建了一个仅插入表。它的结构非常通用,如下所示:

  `id` bigint(20) unsigned NOT NULL auto_increment,
  `user_id` bigint(20) unsigned NOT NULL,
  `property` varchar(32) NOT NULL,
  `value` longblob NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

它只是一个分配了 user_id 的键/值表。这种方法有其优点,因为并非所有用户都具有相同的属性,因此表中的字段不会浪费。此外,它还允许滚动更改日志,因为我可以看到用户对特定属性所做的每项更改。

现在,由于该表中从未发生过删除或更新,因此我可以假设最大的 id 将始终是最新的条目。

但是,我想一次选择多个属性,例如“address1”、“address2”、“city”、“state”,并且我希望每个属性都是具有最高 id 的类型条目。

因此,如果他们更改了“州”属性 8 次,“城市”属性更改了 4 次,那么我只希望 SELECT 返回每个属性的最新值(1 个州和 1 个城市)。

我不确定使用这种类型的表是否可以有效地完成此操作,因此我对不同的表方法持开放态度。

如果我需要提供更多信息或更好地澄清我的问题,请告诉我。

=== 我尝试了以下操作,但是,在最后一次“address2”更改之后可能会有 3 行“address1”更改。也许使用 GROUP BY 会起作用?

SELECT property, value FROM kvtable WHERE user_id = 1 AND (property = 'address1' OR property = 'address2') ORDER BY id

Mic*_*ski 5

假设您的 id 是增量整数,并且您没有手动乱序指定它们MAX(),则可以在子查询中使用一些聚合来完成此操作。子查询的要点是返回每个用户的每个属性名称的最新条目。它将与整个表连接起来以提取关联的属性值。本质上,子查询会丢弃每组没有 max(id) 的所有行。

SELECT kvtable.* 
FROM
  kvtable
  JOIN (
    SELECT
      MAX(id) AS id,
      user_id,
      property
    FROM kvtable
    /* optionally limit by user_id */
    WHERE user_id = <someuser>
    GROUP BY user_id, property
  ) maxids ON kvtable.id = maxids.id
Run Code Online (Sandbox Code Playgroud)

  • `(user_id, property)` 上的索引将有助于提高性能(它将由子查询使用)。 (2认同)