首页内容源全部用户是一致的,是若干新闻每个用户点开一个新闻后,该新闻将标记为“已读”,该用户再刷新首页这条新闻就在首页不存在了,也就是说首页仅存在用户未读过的新闻
那么这样的数据库表结构应如何设计?每个用户首页列出新闻的 SQL 语句应该是怎样的?
(主要的问题并不是如何设计表结构来储存用户“已读”的新闻,而是首页如何根据用户已读的新闻列出每个用户不同的首页内容,即首页 SQL 应该是怎样的)
小伙看你根骨奇佳,潜力无限,来学PHP伐。
这个问题是一个很综合的问题,不是单靠 SQL 就能很好解决的(虽然也能)。
新闻和每个人的已读状态,其实是一张二维表,横纵坐标分别是新闻ID和用户ID,这张二维表的大小是新闻数和用户数的乘积,那是相当的大。
所以,从建表来说,不管你是建一张新闻与用户的状态关系表,还是为用户建一张已读新闻状态表或者为新闻建一张已读用户状态表,都不是很好的方案。
如果是新闻用户状态关系表,假如有10,000用户,1,000新闻,这张表的数据在最大的情况会有10,000,000条记录。
建用户的新闻状态表和建新闻的用户状态表都一样,需要个巨大的字段,一般可能是TEXT和BLOB,非常不利用搜索。
在这种情况下,即使使用 No-SQL,都难以解决问题。所以需要变通。
首先一个问题,你显示在首页上的新闻可能会显示很旧的新闻么?换句话说,如果所有近一个月的新闻该用户都读完了,你会把上个月的新闻显示给他么……?不会吧!这样的话,新闻本身已经没有意义了。
那么,合理的作法是什么呢?应该是显示在某个时间段内的新闻,比如最近3天。先限定一个范围,然后再来思考这个范围内的逻辑。
但是要加一个逻辑处理,就是这3天的新闻,用户都看完了怎么办?理论上来说,应该显示最新的新闻出来,即使已经看过了。
当然这只是一个粗略的分析,具体是什么情况我并不清楚,需要你自己根据需求去研究细化。
近3天的新闻已经是一个不大的量了,在这个范围内,完全可以按照之前的想法进行实施,不管用上面哪种方法,都不会有巨大的数据量(当然要记得删旧数据,即3天前的相关数据)。
给每篇文章一个独立的id给每个用户一个已读的列把它看到的文章的id保存到这个列刷新首页里判断一下,如果提取的新闻的id已经在他的已读列里,不显示;然后再提取一次。
使用中间表存储新闻与用户的关系,并保存已读标记,不过如果是互联网方面产品不建议没次读数据库,可以通过缓存等来提高访问效率
取新闻的时候,就不要取已读ID的新闻不就行了吗?select news.news from isread_news,news where isread_news.id <> news.id
select * from news where Id not exists(select news_id from red_news where user_id = ?) limit 10;
这个问题是一个很综合的问题,不是单靠 SQL 就能很好解决的(虽然也能)。
按你的思路分析技术可行性
新闻和每个人的已读状态,其实是一张二维表,横纵坐标分别是新闻ID和用户ID,这张二维表的大小是新闻数和用户数的乘积,那是相当的大。
所以,从建表来说,不管你是建一张新闻与用户的状态关系表,还是为用户建一张已读新闻状态表或者为新闻建一张已读用户状态表,都不是很好的方案。
如果是新闻用户状态关系表,假如有10,000用户,1,000新闻,这张表的数据在最大的情况会有10,000,000条记录。
建用户的新闻状态表和建新闻的用户状态表都一样,需要个巨大的字段,一般可能是TEXT和BLOB,非常不利用搜索。
在这种情况下,即使使用 No-SQL,都难以解决问题。所以需要变通。
分析合理的需求
首先一个问题,你显示在首页上的新闻可能会显示很旧的新闻么?换句话说,如果所有近一个月的新闻该用户都读完了,你会把上个月的新闻显示给他么……?不会吧!这样的话,新闻本身已经没有意义了。
那么,合理的作法是什么呢?应该是显示在某个时间段内的新闻,比如最近3天。先限定一个范围,然后再来思考这个范围内的逻辑。
但是要加一个逻辑处理,就是这3天的新闻,用户都看完了怎么办?理论上来说,应该显示最新的新闻出来,即使已经看过了。
当然这只是一个粗略的分析,具体是什么情况我并不清楚,需要你自己根据需求去研究细化。
合理需求下的实现
近3天的新闻已经是一个不大的量了,在这个范围内,完全可以按照之前的想法进行实施,不管用上面哪种方法,都不会有巨大的数据量(当然要记得删旧数据,即3天前的相关数据)。
给每篇文章一个独立的id
给每个用户一个已读的列
把它看到的文章的id保存到这个列
刷新首页里判断一下,如果提取的新闻的id已经在他的已读列里,不显示;
然后再提取一次。
使用中间表存储新闻与用户的关系,并保存已读标记,不过如果是互联网方面产品不建议没次读数据库,可以通过缓存等来提高访问效率
取新闻的时候,就不要取已读ID的新闻不就行了吗?select news.news from isread_news,news where isread_news.id <> news.id
select * from news where Id not exists(select news_id from red_news where user_id = ?) limit 10;