想知道大家在做非關(guān)係型資料庫(kù)的專案時(shí)是如何進(jìn)行設(shè)計(jì)的,以學(xué)生選課為例,每個(gè)學(xué)生可以選擇多個(gè)課程,每個(gè)課程可以讓多個(gè)學(xué)生選擇,這種多對(duì)多關(guān)係要如何設(shè)計(jì),如果我要?jiǎng)h除一個(gè)課程,如何保證資料庫(kù)的一致性?
MongoDB 考慮兩種基本模式:文件和分錶。
文檔模式把一筆記錄記入一個(gè)文檔,以學(xué)生選課為例,就是在一個(gè)學(xué)生的文檔下記錄所有他選的課程;分錶模式就是像關(guān)係型資料庫(kù)那樣,學(xué)生和課程分開建表,然後再建一個(gè)學(xué)生和課程對(duì)應(yīng)關(guān)係(選課)的表。
文件的主要優(yōu)點(diǎn)是讀取效率高,MongoDB 沒有joint
,如果分錶,每次查詢涉及幾張表就要做幾次查詢。文檔的主要缺點(diǎn)第一就是維護(hù)不便,例如你修改了一個(gè)課程的信息,就得找到所有包含這個(gè)課程的學(xué)生文檔,然後逐個(gè)修改。另外一個(gè)文檔的大小是有限制的,不能無限增加資料。
分錶的優(yōu)缺點(diǎn)和文檔式相反。
實(shí)務(wù)中要權(quán)衡選擇,以讀取為主的資料傾向於選擇文檔模式,寫/修改頻率高的資料可以考慮分錶。另外對(duì)於可能無限增加資料的字段,通常也要考慮分錶存儲(chǔ)。
一般是二者結(jié)合起來用,在文檔中記錄讀取頻率較高的信息,其它細(xì)節(jié)信息單獨(dú)建表。到你這個(gè)例子裡,就是學(xué)生和課程建兩個(gè)表,每個(gè)學(xué)生文件下記錄選課的基礎(chǔ)資訊(例如課程代碼和名稱),然後每個(gè)課程的具體資訊儲(chǔ)存在課程表裡。
當(dāng)你每次列出一個(gè)學(xué)生的選課資訊時(shí),一次查詢就可以列出所有選課的代碼和名稱,當(dāng)需要查看具體一門課程的詳細(xì)信息時(shí)再對(duì)課程表做一次查詢。這樣比完全分錶可以減少一次查詢,比完全文檔記錄減少了文檔的大小和修改課程資訊時(shí)要修改的範(fàn)圍。
如果你要?jiǎng)h除一門課,先在課表裡刪除這門課的文檔,然後在學(xué)生表裡找到所有包含這門課的記錄然後修改之。靈活運(yùn)用索引和操作符,並不是問題。