出于速度和维护历史记录的目的,我创建了一个仅插入表。它的结构非常通用,如下所示:
`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
假设您的 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)