無明確目標html
mongodb 這個名詞相信你們不會陌生吧。有段時間 nosql 的概念炒得特別火,其中 hbase redis mongodb couchdb 之類的名詞都相繼進入了大衆的視野。node
hbase 和 redis 和 mongodb 和 couchdb 雖然都屬於 nosql 的大範疇。但它們關注的領域是不同的。hbase 是存海量數據的,redis 用來作緩存,而 mongodb 和 couchdb 則試圖取代一些使用 mysql 的場景。mysql
mongodb 的官網是這樣介紹本身的:git
MongoDB (from "humongous") is an open-source document database, and the leading NoSQL database. Written in C++github
開源、文檔型、nosql。web
其中文檔型是個重要的概念須要理解。redis
在 sql 中,咱們的數據層級是:數據庫(db) -> 表(table) -> 記錄(record)-> 字段;在 mongodb 中,數據的層級是:數據庫 -> collection -> document -> 字段。這四個概念能夠對應得上。sql
文檔型數據這個名字中,「文檔」兩個字很容易誤解。其實這個文檔就是 bson 的意思。bson 是 json 的超集,好比 json 中無法儲存二進制類型,而 bson 拓展了類型,提供了二進制支持。mongodb 中存儲的一條條記錄均可以用 bson 來表示。因此你也能夠認爲,mongodb 是個存 bson 數據的數據庫,或是存哈希數據的數據庫。mongodb
mongodb 相對於它的競爭對手們來講——好比 couchdb,它的一大優點就是儘量提供與 sql 對應的概念。以前說了,sql 中的記錄對應 mongodb 中的 document,記錄這東西是一維的,而 document 能夠嵌套不少層。在某些場景下,好比存儲一個文章的 tags,mongodb 中的字段能夠輕鬆存儲數組類型,而 sql 中就須要設計個一對多的表關係出來。shell
假設有一個 blog 應用,其中有張 Post 表,表中有用戶發表的一些博客內容(post)。
這些 post 文檔的樣子大概會是這樣:
var post = { title: '呵呵的一天', author: 'alsotang', content: '今天網速不好', tags: ['呵呵', '網速', '差'], };
mongodb 中有個最亮眼的特性,就是 Auto-Sharding,sharding 的意思能夠理解成咱們 scale sql 時的分表。
在 mongodb 中,表與表之間是沒有聯繫的,不像 sql 中同樣,能夠設定外鍵,能夠進行錶鏈接。mongodb 中,也沒法支持事務。
因此這樣的表,無債一身輕。能夠很輕易地 scale 至多個實例(假設實例都有不一樣的物理位置)上。在 mongodb 中,實時的那些查詢,也就只能進行條件查詢:某某大於一個值或某某等於一個值。而 sql 中,若是一張表的數據存在了多個實例上的話,當與其餘表 join 時候,表之間的運來運去會是個很慢的過程,具體我也不太懂。
反正使用 mongodb 時,必定要思考的兩點就是:表 join 到底要不要,事務支持到底要不要。
mongodb 中的索引特性跟 sql 中差很少,只是它對於嵌套的數據類型也提供了支持。在創建複合索引時,mongodb 能夠指定不一樣字段的排序,好比兩個字段 is_top
(置頂) 和 create_time
(建立時間) 要創建複合索引,咱們能夠指定 is_top 按正序排,create_time 按逆序排。mysql 說是有計劃支持這個特性,不過目前也沒什麼消息。不過這點不重要。
mongodb 中,collection 是 schema-less 的。在 sql 中,咱們須要用建表語句來代表數據應該具備的形式,而 mongodb 中,能夠在同一張裏存各類各樣不一樣的形式的數據。同一個 collection 中,能夠有些 document 具備 100 個字段,而另外一些,則只具備 5 個字段。若是你分不清這個特性的使用場景,那麼請像使用 sql 同樣的,儘量保證一個 collection 中數據格式是統一的。這個 schema-less 的特性,有個比較典型的場景是用來存儲日誌類型的數據,能夠搜搜看這方面的典型場景。
mongodb 和 mysql 要我選的話,可有可無的應用我會選擇 mongodb,就當個簡單的存 json 數據的數據庫來用;若是是線上應用,確定仍是會選擇 mysql。畢竟 sql 比較成熟,並且各類經常使用場景的最佳實踐都有先例了。
我所在的阿里巴巴數據平臺,有各類各樣的大數據系統。有些作離線計算,一算就是幾個小時,算出來的結果被緩存起來,查詢時候就能夠實時獲得結果,只是數據一致性上,不可避免會有 delay;有些作實時運算,能夠在 1s 內從幾千萬條數據中算出一個複雜條件的結果。但它們都提供了 sql 的接口,也就是說,不管底層他們是如何讓幾百臺機器 mapreduce,都讓你能夠用已有的 sql 知識進行查詢。因此仍是選擇 sql 省事啊。
這裏還有個很好玩的網站:http://www.mongodb-is-web-scale.com/
順便說說 mongodb 與 redis 的不一樣。mongodb 是用來存非臨時數據的,能夠認爲是存在硬盤上,而 redis 的數據能夠認爲都在內存中,存儲臨時數據,丟了也無所謂。對於稍微複雜的查詢,redis 支持的查詢方式太少太少了,幾乎能夠認爲是 key-value 的。聽說 instagram 的數據就所有存在 redis 中,用了好幾個幾十 G 內存的 aws ec2 機器在存。redis 也是支持把數據寫入硬盤的,aof 貌似都過期了,很久沒關注了。
mongodb 與 hbase 的區別。若是說你已經在考慮使用 hbase 了的話,應該也不用我介紹它們的區別了吧..
主題所限,就不展開講了。這之間的選擇和權衡,提及來真的是個很大的話題。
我對這方面的話題很感興趣,若是要討論這方面話題的話,能夠去 https://cnodejs.org/ 發個帖,詳細描述一下場景而後 at 我(@alsotang)。
mongodb 的官網中有一些特性介紹:
其中標有箭頭的是基本概念,圓圈的是進階概念,畫叉的沒必要了解。
課程到這,一直忘記說 mongodb 的安裝了。
ubuntu: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/
mac: $ brew install mongodb
裝好之後,在命令行 $ mongod
,而後另外開個 shell 窗口,輸入 $ mongo
就能使用了。
mongoose 是個 odm。odm 的概念對應 sql 中的 orm。也就是 ruby on rails 中的 activerecord 那一層。orm 全稱是 Object-Relational Mapping
,對象關係映射;而 odm 是 Object-Document Mapping
,對象文檔映射。
它的做用就是,在程序代碼中,定義一下數據庫中的數據格式,而後取數據時經過它們,能夠把數據庫中的 document 映射成程序中的一個對象,這個對象有 .save .update 等一系列方法,和 .title .author 等一系列屬性。在調用這些方法時,odm 會根據你調用時所用的條件,自動轉換成相應的 mongodb shell 語句幫你發送出去。天然地,在程序中鏈式調用一個個的方法要比手寫數據庫操做語句具備更大的靈活性和便利性。
mongoose 的官網給出了相似這樣一個示例,我改造了一下:
// 首先引入 mongoose 這個模塊 var mongoose = require('mongoose'); // 而後鏈接對應的數據庫:mongodb://localhost/test // 其中,前面那個 mongodb 是 protocol scheme 的名稱;localhost 是 mongod 所在的地址; // 端口號省略則默認鏈接 27017;test 是數據庫的名稱 // mongodb 中不須要創建數據庫,當你須要鏈接的數據庫不存在時,會自動建立一個出來。 // 關於 mongodb 的安全性,mongodb 我印象中安全機制很殘廢,用戶名密碼那套都作得很差,更 // 別提細緻的用戶權限控制了。不過不用擔憂,mongodb 的默認配置只接受來自本機的請求,內網都連不上。 // 當須要在內網中爲其餘機器提供 mongodb 服務時,或許能夠去看看 iptables 相關的東西。 mongoose.connect('mongodb://localhost/test'); // 上面說了,我推薦在同一個 collection 中使用固定的數據形式。 // 在這裏,咱們建立了一個名爲 Cat 的 model,它在數據庫中的名字根據傳給 mongoose.model 的第一個參數決定,mongoose 會將名詞變爲複數,在這裏,collection 的名字會是 `cats`。 // 這個 model 的定義是,有一個 String 類型的 name,String 數組類型的 friends,Number 類型的 age。 // mongodb 中大多數的數據類型均可以用 js 的原生類型來表示。至於說 String 的長度是多少,Number 的精度是多少。String 的最大限度是 16MB,Number 的整型是 64-bit,浮點數的話,js 中 `0.1 + 0.2` 的結果都是亂來的。。就不期望什麼了。。 // 這裏能夠看到各類示例:http://mongoosejs.com/docs/schematypes.html var Cat = mongoose.model('Cat', { name: String, friends: [String], age: Number, }); // new 一個新對象,名叫 kitty // 接着爲 kitty 的屬性們賦值 var kitty = new Cat({ name: 'Zildjian', friends: ['tom', 'jerry']}); kitty.age = 3; // 調用 .save 方法後,mongoose 會去你的 mongodb 中的 test 數據庫裏,存入一條記錄。 kitty.save(function (err) { if (err) // ... console.log('meow'); });
咱們能夠驗證一下
$ mongo MongoDB shell version: 2.6.4 connecting to: test > show dbs > use test > show collections > db.cats.find()
會發現裏面就有一條記錄了。
若是要寫個博客程序練手。數據庫能夠這樣設計
var Post = mongoose.model('Post', { title: String, content: String, author: String, create_at: Date, });
評論就不要本身作了,接入多說:http://duoshuo.com/
編輯器就純文本好了,用 markdown 寫。
用戶系統也不作,硬編碼幾個管理員帳號在配置文件中,而後用 http basic auth:https://github.com/jshttp/basic-auth 來作驗證。
Nodeclub 是使用 Node.js 和 MongoDB 開發的社區系統