## 第十二步:數據庫模式
在根目錄新建目錄models,然后進入目錄并新建文件*character.js*:
~~~
var mongoose = require('mongoose');
var characterSchema = new mongoose.Schema({
characterId: { type: String, unique: true, index: true },
name: String,
race: String,
gender: String,
bloodline: String,
wins: { type: Number, default: 0 },
losses: { type: Number, default: 0 },
reports: { type: Number, default: 0 },
random: { type: [Number], index: '2d' },
voted: { type: Boolean, default: false }
});
module.exports = mongoose.model('Character', characterSchema);
~~~

一個模式(schema)是你的MongoDB數據庫中的數據的一個表示,你能強迫某些字段必須為特定的類型,甚至決定該字段是否必需、唯一或者僅包含指定的元素。
和抽象的模式相比,一個模型(model)是和實踐更接近的對象,包含添加、刪除、查詢、更新數據的方法,在上面,我們創建了一個Character模型并將它暴露出來。
> 注意:為什么這個教程仍然使用MongoDB?為什么不使用MySQL、PostgreSQL、CouchDB甚至[RethinkDB](http://rethinkdb.com/)?這是因為對于要構建的應用來說,我并不真正關心數據庫層到底是什么樣的。我更關注在前端的技術棧,因為這是我最感興趣的部分。MongoDB也許并適合所有的使用場景,但它是一個合適的通用數據庫,并且過去3年來我和它相處良好。
這里大多數字段都能自我解釋,不過`random`和`voted`也許需要更多解釋:
* `random`?– 從`[Math.random(), 0]`生成的包含兩個數字的數組,這是一個MongoDB相關的[地理](http://docs.mongodb.org/manual/applications/geospatial-indexes/)標記,為了從數據庫隨機抓取一些角色,我們將使用[`$near`](http://docs.mongodb.org/manual/reference/operator/query/near/)操作符,我是從StackOverflow上[Random record from MongoDB](http://stackoverflow.com/questions/2824157/random-record-from-mongodb)學到這個技巧。
* `voted`?– 一個布爾值,為確定角色是否已被投票。如果不設置的話,人們可能會給同一角色反復刷票,現在當請求兩個角色時,只有那些沒有被投票的角色會被獲取。即使有人直接使用API,已投票的角色也不會再次被投票。
回到server.js,在文件開頭添加下面的代碼:
~~~
var mongoose = require('mongoose');
var Character = require('./models/character');
~~~
為了保證一致性和系統性,我經常按照下面的順序導入模塊:
1. 核心Node.js模塊——path、querystring、http
2. 第三方NPM庫——mongoose、express、request
3. 應用本身文件——controllers、models、config
最后,為鏈接到數據庫,在依賴模塊和Express中間件之間添加下面的代碼,它將在我們啟動Express app的時候發起一個到MongoDB的連接池:
~~~
mongoose.connect(config.database);
mongoose.connection.on('error', function() {
console.info('Error: Could not connect to MongoDB. Did you forget to run `mongod`?');
});
~~~
> 注意:我們將在config.js中設置數據庫的hostname以避免硬編碼。
在根目錄新建另一個文件*config.js*:
~~~
module.exports = {
database: process.env.MONGO_URI || 'localhost'
};
~~~
它將使用一個環境變量(如果可用)或降級到localhost,這將允許我們在本地開發時使用一個hostname,而在生產環境使用另一個,同時無需修改任何代碼。這種方法對于[處理OAuth客戶端key和secret](https://github.com/sahat/hackathon-starter/blob/master/config/secrets.js)時特別有用。
現在讓我們將它導入到server.js中:
~~~
var config = require('./config');
~~~
在終端中打開一個新的標簽并運行`mongod`。

- 前言
- 概述
- 第一步:新建Express項目
- 第二步:構建系統
- 第三步:項目結構
- 第四步: ES6速成教程
- 第五步: React速成教程
- 第六步:Flux架構速成教程
- 第七步:React路由(客戶端)
- 第八步:React路由(服務端)
- 第九步:Footer和Navbar組件
- 第十步:Socke.IO – 實時用戶數
- 第十一步:添加Character的組件
- 第十二步:數據庫模式
- 第十三步:Express API 路由(1/2)
- 第十五步:Home組件
- 第十四步:Express API 路由(2/2)
- 第十六步:角色(資料)組件
- 第十七步:Top 100 組件
- 第十八步:Stats組件
- 第十九步:部署
- 第二十步: 附加資源
- 總結