京山游侠

专注技术,拒绝扯淡
posts - 50, comments - 868, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

为我的创业网站创建数据库

Posted on 2008-01-24 22:05 京山游侠 阅读(2502) 评论(6)  编辑  收藏 所属分类: J2EE学习及探索

这里的文字主要是为了记录下我的一些思路,以防日后遗忘。中途会经历相当多的修改。有兴趣的朋友欢迎指教。

关于我的网站应该提供一些什么样的功能、使用什么样的用户交互方式,雏形在我的脑中基本已经形成了,但是还不系统。我需要赶快把它们记录下来,免得以后忘了。当然,在开发的过程中,我的思路随时都会发生变化,因此这里记下的东西也会发生很多修改。一想到网站的功能,马上就会想到要设计什么样的数据库来支持它。所以,这里的记录主要是怎么设计数据库。

数据库软件使用MySQL,先修改my.ini配置文件,默认使用UTF-8编码、InnoDB数据库引擎,并启动二进制日志,以使得数据库备份的工作变简单些。

default-character-set = utf8
datadir
= " D:/MySQL_Data/ "

innodb_data_home_dir 
=  ./ibdata
innodb_log_group_home_dir 
=  ./ibdata
innodb_data_file_path 
=  ibdata1:50M:autoextend:max:1G

log-bin 
=  ./bin_log/binlog
binlog-do-db 
=  YumDaysIndex
binlog-do-db 
=  YumDays001

然后开始创建数据库,经过前面在网站架构方面的设想,我需要创建最少两个数据库:一个索引数据库,一个或多个内容数据库。我把索引数据库命名为YumDaysIndex,内容数据库命名为YumDaysNNN,其中的NNN是数字编号,在刚开始的时候,肯定只要一个YumDays001就够了。
GRANT ALL PRIVILEGES ON YumDaysIndex.* TO '********'@'%' IDENTIFIED BY '********' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON YumDays001.* TO '********'@'%' IDENTIFIED BY '********' WITH GRANT OPTION;
CREATE DATABASE YumDaysIndex;
CREATE DATABASE YumDays001;

选择YumDays001数据库,创建用户表:
 USE YumDays001; 

 
CREATE TABLE users(
   id 
char(32NOT NULL PRIMARY KEY,
   name 
varchar(30NOT NULL,
   password 
char(32NOT NULL,
   monicker 
varchar(30NOT NULL,
   question 
varchar(30NOT NULL,
   answer 
varchar(30NOT NULL,
   email 
varchar(30NOT NULL,
   qq 
varchar(12NOT NULL,
   roleid 
char(32NOT NULL,
   score 
int NOT NULL DEFAULT 0,
   albumusage 
int NOT NULL DEFAULT 0,
   regtime 
timestamp NOT NULL DEFAULT '2008-01-01 00:00:00',
   logintime 
timestamp NOT NULL DEFAULT '2008-01-01 00:00:00',
   isdeleted 
varchar(2NOT NULL DEFAULT '0',
   
INDEX(name),
   
INDEX(monicker)
 );

这样一些字段分别代表ID、用户名、密码、昵称、密码问题、答案、email、QQ号、用户角色、积分、相册已经使用的磁盘空间、注册时间、登录时间、是否删除等。设计这个表的思路如下:
1、name只能用英文,因为它将是URL的组成部分,为了便于用户之间的识别,所以需要monicker(昵称)字段;
2、根据用户的score字段可以算出用户的相册容量,每次上传图片的时候,都增加albumusage字段的值,如果空间已经被使用完,则不容许上传;
3、ID使用UUID类型,所以它的列类型为char(32),之所以使用UUID,是因为users表会被分割到很多个数据库中,使用UUID可以保证ID的唯一性;
4、isdelete的列类型也比较奇怪,为varchar(2),而默认值却是'0'(字符串),这是因为SpringSide的实现中,在删除数据的时候,会把这个字段设置为'-1'(字符串)。

从这个表中可以看出,这里涉及到一个用户角色的问题,不同的角色拥有不同的权限,所以需要一个Roles表。考虑到Roles表包含的记录数不会太多,而且分布到多个服务器上也不好维护,所以Roles表应该放到索引服务器中。用户登录这样的过程也应该由索引服务器处理,然后将用户的一些信息保存到Cookie中,不过如果用户操作的时候需要查看权限,则一定要向索引服务器请求,索引服务器通过提供WebService来响应请求,因为在Cookie中保存权限会出现安全问题。

创建Roles表的代码如下:
USE YumDaysIndex;

 
CREATE TABLE roles(
   id 
char(32NOT NULL PRIMARY KEY,
   name 
varchar(20NOT NULL,
   privilegesflag 
varchar(255),
   
INDEX(name)
 );

这里需要说明的是privilegesflag字段,该字段我设计为一个用逗号隔开的字符串,比如“post,reply”,代表用户具有发帖、回帖的权限。这么设计的好处就是在开发过程中,不用为了增加权限而修改数据表的结构,只用往这个表中加入新的字符串就行了,而Java代码中,分割字符串又是那么的方便。

在这个表中,我初步设计的角色有四个,它们分别是管理员、超级用户、普通用户和被锁定用户。当然,如果网站规模越来越大,需要有人帮着把关时(否则肯定黄帖广告贴泛滥),可能需要版主、编辑这样的角色。

在我刚开始设计这个系统时,本来是加入了用户群组的功能的,但是经过这两天的沉淀,我决定暂时还是不要这个功能了。以后再加上都可以,但是开发初期我不想为自己找太多麻烦。

文章要进行分类,因此需要创建一个分类表,这个表依然保留在索引服务器上:
 CREATE TABLE catalogs(
   id 
char(32NOT NULL PRIMARY KEY,
   name 
varchar(20NOT NULL,
   
INDEX(name)
 );

这个表的内容很简单,无需解释。

再下面,就是用来保存文章的表了:
USE YumDays001

 
CREATE TABLE topics(
   id 
char(32NOT NULL PRIMARY KEY,
   catalogid 
char(32NOT NULL,
   subject 
varchar(60DEFAULT NULL,
   content 
text,
   summary 
varchar(300default NULL,
   mainpicture 
varchar(100NOT NULL,
   userid 
char(32NOT NULL,
   time 
timestamp NOT NULL default CURRENT_TIMESTAMP,
   lastedittime 
timestamp NOT NULL default '2007-01-01 00:00:00',
   lastreplytime 
timestamp NOT NULL default '2007-01-01 00:00:00',
   visitcount 
int NOT NULL,
   accessmod 
tinyint NOT NULL,
   
INDEX(subject),
   
INDEX(userid),
   
INDEX(time),
   
INDEX(lastreplytime)
 ); 

该表应该保存到内容数据库中。其中的字段都很好理解,从名字即可看出意义。其中需要解释的两个字段如下:
1、mainpicture:我希望每一篇文章都有一个主题图片,该图片在显示文章列表的时候也可以显示(当然是缩略图)。其内容是一个URL。
2、accessmod:该字段保存了该文章的安全属性,即是否公开。取值为1则不公开,取值为3则完全公开。那么2呢?那是我为用户群保留的,取值为2则只正对该文章所属的群公开。
至于索引,那是要根据网站需要提供什么样的功能来设计的。当网站需要按照哪一个规则对文章进行查找的时候,就要在该字段上建立索引,以便加快查找速度。

再往下,则是用来保存回复的表:
 CREATE TABLE replys(
   id 
char(32NOT NULL PRIMARY KEY,
   subject 
varchar(50NOT NULL,
   content 
text,
   userid 
char(32NOT NULL,
   time 
timestamp NOT NULL default CURRENT_TIMESTAMP
 );

自己回复了哪些文章,心里也要有个数,所以要建立一个表,用来记录用户参与了的文章:

 CREATE TABLE participation(
 id 
char(32NOT NULL PRIMARY KEY,
 userid 
char(32NOT NULL,
 topicid 
char(32NOT NULL,
 
INDEX(userid)
 );

再然后,是用来管理相册和相片的表:
 create table albums(
   id 
char(32NOT NULL PRIMARY KEY,
   userid 
char(32NOT NULL,
   name 
varchar(20NOT NULL,
   description 
varchar(200DEFAULT NULL,
   photopath 
varchar(30NOT NULL,
   miniphotopath 
varchar(30NOT NULL,
   accessmod 
tinyint NOT NULL,
   
INDEX(userid)
 );

这里的photopath是该相册在服务器上的文件路径,而miniphotopath则是缩略图的路径。accessmod也是起安全控制作用的,意义同前。

 CREATE TABLE photos(
   id 
char(32NOT NULL PRIMARY KEY,
   albumid 
char(32NOT NULL,
   filename 
varchar(20NOT NULL,
   
INDEX(albumid)
 );

这样,内容数据库的表已经差不多了,剩下的在开发过程中再逐步完善。而索引服务器还只有前面提到的Roles表和Catalogs表,但是索引服务器要提供显示首页的功能,要提供反向代理的功能,要提供统计排序的功能。因此,我在索引数据库中设计了以下表。

首先,索引服务器中也应该保存有Users的所有数据,需要保存所有的记录,但是不需要保存所有的字段。初步的设计如下:
USE YumDaysIndex;

 
CREATE TABLE users(
   id 
char(32NOT NULL PRIMARY KEY,
   name 
varchar(30NOT NULL,
   password 
char(32NOT NULL,
   monicker 
varchar(30NOT NULL,
   roleid 
char(32NOT NULL,
   score 
int NOT NULL DEFAULT 0,
   webserver 
varchar(10NOT NULL,
   
INDEX(name),
   
INDEX(score)
 );

 这里保存有用户的验证信息,因此简单的验证功能都可以通过索引服务器来完成。这里有两个字段值得一提,一是score,用来保存用户的分数,主要是为了实现用户排名;另一个字段是webserver,它保存了该用户会被分配到那个Web服务器。

索引服务器还应该保存所有Topics的记录,当然,它不需要保存所有的字段,和Users表一样,它只需要知道到哪个Web服务器可以找到这个Topic的所有数据就行了。初步设计如下:

 CREATE TABLE topics(
 id 
char(32NOT NULL PRIMARY KEY,
 catalogid 
char(32NOT NULL,
 time 
timestamp NOT NULL default CURRENT_TIMESTAMP,
 webserver 
varchar(10NOT NULL,
 
INDEX(time)
 );

这个表非常简单,只是维护了一个所有Topic的索引而已,通过webserver字段就知道到哪里找它的详细信息,索引服务器显示主页的时候,可以通过AJAX调用相应的webserver来显示它的摘要信息。time字段是用来排序的,catalog字段是用来分类的。

我还有一个想法,就是想能够按照最新的回复来对Topic进行排序,基本上所有的论坛都是采取的这种方法,只需要有人回复,文章就会被顶上去。但是,由于Topics是分布存储的,所以需要有一个表用来保存最近被回复的文章的信息,而其它的服务器则可以通过定时服务,每隔几分钟在自己的服务器上统计最新被回复的文章,然后提交到索引服务器。其结构如下:

 CREATE TABLE hottopics(
   id 
char(32NOT NULL PRIMARY KEY,
   subject 
varchar(60NOT NULL,
   lastreplytime 
timestamp NOT NULL default '2007-01-01 00:00:00',
   sebserver 
varchar(10NOT NULL,
   
INDEX(lastreplytime)
 );

这个表,只需要保存少量的纪录就够了。

还要一个统计表,维护一些统计信息,如注册用户数、文章总数、回复总数、响应新用户注册的当前服务器等等,如下:

 CREATE TABLE statistic(
   usercount 
int NOT NULL,
   topiccount 
int NOT NULL,
   replycount 
int NOT NULL,
   currentwebserver 
varchar(10NOT NULL
 );

这个表的名字是单数形式,因为这个表只需要一条纪录就够了。

索引服务器还需要维护所有的相册信息,同Topics表一样,其结构如下:

 CREATE TABLE albums(
   id 
char(32NOT NULL PRIMARY KEY,
   time 
timestamp NOT NULL default CURRENT_TIMESTAMP,
   webserver 
varchar(10NOT NULL,
   
INDEX(time)
 );

数据库的设计到此告一段落,下一步就开始写代码了。数据库设计中的缺陷,只有经过实战的检验才能够体现出来。


评论

# re: 为我的创业网站YumDays创建数据库  回复  更多评论   

2008-01-27 21:01 by 海边沫沫
目前能够想得到的缺陷:
1、是否有必要不做物理删除?如果有必要的话,Topics表、Albums表、Replys表、Photos表都需要增加相应的字段。
2、Albums表和Photos表都缺少创建时间和上传时间的字段。
3、是否需要将所有的timestamp类型的字段改成datetime型,并设置一致的默认值?
4、整个网站缺乏对用户的操作进行日志记录的数据表。

# re: 为我的创业网站YumDays创建数据库  回复  更多评论   

2008-02-02 17:18 by tlexQQ
个人认为,创建时间很重要。甚至可以根据这个扩充功能。没有的话……
那就太遗憾了,以后要加还很麻烦。

用户操作日志?这个不清楚是不是必要。

# re: 为我的创业网站YumDays创建数据库  回复  更多评论   

2008-02-02 19:27 by 海边沫沫
谢谢
我已经都增加time字段了。

# re: 为我的创业网站YumDays创建数据库  回复  更多评论   

2008-02-27 17:52 by cacaroter
加油,曾经在你的BLOG上学到很多东西。。

# re: 为我的创业网站YumDays创建数据库[未登录]  回复  更多评论   

2008-03-06 10:27 by peter
喜欢有创新的人,帅哥,你要做的话,干嘛要写在bolg上?干嘛不自己搞个需求,用pd做个模型?你的网时要赢利吗?如果不是可以写出来,如果是建议在自己机器上搞。我曾想过网络图片打印服务,不过现在不做这个。美工很烦人,开发很难搞美工。saaspeter@gmail.com

# re: 为我的创业网站YumDays创建数据库  回复  更多评论   

2008-03-30 18:46 by 海边沫沫
今天为albums表添加了mainpicture字段,这样就可以为每一个相册都指定一个主题图片了。

只有注册用户登录后才能发表评论。


网站导航: