京山游俠

          專(zhuān)注技術(shù),拒絕扯淡
          posts - 50, comments - 868, trackbacks - 0, articles - 0
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          這里的文字主要是為了記錄下我的一些思路,以防日后遺忘。中途會(huì)經(jīng)歷相當(dāng)多的修改。有興趣的朋友歡迎指教。

          關(guān)于我的網(wǎng)站應(yīng)該提供一些什么樣的功能、使用什么樣的用戶(hù)交互方式,雛形在我的腦中基本已經(jīng)形成了,但是還不系統(tǒng)。我需要趕快把它們記錄下來(lái),免得以后忘了。當(dāng)然,在開(kāi)發(fā)的過(guò)程中,我的思路隨時(shí)都會(huì)發(fā)生變化,因此這里記下的東西也會(huì)發(fā)生很多修改。一想到網(wǎng)站的功能,馬上就會(huì)想到要設(shè)計(jì)什么樣的數(shù)據(jù)庫(kù)來(lái)支持它。所以,這里的記錄主要是怎么設(shè)計(jì)數(shù)據(jù)庫(kù)。

          數(shù)據(jù)庫(kù)軟件使用MySQL,先修改my.ini配置文件,默認(rèn)使用UTF-8編碼、InnoDB數(shù)據(jù)庫(kù)引擎,并啟動(dòng)二進(jìn)制日志,以使得數(shù)據(jù)庫(kù)備份的工作變簡(jiǎn)單些。

          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

          然后開(kāi)始創(chuàng)建數(shù)據(jù)庫(kù),經(jīng)過(guò)前面在網(wǎng)站架構(gòu)方面的設(shè)想,我需要?jiǎng)?chuàng)建最少兩個(gè)數(shù)據(jù)庫(kù):一個(gè)索引數(shù)據(jù)庫(kù),一個(gè)或多個(gè)內(nèi)容數(shù)據(jù)庫(kù)。我把索引數(shù)據(jù)庫(kù)命名為YumDaysIndex,內(nèi)容數(shù)據(jù)庫(kù)命名為YumDaysNNN,其中的NNN是數(shù)字編號(hào),在剛開(kāi)始的時(shí)候,肯定只要一個(gè)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數(shù)據(jù)庫(kù),創(chuàng)建用戶(hù)表:
           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、用戶(hù)名、密碼、昵稱(chēng)、密碼問(wèn)題、答案、email、QQ號(hào)、用戶(hù)角色、積分、相冊(cè)已經(jīng)使用的磁盤(pán)空間、注冊(cè)時(shí)間、登錄時(shí)間、是否刪除等。設(shè)計(jì)這個(gè)表的思路如下:
          1、name只能用英文,因?yàn)樗鼘⑹荱RL的組成部分,為了便于用戶(hù)之間的識(shí)別,所以需要monicker(昵稱(chēng))字段;
          2、根據(jù)用戶(hù)的score字段可以算出用戶(hù)的相冊(cè)容量,每次上傳圖片的時(shí)候,都增加albumusage字段的值,如果空間已經(jīng)被使用完,則不容許上傳;
          3、ID使用UUID類(lèi)型,所以它的列類(lèi)型為char(32),之所以使用UUID,是因?yàn)閡sers表會(huì)被分割到很多個(gè)數(shù)據(jù)庫(kù)中,使用UUID可以保證ID的唯一性;
          4、isdelete的列類(lèi)型也比較奇怪,為varchar(2),而默認(rèn)值卻是'0'(字符串),這是因?yàn)镾pringSide的實(shí)現(xiàn)中,在刪除數(shù)據(jù)的時(shí)候,會(huì)把這個(gè)字段設(shè)置為'-1'(字符串)。

          從這個(gè)表中可以看出,這里涉及到一個(gè)用戶(hù)角色的問(wèn)題,不同的角色擁有不同的權(quán)限,所以需要一個(gè)Roles表。考慮到Roles表包含的記錄數(shù)不會(huì)太多,而且分布到多個(gè)服務(wù)器上也不好維護(hù),所以Roles表應(yīng)該放到索引服務(wù)器中。用戶(hù)登錄這樣的過(guò)程也應(yīng)該由索引服務(wù)器處理,然后將用戶(hù)的一些信息保存到Cookie中,不過(guò)如果用戶(hù)操作的時(shí)候需要查看權(quán)限,則一定要向索引服務(wù)器請(qǐng)求,索引服務(wù)器通過(guò)提供WebService來(lái)響應(yīng)請(qǐng)求,因?yàn)樵贑ookie中保存權(quán)限會(huì)出現(xiàn)安全問(wèn)題。

          創(chuàng)建Roles表的代碼如下:
          USE YumDaysIndex;

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

          這里需要說(shuō)明的是privilegesflag字段,該字段我設(shè)計(jì)為一個(gè)用逗號(hào)隔開(kāi)的字符串,比如“post,reply”,代表用戶(hù)具有發(fā)帖、回帖的權(quán)限。這么設(shè)計(jì)的好處就是在開(kāi)發(fā)過(guò)程中,不用為了增加權(quán)限而修改數(shù)據(jù)表的結(jié)構(gòu),只用往這個(gè)表中加入新的字符串就行了,而Java代碼中,分割字符串又是那么的方便。

          在這個(gè)表中,我初步設(shè)計(jì)的角色有四個(gè),它們分別是管理員、超級(jí)用戶(hù)、普通用戶(hù)和被鎖定用戶(hù)。當(dāng)然,如果網(wǎng)站規(guī)模越來(lái)越大,需要有人幫著把關(guān)時(shí)(否則肯定黃帖廣告貼泛濫),可能需要版主、編輯這樣的角色。

          在我剛開(kāi)始設(shè)計(jì)這個(gè)系統(tǒng)時(shí),本來(lái)是加入了用戶(hù)群組的功能的,但是經(jīng)過(guò)這兩天的沉淀,我決定暫時(shí)還是不要這個(gè)功能了。以后再加上都可以,但是開(kāi)發(fā)初期我不想為自己找太多麻煩。

          文章要進(jìn)行分類(lèi),因此需要?jiǎng)?chuàng)建一個(gè)分類(lèi)表,這個(gè)表依然保留在索引服務(wù)器上:
           CREATE TABLE catalogs(
             id 
          char(32NOT NULL PRIMARY KEY,
             name 
          varchar(20NOT NULL,
             
          INDEX(name)
           );

          這個(gè)表的內(nèi)容很簡(jiǎn)單,無(wú)需解釋。

          再下面,就是用來(lái)保存文章的表了:
          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)
           ); 

          該表應(yīng)該保存到內(nèi)容數(shù)據(jù)庫(kù)中。其中的字段都很好理解,從名字即可看出意義。其中需要解釋的兩個(gè)字段如下:
          1、mainpicture:我希望每一篇文章都有一個(gè)主題圖片,該圖片在顯示文章列表的時(shí)候也可以顯示(當(dāng)然是縮略圖)。其內(nèi)容是一個(gè)URL。
          2、accessmod:該字段保存了該文章的安全屬性,即是否公開(kāi)。取值為1則不公開(kāi),取值為3則完全公開(kāi)。那么2呢?那是我為用戶(hù)群保留的,取值為2則只正對(duì)該文章所屬的群公開(kāi)。
          至于索引,那是要根據(jù)網(wǎng)站需要提供什么樣的功能來(lái)設(shè)計(jì)的。當(dāng)網(wǎng)站需要按照哪一個(gè)規(guī)則對(duì)文章進(jìn)行查找的時(shí)候,就要在該字段上建立索引,以便加快查找速度。

          再往下,則是用來(lái)保存回復(fù)的表:
           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
           );

          自己回復(fù)了哪些文章,心里也要有個(gè)數(shù),所以要建立一個(gè)表,用來(lái)記錄用戶(hù)參與了的文章:

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

          再然后,是用來(lái)管理相冊(cè)和相片的表:
           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是該相冊(cè)在服務(wù)器上的文件路徑,而miniphotopath則是縮略圖的路徑。accessmod也是起安全控制作用的,意義同前。

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

          這樣,內(nèi)容數(shù)據(jù)庫(kù)的表已經(jīng)差不多了,剩下的在開(kāi)發(fā)過(guò)程中再逐步完善。而索引服務(wù)器還只有前面提到的Roles表和Catalogs表,但是索引服務(wù)器要提供顯示首頁(yè)的功能,要提供反向代理的功能,要提供統(tǒng)計(jì)排序的功能。因此,我在索引數(shù)據(jù)庫(kù)中設(shè)計(jì)了以下表。

          首先,索引服務(wù)器中也應(yīng)該保存有Users的所有數(shù)據(jù),需要保存所有的記錄,但是不需要保存所有的字段。初步的設(shè)計(jì)如下:
          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)
           );

           這里保存有用戶(hù)的驗(yàn)證信息,因此簡(jiǎn)單的驗(yàn)證功能都可以通過(guò)索引服務(wù)器來(lái)完成。這里有兩個(gè)字段值得一提,一是score,用來(lái)保存用戶(hù)的分?jǐn)?shù),主要是為了實(shí)現(xiàn)用戶(hù)排名;另一個(gè)字段是webserver,它保存了該用戶(hù)會(huì)被分配到那個(gè)Web服務(wù)器。

          索引服務(wù)器還應(yīng)該保存所有Topics的記錄,當(dāng)然,它不需要保存所有的字段,和Users表一樣,它只需要知道到哪個(gè)Web服務(wù)器可以找到這個(gè)Topic的所有數(shù)據(jù)就行了。初步設(shè)計(jì)如下:

           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)
           );

          這個(gè)表非常簡(jiǎn)單,只是維護(hù)了一個(gè)所有Topic的索引而已,通過(guò)webserver字段就知道到哪里找它的詳細(xì)信息,索引服務(wù)器顯示主頁(yè)的時(shí)候,可以通過(guò)AJAX調(diào)用相應(yīng)的webserver來(lái)顯示它的摘要信息。time字段是用來(lái)排序的,catalog字段是用來(lái)分類(lèi)的。

          我還有一個(gè)想法,就是想能夠按照最新的回復(fù)來(lái)對(duì)Topic進(jìn)行排序,基本上所有的論壇都是采取的這種方法,只需要有人回復(fù),文章就會(huì)被頂上去。但是,由于Topics是分布存儲(chǔ)的,所以需要有一個(gè)表用來(lái)保存最近被回復(fù)的文章的信息,而其它的服務(wù)器則可以通過(guò)定時(shí)服務(wù),每隔幾分鐘在自己的服務(wù)器上統(tǒng)計(jì)最新被回復(fù)的文章,然后提交到索引服務(wù)器。其結(jié)構(gòu)如下:

           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)
           );

          這個(gè)表,只需要保存少量的紀(jì)錄就夠了。

          還要一個(gè)統(tǒng)計(jì)表,維護(hù)一些統(tǒng)計(jì)信息,如注冊(cè)用戶(hù)數(shù)、文章總數(shù)、回復(fù)總數(shù)、響應(yīng)新用戶(hù)注冊(cè)的當(dāng)前服務(wù)器等等,如下:

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

          這個(gè)表的名字是單數(shù)形式,因?yàn)檫@個(gè)表只需要一條紀(jì)錄就夠了。

          索引服務(wù)器還需要維護(hù)所有的相冊(cè)信息,同Topics表一樣,其結(jié)構(gòu)如下:

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

          數(shù)據(jù)庫(kù)的設(shè)計(jì)到此告一段落,下一步就開(kāi)始寫(xiě)代碼了。數(shù)據(jù)庫(kù)設(shè)計(jì)中的缺陷,只有經(jīng)過(guò)實(shí)戰(zhàn)的檢驗(yàn)才能夠體現(xiàn)出來(lái)。


          評(píng)論

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)  回復(fù)  更多評(píng)論   

          2008-01-27 21:01 by 海邊沫沫
          目前能夠想得到的缺陷:
          1、是否有必要不做物理刪除?如果有必要的話(huà),Topics表、Albums表、Replys表、Photos表都需要增加相應(yīng)的字段。
          2、Albums表和Photos表都缺少創(chuàng)建時(shí)間和上傳時(shí)間的字段。
          3、是否需要將所有的timestamp類(lèi)型的字段改成datetime型,并設(shè)置一致的默認(rèn)值?
          4、整個(gè)網(wǎng)站缺乏對(duì)用戶(hù)的操作進(jìn)行日志記錄的數(shù)據(jù)表。

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)  回復(fù)  更多評(píng)論   

          2008-02-02 17:18 by tlexQQ
          個(gè)人認(rèn)為,創(chuàng)建時(shí)間很重要。甚至可以根據(jù)這個(gè)擴(kuò)充功能。沒(méi)有的話(huà)……
          那就太遺憾了,以后要加還很麻煩。

          用戶(hù)操作日志?這個(gè)不清楚是不是必要。

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)  回復(fù)  更多評(píng)論   

          2008-02-02 19:27 by 海邊沫沫
          謝謝
          我已經(jīng)都增加time字段了。

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)  回復(fù)  更多評(píng)論   

          2008-02-27 17:52 by cacaroter
          加油,曾經(jīng)在你的BLOG上學(xué)到很多東西。。

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)[未登錄](méi)  回復(fù)  更多評(píng)論   

          2008-03-06 10:27 by peter
          喜歡有創(chuàng)新的人,帥哥,你要做的話(huà),干嘛要寫(xiě)在bolg上?干嘛不自己搞個(gè)需求,用pd做個(gè)模型?你的網(wǎng)時(shí)要贏利嗎?如果不是可以寫(xiě)出來(lái),如果是建議在自己機(jī)器上搞。我曾想過(guò)網(wǎng)絡(luò)圖片打印服務(wù),不過(guò)現(xiàn)在不做這個(gè)。美工很煩人,開(kāi)發(fā)很難搞美工。saaspeter@gmail.com

          # re: 為我的創(chuàng)業(yè)網(wǎng)站YumDays創(chuàng)建數(shù)據(jù)庫(kù)  回復(fù)  更多評(píng)論   

          2008-03-30 18:46 by 海邊沫沫
          今天為albums表添加了mainpicture字段,這樣就可以為每一個(gè)相冊(cè)都指定一個(gè)主題圖片了。
          主站蜘蛛池模板: 陆河县| 从化市| 安仁县| 宣汉县| 绍兴市| 永胜县| 荆门市| 永寿县| 琼中| 株洲市| 荥经县| 稻城县| 许昌市| 兰西县| 定襄县| 津市市| 宁波市| 河间市| 富民县| 嵊州市| 石阡县| 镇赉县| 都江堰市| 杨浦区| 柳江县| 黎城县| 杂多县| 衡水市| 繁昌县| 汤阴县| 内黄县| 蒲江县| 会理县| 星座| 武安市| 青龙| 玛曲县| 凤冈县| 淮阳县| 富锦市| 延安市|