您可以使用时间戳列,甚至可能使用主键本身来执行此操作,具体取决于您的设置方式。如果主键是AUTO_INCREMENT 整数,这是一个使用主键的示例。
CREATE TABLE `comments` (
`comment_id` int NOT NULL AUTO_INCREMENT,
`thread_id` int NOT NULL,
`comment` text,
PRIMARY KEY (`comment_id`),
FOREIGN KEY (`thread_id`) REFERENCES `threads` (`thread_id`)
);
在该表定义中,您有一个 AUTO_INCREMENT int 主键。您还有一个thread_id,它是threads 表的外键。最后,您在comment 中有评论本身。
当您第一次为某个线程加载页面时,您需要执行以下操作:
SELECT comment_id, comment
FROM comments
WHERE thread_id = 123
ORDER BY comment_id
LIMIT 10;
这意味着您将为您的给定线程选择 10 个按 int PK 排序的 cmets(在本例中为 123)。现在,当您显示此内容时,您需要以某种方式保存最大的comment_id。在这种情况下说它是10。然后,让“加载更多 cmets”按钮在单击时将这个最大的 comment_id 传递给服务器。服务器现在将执行以下操作:
SELECT comment_id, comment
FROM comments
WHERE thread_id = 123 AND comment_id > 10 -- 10 is the value you passed in as your largest previously loaded comment_id
ORDER BY comment_id
LIMIT 10;
现在您有一组另外十个 cmets,您知道没有一个 cmets 可能与您之前显示的 cmets 重复,并且您永远不会跳过任何 cmets,因为它们总是按升序排列 int 键.
如果您现在回顾一下用于加载初始 cmets 集的查询,您会发现它与加载其他 cmets 的查询几乎相同,因此您实际上可以对两者使用相同的查询。当您最初加载 cmets 时,只需将 0 作为最大的 comment_id 传递。
如果您没有像这样工作的主键,您也可以使用timestamp 列执行相同的操作,并且您也不想将其更改为像这样工作。您只需按timestamp 列对结果进行排序,然后将最后加载的评论的timestamp 传递给您的“加载更多 cmets”函数。为了避免跳过同时发布的 cmets,您可以使用具有六位小数秒精度的 timestamp。将timestamp 列创建为TIMESTAMP(6)。然后,您的时间戳将被记录为2014-09-08 17:51:04.123456 之类的东西,其中第二个后的最后六位数字是一秒的小数。有了这么高的精度,您几乎不可能同时记录 cmet。
当然,您仍然可以在相同的确切时间戳记录两个或更多 cmets,但这不太可能。这使得 AUTO_INCREMENT int 成为一个更好的解决方案。最后一个选项是使用基于时间的UUID,因为它们包含一种机制,通过在同一微秒内发生事情时稍微调整值来确保唯一性。它们也仍然按时间排序。这样做的问题是 MySQL 对 UUID 的支持不是很好。