其實之前該講的都講得差不多了,所以接下來特別針對 Model 的部份來加強一下好了。
畢竟 Views 與 Contorllers 大家都會寫,所以 Model 這個部份我想特別拿出來充版面稍微講解一下應該很合理吧。
NoSQL vs. RDBMS
其實我自己使用關聯式資料表(RDBMS)也有好一陣子了,雖然說大家一直都在跟 NoSQL 比較效能問題,但我總覺得這樣比起來有失公允。畢竟這兩件事情,在某方面來說目的是不同的。
RDBMS 既然叫做關聯式資料表,我們當然就是需要他有關聯,所以設計方向自然會與 NoSQL 有所區別。而最常被拿出來戰的效能問題,更多時候,我覺得是資料結構與關聯(Schema)設計的問題。
反觀 NoSQL,基本上是基於 Schema-free 的方向在走,所以自然就沒有所謂資料結構與關聯設計的缺陷。但是,事情真的可以像想像中的那麼順利嗎?當我們沒有了資料表關聯後,你能夠確保你的操作都是沒有問題的嗎?
通常會炸個幾次(或數次。
我們都會說 key-value 的形式是相當快速的,是,這無可否認。但是,當你有試著去操作過 redis-cli
然後去找資料的時候,我告訴你我好想死啊這真不是人做的工作。
那 MongoDB 有好一點嘛?他多了一層 collections
,所以跟 Redis 比起來當然好整理一點,雖然跟 key-value 的概念似乎有點不同,不過這樣是相當便利的一種作法,把他想成是一種 tables 就很容易理解。
比起 Redis 純 key-value 的模式真是佛心太多了
Mongoose vs. Mongoskin
我在 Part 1 有提到關於 Model 的簡單實作方式,所以這裡就稍微再深入一點,講講 mongoose 跟 mongoskin 的部份。
我知道 Coke 所採用的是 Mongoose,因為依賴了 Schema 的設定方式,所以是一個蠻不錯的 ORM/ODM 的解決方案。不過也就因為他依賴了 Schema/Model 的設定方式,所以彈性必然會受到限制。
實際舉個例子,
var mongo = require( 'mongoose' );
mongo.connect('localhost:27017/mydatabase', function ( err ) {
if( err ) {
return err;
}
});
var Blog = new Schema({
slogan : { type: String, required: true },
author : { type: String },
content : { type: String },
created_at : { type: Number, 'default': Date.now },
updated_at : { type: Number }
});
var Entries = mongo.model( 'Blog', Blog );
Entries.findOne({
author: '閃光洽'
}, function( err, entry ) {
/*
* Output: entry.slogan, entry.author... etc.
*/
});
var mongo = require( 'mongoskin' );
mongo.db('localhost:27017/mydatabase')
.collection('blog')
.findOne({
author: '閃光洽'
})
.toArray( function( err, entry ){
/*
* Output: entry.slogan, entry.author... etc.
*/
});
你覺得哪一種比較好呢?
我個人覺得,有 Schema 有他的好處,起碼有人接棒的時候比較不會手足無措。雖然少了一點彈性,但是我想這件事情自己還是得有點取捨。雖然說 Coke 支援 Mongoose,不過,我期待他能支援 Mongoskin,也是不錯的選擇。
也許,自己做一個 Middleware 也是不錯的選擇(喂
Static Files
Ben 說 production
模式底下,靜態檔案都交給 Nginx 去操作,所以才會有我在第一篇所提到的靜態檔案消失的問題。這裡提供我的設定給大家參考一下,這是基於 Coke 所使用的設定,當然,倘若你對 Nginx 很熟悉,要使用到哪一種服務底下都是可行的,
upstream cokeapp {
ip_hash;
server localhost:4000;
}
server {
listen 80;
server_name nodejs.tw;
root /var/www/cokeapp/;
index index.html index.htm;
location ~* \.(?:manifest|appcache|html|xml|json)$ {
expires -1;
}
location ~* \.(?:rss|atom)$ {
expires 1h;
add_header Cache-Control "public";
}
location ~* \.ico$ {
root /var/www/cokeapp/public/;
expires 1w;
access_log off;
add_header Cache-Control "public";
}
location ~* \.(?:jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {
root /var/www/cokeapp/public/;
if (!-f $request_filename) {
return 404;
}
access_log off;
expires 1M;
add_header Cache-Control "public";
}
location ~* \.(?:css|js)$ {
root /var/www/cokeapp/public/;
# expires -1; #for development
expires 1M; #for production
access_log off;
add_header Cache-Control "public";
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://cokeapp/;
proxy_redirect off;
}
}
小結
最近 NodeJS 越來越熱門,而我目前也計畫著將一些新的專案轉由 NodeJS 來服務,其實無論是哪一種伺服端語言,他們都有各自的特質與性格,與其不斷比較或是拿 X 語言抨擊 Y 語言,實際操作與使用才是王道吧!
NodeJS 正夯,JavaScript 正夯,有機會的話,Why NOT?