我的NodeJS學(xué)習(xí)之路6(數(shù)據(jù)庫設(shè)計及開發(fā))

請關(guān)注專題:我的NodeJS學(xué)習(xí)之路(實踐之路)

小弟初涉node領(lǐng)域,不足之處纹腌,還請多多指教!
歡迎Star、Fork:https://github.com/gefangshuai/ANodeBlog

這篇主要來講Mongodb數(shù)據(jù)庫有關(guān)的內(nèi)容砌溺。

早已久仰NoSQL的大名,知道它相對有關(guān)系型數(shù)據(jù)庫冠绢,有很多的優(yōu)點抚吠,只是一直沒有時間來研究這個東西。所以借這個項目弟胀,對Mongodb進行了一次深入了解楷力。

Mongodb(或者是其他NoSQL數(shù)據(jù)庫)給我印象最深的就是高度的靈活性

關(guān)系型數(shù)據(jù)庫與非關(guān)系型數(shù)據(jù)庫的簡單對比

舉個栗子

假如我們用關(guān)系型數(shù)據(jù)庫設(shè)計了一張文章表孵户,字段如下:

  • title:文章標題
  • content:文章內(nèi)容
  • authorId:作者ID(通诚舫可能是外鍵)

同時根據(jù)我們的設(shè)計,項目已經(jīng)開始線上測試并且錄入了很多文章數(shù)據(jù)夏哭。
這個時候產(chǎn)品狗要求我們開發(fā)一個文章的喜歡功能:類似“簡書”检柬。

只需要在文章中看到喜歡的用戶即可,所以是一個單向的關(guān)聯(lián)關(guān)系竖配。

關(guān)系型數(shù)據(jù)庫的解決思路:

需要添加一張喜歡表: favorite何址,里面兩個字段:articleIduserId,表述的意思是:xx文章被xxx些用戶喜歡了进胯。文章和喜歡的用戶為多對多關(guān)系用爪。

可能,習(xí)慣了關(guān)系型數(shù)據(jù)庫的你沒覺出什么來胁镐,下面看一下非關(guān)系型數(shù)據(jù)庫的設(shè)計思路偎血。

非關(guān)系型數(shù)據(jù)庫的解決思路:

在文章的Collection中增加一個SubCollection诸衔,SubCollection中可以存放用戶信息,如用戶名颇玷,只要有用戶喜歡了文章笨农,在這篇文章的文檔中的子文檔下插入一條記錄即可!

{
  id: xxx,
  title: '學(xué)習(xí)NodeJS',
  content: `xxxx`,
  favorite: [
    {name: '張三'},
    {name: '李四'}
  ]
}

表述的意思就是“張三帖渠、李四喜歡了《學(xué)習(xí)NodeJS》”谒亦。

是不是比關(guān)系型數(shù)據(jù)庫的設(shè)計思路更加靈活清晰?阿弃!

好了诊霹,對于關(guān)系型數(shù)據(jù)庫非關(guān)系型數(shù)據(jù)庫的討論就不再深入了,沒有好壞之分渣淳,各有優(yōu)勢脾还。

項目中的Mongodb設(shè)計

NodeJS的流行,離不開豐富的中間件支持入愧,對于操作Mongoose的中間件鄙漏,我推薦“mongoosejs”, 官網(wǎng)稱之為:“Mongoose ODM”棺蛛。

關(guān)于orm和odm:

  • ORM:Object Relational Mapping怔蚌,對象關(guān)系映射
  • ODM:Object Document Mapping,對象文檔映射

其實兩者知識技術(shù)名詞上的區(qū)別旁赊,表象是一樣的桦踊,都是對象和數(shù)據(jù)庫的映射罷了。

Mongoose內(nèi)部實現(xiàn)了一套驗證機制及靈活的數(shù)據(jù)庫操作终畅,也是我推薦的一大理由籍胯。

先學(xué)習(xí)以下Mongoose的基本用法

  1. 將Mongoose集成到項目中
npm install --save mongoose
  1. 連接數(shù)據(jù)庫
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/blog');
  1. 定義一個Schema(也就是Mongodb中的Collections集合),更多字段類型离福,請參考SchemaTypes
var userSchema = {
    username: {type: String, required: true, unique: true},
    password: {type: String, required: true}
}
  1. 將Schema進行“Model化”
var User = mongoose.model('User', userSchema );
  1. 增加記錄
User.create({username: '張三', password: 'md5-pass'}, function(err, user){
    if(!err){
        console.log(user.username + ' 保存成功!');
    }else{
       console.log('數(shù)據(jù)保存失斦壤恰:' + err);
    }
});
  1. 修改記錄
User.findOneAndUpdate({_id: req.params.userId}, {
    username: newUsername
}, function (err, raw) {
    if(!err) {
        console.log( '修改成功!');
    }else{
        console.log('修改失敗');
    }
});
  1. 刪除記錄
User.deleteById(userId, function(err, doc){
    if(!err){
        console.log('刪除成功');
    }
});
  1. 查詢記錄
User.findById(userId, callback);    // one record
User.findOne({username: '張三'}, callback);  // one record
User.find();  // multi records

了解了Mongoose的基本用法,在進行數(shù)據(jù)庫設(shè)計妖爷,就容易很多了蝶涩。

本例中用戶User和文章Article的設(shè)計可直接參考dhHelper中的具體代碼。

Mongoose高級用法

關(guān)聯(lián)關(guān)系的建立

大家會發(fā)現(xiàn)dhHelperuserSchemaarticleSchema是有對應(yīng)關(guān)系的(具體的說是“一對多的關(guān)系”)絮识,那么這個對應(yīng)關(guān)系是怎么設(shè)計的呢绿聘?

說到這里,我們先來說一個其他的問題:“關(guān)于Mongodb中兩個集合之間的對應(yīng)關(guān)系次舌,設(shè)計呢熄攘?”
通過查找資料我的總結(jié)如下:

  • 如果只需要通過A集合查詢B集合,而不需要反過來查詢垃它,也就是單向的關(guān)系(如文章和評論,只需要展示文章的時候,將其評論展示即可)国拇,那么可以在A集合中建立一個子集合B洛史。這樣的查詢速度是最快的。
  • 如果既需要通過A查詢B酱吝,又需要通過B查詢A(如作者和文章也殖,需要查詢某作者下的所有文章,展示文章的時候务热,有需要展示作者的相關(guān)信息)忆嗜,那么可以在子集合中通過一個唯一字段關(guān)聯(lián)父集合。

articleSchema中增加一個字段_user崎岂,類型為Schema.Types.ObjectId捆毫,關(guān)聯(lián)User

_user: {
    type: Schema.Types.ObjectId,
    ref: 'User'
}

這樣,User和Article的關(guān)聯(lián)關(guān)系就建立好了冲甘。

Tip:
雖然關(guān)聯(lián)關(guān)系建立好了绩卤,但是當我們

var article = Article.findById(id, callback);

查詢出來的article調(diào)用article._user.username是出不來數(shù)據(jù)的,原因就是我們需要用到populate()函數(shù)江醇。

var article = Article.findById(id, callback).populate('_user');

這樣article._user.username就有數(shù)據(jù)了濒憋。類似Hibernate懶加載機制,需要做一下特殊處理陶夜。

加入時間戳

所謂時間戳凛驮,就是當我們對數(shù)據(jù)進行增加或修改的時候,數(shù)據(jù)庫能自動記錄增加時間修改時間条辟,不需要手動來維護黔夭。

以前使用Hibernate,默認是沒有這個功能的捂贿,要想實現(xiàn)需要通過@PrePersist注解和@PreUpdate注解來手動定義好纠修,很是麻煩。而Mongoose的解決方法是在數(shù)據(jù)庫的定義時就可以將這些信息定義好厂僧。這可能也就是約定優(yōu)于配置(convention over configuration)的好處吧扣草!

定義時間戳,很簡單颜屠,在new Schema()的時候辰妙,將時間戳的定義當作第二個參數(shù)傳入即可:

new Schema({xxx: xxx}, {timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'});

其中createdAtupdatedAt是固定的key,created_atupdated_at是對應(yīng)的字段名字甫窟。

關(guān)于NodeJS中數(shù)據(jù)庫的知識密浑,就寫這么多了,想要更多的了解有關(guān)Mongoose的用法粗井,請參考官方文檔:Mongoosejs Guide尔破。文檔寫得非常詳細街图!

Have a good luck~

未完待續(xù)
請關(guān)注專題:我的NodeJS學(xué)習(xí)之路(實踐之路)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懒构,隨后出現(xiàn)的幾起案子餐济,更是在濱河造成了極大的恐慌,老刑警劉巖胆剧,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件絮姆,死亡現(xiàn)場離奇詭異,居然都是意外死亡秩霍,警方通過查閱死者的電腦和手機篙悯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铃绒,“玉大人鸽照,你說我怎么就攤上這事∧渎ⅲ” “怎么了移宅?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長椿疗。 經(jīng)常有香客問我漏峰,道長,這世上最難降的妖魔是什么届榄? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任浅乔,我火速辦了婚禮,結(jié)果婚禮上铝条,老公的妹妹穿的比我還像新娘靖苇。我一直安慰自己,他們只是感情好班缰,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布贤壁。 她就那樣靜靜地躺著,像睡著了一般埠忘。 火紅的嫁衣襯著肌膚如雪脾拆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天莹妒,我揣著相機與錄音名船,去河邊找鬼。 笑死旨怠,一個胖子當著我的面吹牛渠驼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鉴腻,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迷扇,長吁一口氣:“原來是場噩夢啊……” “哼百揭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜓席,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤信峻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瓮床,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡产镐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年隘庄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癣亚。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡丑掺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出述雾,到底是詐尸還是另有隱情街州,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布玻孟,位于F島的核電站唆缴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黍翎。R本人自食惡果不足惜面徽,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匣掸。 院中可真熱鬧趟紊,春花似錦、人聲如沸碰酝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽送爸。三九已至铛嘱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碱璃,已是汗流浹背弄痹。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嵌器,地道東北人肛真。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像爽航,于是被迫代替她去往敵國和親蚓让。 傳聞我的和親對象是個殘疾皇子乾忱,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容