> For the complete documentation index, see [llms.txt](https://protegejj.gitbook.io/system-design/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://protegejj.gitbook.io/system-design/design-rss-reader.md).

# Design RSS Reader

## Desgin RSS Reader

## 1. Scenario

a. user login/register

b. user subscribe/unsubscribe publisher

c. news feed sorted by publish time

d. 区分read和unread, 一键标记未读为已读

## 2. Service

a. User Service(login/register)

b. RSS Service(news feed)

c. Subscription Service(subscribe/unsubscribe publisher)

## 3. Storage

user table: {user\_id, user\_name, password}

publisher table: {publisher\_id, url}

posts table: {post\_id, publisher\_id, publish\_time, post\_title, post\_content}

feed table: {feed\_id, user\_id, post\_id, create\_time}

subscription table: {subscription\_id, user\_id, publisher\_id}

read status table: {post\_id, user\_id}， 建立index(composite index， user id + post id)只有看过的post会放到这个table里面

## 4. Scale

a. Pull VS Push Model

分publisher和user的角度展开:

如果publisher的subscribed user很多，用pull model好些，反之可以用push model

如果一个用户subscribe很多频道，用push model。如果用户subscribe频道少，用push model.

b. 实现一键标记未读post为已读功能:

(1) 是否可以考虑在客户端解决已读/未读问题？ 比如mobile里记录已读的信息，但缺点是这个方法不能跨平台。

(2) 首先考虑的问题是在rss read中unread的多还是read的多？ 如果unread的多，我们可以存read的post id + user id到read status table

利用read\_status table，每当user看了一个帖子后，我们就把user id和对应的post id插入这个table中。但这个做法的缺点是数据量会很大(user数量 \* post数量)。可以根据不同维度拆分，比如老的消息基本没人看就按时间拆分(比如根据用户last login timestamp，每当用户login后，自动将之前的未读的mark成已读)，如果绝对部分用户不看的就按用户活跃度拆分等方式
