上下文:
user_feed
表存储在MariaDB
数据库InnoDB
存储引擎清晰度说明:在整个问题中,每当我使用术语“用户的”和“#34;我所指的是user_feed
表中为user_id
字段设置相同值的所有记录。
因此,最初,在登录时,用户会获得前40个帖子,这些帖子的用户ID为user_feed
表中的外键。该查询使用ORDER BY date_created
子句获取前40个帖子。当用户向下滚动时,让我们说第30号帖子,我想在他们的Feed中查询接下来的40个帖子。现在,我计划使用用户在应用中发布的上一篇文章创建的日期,以确定从user_feed
表格中获得哪些帖子。
我的问题是:如果我将帖子的date_created
时间戳设置到user_feed
表格中,那么针对特定用户的Feed的两个帖子是否可能会有相同的时间戳?
user_feed表:
CREATE TABLE `user_feed` (
`user_id` int(1) unsigned NOT NULL,
`post_id` int(1) unsigned NOT NULL,
`reposter_id` int(1) unsigned DEFAULT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`,`post_id`),
KEY `user_id` (`user_id`),
KEY `date_created` (`date_created`),
KEY `post_id` (`post_id`),
KEY `reposter_id` (`reposter_id`),
CONSTRAINT `user_feed_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `user_feed_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
更新:因此,将时间用作确定唯一性的指示因素所需的复杂性似乎是不可能的。下一个选项是让列id
随每个新帖子递增,这样我就可以在user_feed
表中查询与特定user_id
对应的下40条记录,并且id
小于从上一个查询收到的第40个帖子的ID。但是,这种方法似乎也存在一些问题:
其一,用户的Feed不能包含相同post_id
的记录,即如果您查看用户的整个Feed,则不会看到两条与同一篇文章。这意味着,无论何时进行重新发布,如果特定用户的订阅源包含与重新发布的记录具有相同post_id
的记录,则必须进行删除。然后,将插入一个设置了reposter_id
字段的新记录。另一种选择是通过将reposter_id
字段设置为转发器的ID并将date_created
字段设置为重新发布的日期来更新现有记录。使用更新似乎更有效,但是使用新的auto_incrementing id
列,我必须通过获取下一个可能的auto_increment值手动更新auto_incrementing列,并使用它来更新id
字段。
我看到的直接问题是:如果新的重新发布的id
字段正在更新,则另一位用户会为此用户的Feed创建一个帖子,因为{{ 1}}列不需要手动设置新帖子(id
的{{1}}以前从未存在过的id
永远不会在post
表中“创建新发布的记录比另一条记录的更新更快,并且具有为更新检索的相同user_feed
;导致主键已存在异常。
使用整个表格的唯一id
列似乎存在的另一个问题是,如果每个帖子的单个帖子都有一个唯一的id
,那么它就会被提供给它。如果你现在还没有注意到的话,那就放入 - 扇出系统以获取用户的饲料。而且,一个帖子可以重新发布数百万次,因此每个帖子也会有一个独特的id
。看起来id
列的值会增加得太快,除非每个用户的Feed都有自己的auto_incrementing字段,即获得用户的下一个最高id
值&# 39; s feed我必须在以下查询的结果中加1:
id
关于上述两点的任何反馈意见?
答案 0 :(得分:0)
多么糟糕的网络。让我们从一些原则开始......
客户端扫描列表时可能会发生插入,替换和删除吗?
表格中的每一行都需要一个唯一的密钥。这应该是PRIMARY KEY
,也可以是id .. AUTO_INCREMENT
。
您要获取按时间排序的一个或多个行。建议INDEX(date_created, id)
。这是有序的,没有重复(因为id
)。无需说UNIQUE
而不是INDEX
。 Do not use OFFSET
您需要替换现有项目。为此,您需要一个唯一的密钥。它可以是id
,如果您可以保持该值,直到您需要进行替换。或者,您可以使用唯一的列(或列的组合),以确定要重新插入或替换或更新的行。请注意,您可能希望保留旧的时间戳。如果id改变,你可能不在乎;在重复时间戳的罕见情况下,可以交换这对项目。