您的位置:首页 > 编程语言 > Java开发

在java eye看到的一篇关于论坛数据库设计的文章

2010-03-25 22:30 585 查看
最近在做的一个东西,发现大数据量排序都是一个不小的问题。正好今天在javaeye index上看到了这篇贴子,用以提醒自己,不要把问题想的太简单。一个高压力系统需要设计上的支持,而不仅仅是硬件。服务器对硬件的需求是永无止境的。

一个简单的论坛系统,以数据库储存如下数据:
用户名,email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容。

每天论坛访问量300万左右,更新帖子10万左右。

请给出数据库表结构设计,并结合范式简要说明设计思路。

这是我看见的百度面试题,以前也在cdsn上面看见过类似的问题,没有仔细想就写了自己的见解和答案,很可惜我以前的想法是错误的;算是误人子弟阿,郁闷!因此我还是先把和几个朋友讨论的结果和自己的想法做一个总结,算是弥补我以前想法造成别人曲解的过错;

首先,我们先来分析一下这道面试题:用户名,email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容。这些字段可以基本归为三类:

1、用户基本信息:用户名(UserName),email(Email),主页(HomePage),电话(Tel),联系地址
(Address);

2、发帖主题信息:发帖标题(Title),发帖内容(Content);

3、回复信息:回复标题(RTitle),回复内容(RContent);

以上一步有基本开发经验的人都知道,只是对基本的信息进行划分;相信将用户基本信息存放在一

张表内不会有什么好讨论的,我创建一张表叫T_Users,并建立主键UserID,用户基本信息所需要存放的内容都放置在此表内;那么是应该把发帖主题和回复信息分别创建两张表存放数据呢还是应该存放在一张表内?字段内容还是比较接近的,因此从数据冗余的角度看,一张表和两张表在此方面的区别并不影响设计;

假设按照大多数论坛的设计思路,将2、3设计成两个表T_Topics和T_Reverts后,再来分析看看是否合适这里的要求;

现在“每天论坛访问量300万左右,更新帖子10万左右”对这句话进行分析,才是这个面试题的关键所在。面试题显然要求在操作数据库的性能方面要有更高的要求。而对数据库的操作而言,检索数据的性能基本不会对数据造成很大的影响(精确查找的情况下),而对表与表之间的连接却会产生巨大的影响,特别在有巨量数据的表之间;而对数据库的连接也是相当消耗性能的操作(这在ADO.NET的教程中都多次提醒的);

因此对问题的定位基本可以确定:在显示和检索数据时,尽量减少数据库的连接以及表与表之间的连接;

解决问题的指导性原则找到了,那就来看看,从上面的设计中,有哪一些地方会产生我们提到的表与表之间的连接;(连接数据库的次数尽量减少到每打开一个页面只连接一次数据库就可以得到所有的数据)1、用户基本信息中的用户名在发帖主题列表以及打开一个主题查看回复内容时上面会有所显示,需要在T_Users和其他两张表进行连接;2、在打开一个主题查看回复内容时,需要在T_Topics和T_Reverts之间进行连接;

其他应该是不需要产生表与表之间的连接;按照面试题来推测:T_Users的数据量应该在1万-10万之间,T_Topics应该在100-1000万之间,T_Reverts应该在1000万-1亿之间;从上面两类连接可以看出来,T_Users和T_Topics会在列表页面连接一次;T_Users、T_Topics和T_Reverts三张表会连接一次;

我说不上来第一种连接是否可以允许(至少在我开发的系统里面都是允许的),但是另外三张表连接是绝对不会允许的!特别是T_Topics和T_Reverts两表之间的连接会产生很大的性能损耗,因此需要避免这样的情况产生。

那怎么样的设计可以避免T_Topics和T_Reverts两表之间的连接呢?前面已经进行了分析:可以考虑把发帖主题和回复信息存放在一张表(T_Infos)里面,看看是否可以解决这个问题;

我们设计一个字段
(Flag)来标记是主题还是回复的内容;设计一个字段(ParentID,主题此字段为ID值)来指定是哪一个特定主题的回复;在开打回复信息时,只需要按照所知道的主题ID,就可以检索到这个主题的内容以及所有的回复内容,上面指出的问题就可以解决!

为了性能,我们再一次对T_Users和T_Infos连接对性能的影响进行一下细致的分析,可以通过在T_Infos表内增加UserName字段来解决和它的连接,这样至少在显示时,性能能够得到保证。但是这样的设计因为UserName字段是冗余的,因此在用户修改UserName的时候就会产生同步数据的问题,这个需要程序来进行弥补,并是我们认为用户不会经常性的修改他的用户名这样的前提下。

因此这道面试题的答案应该是设计两张表,用户基本信息表T_Users和内容表T_Infos,这两张表的连接还是通过UserID,但是T_Infos中增加UserName这个字段来增加性能。

上面的面试题算是分析完了,但是从这道题目的分析中我们可以看出来,这样的设计是建立在“一个简单的论坛系统”这样的基础上的极端事例,在我们真实的世界中,不太会有很多的人喜欢这样简单的论坛,而且这样的论坛在扩展性方面会产生很大的限制;这算不算这道题目是应试教育的产物呢?而且在设计的时候不仅仅是为了适应现在系统的需求还需要提供将来新的要求的变化,因此在实际的开发过程中间并不推荐使用这道面试题的答案。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐