在写一个登录会话demo的时候,使用mongodb.open总是打开失败,查了不少资料,最后open问题想彻底解决还是用Mongoose吧,所以开始丢弃使用Mongodb原生API了(溜了溜了
MongoDB
什么是MongoDB ?
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
hbase 、redis 、mongodb 、couchdb 虽然都属于 nosql 的大范畴。但它们关注的领域是不一样的。hbase 是存海量数据的,redis 用来做缓存,而 mongodb 和 couchdb 则试图取代一些使用 mysql 的场景。
MongoDB是开源、文档型、nosql。
其中文档型是个重要的概念需要理解。
在 sql 中,我们的数据层级是:数据库(db) -> 表(table) -> 记录(record)-> 字段;在 mongodb 中,数据的层级是:数据库 -> collection -> document -> 字段。这四个概念可以对应得上。
文档型数据这个名字中,“文档”两个字很容易误解。其实这个文档就是 bson 的意思。bson 是 json 的超集,比如 json 中没法储存二进制类型,而 bson 拓展了类型,提供了二进制支持。mongodb 中存储的一条条记录都可以用 bson 来表示。所以你也可以认为,mongodb 是个存 bson 数据的数据库,或是存哈希数据的数据库。
与json相比,bson着眼于提高存储和扫描效率。bson文档中的大型元素以长度字段为前缀以便于扫描。在某些情况下,由于长度前缀和显式数组索引的存在,bson使用的空间会多于json。
在 mongodb 中,表与表之间是没有联系的,不像 sql 中一样,可以设定外键,可以进行表连接。mongodb 中,也无法支持事务。
mongodb 中的索引特性跟 sql 中差不多,只是它对于嵌套的数据类型也提供了支持。在建立复合索引时,mongodb 可以指定不同字段的排序,比如两个字段 is_top(置顶) 和 create_time(创建时间) 要建立复合索引,我们可以指定 is_top 按正序排,create_time 按逆序排。
mongodb 中,collection 是 schema-less 的。这个 schema-less 的特性,有个比较典型的场景是用来存储日志类型的数据。有些documents有10个字段,有些只有5个。
MongoDB安装简单。
mongodb怎样使用内存
mongodb使用内存映射存储引擎,
它会把数据文件映射到内存中,如果是读操作,内存中的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺序的写操作,总之可以大幅度提升性能。MongoDB并不干涉内存管理工作,而是把这些工作留给操作系统的虚拟内存管理器去处理,这样做的好处是简化了MongoDB的工作,但坏处是你没有方法很方便的控制MongoDB占多大内存,幸运的是虚拟内存管理器的存在让我们多数时候并不需要关心这个问题。
MongoDB的内存使用机制让它在缓存重建方面更有优势,简而言之:如果重启进程,那么缓存依然有效,如果重启系统,那么可以通过拷贝数据文件到/dev/null的方式来重建缓存。
mongo使用场合
mongodb的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。mongo适用于以下场景:
a.网站数据:mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
b.缓存:由于性能很高,mongo也适合作为信息基础设施的缓存层。在系统重启之后,由mongo搭建的持久化缓存可以避免下层的数据源过载。
c.大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
d.高伸缩性的场景:mongo非常适合由数十或者数百台服务器组成的数据库。
e.用于对象及JSON数据的存储:mongo的BSON数据格式非常适合文档格式化的存储及查询。
不适合的场景:
a.高度事物性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
b.传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
c.需要SQL的问题。
Mongoose
很多nodejs的新手都是直接用mongodb本身直接操作数据库,我也是如此。
不知道大家有没有遇到过这个错误:
Error: db object already connecting, open cannot be called multiple times
也许你会说是异步写得不好,但是就算异步写得再好,也逃避不了这个错误
因为无论如何,都要用到db.open();这东西,而且访问完毕还得db.close();
于是就有一个问题:刷新得太快,或者多个用户同时访问数据库,数据库没来得及关闭,那个Error就会出现。
用mongoose就不会出现这错误勒,因为一旦连接好数据库,db就会处于open状态,不存在访问时要打开,然后又要关闭的规则。
Mongoose的使用
使用mongoose的步骤:
引入模块(node)—> 定义schema —> 定义模型操作数据库
1、引入模块并连接数据库
var mongoose = require('mongoose'),
DB_URL = 'mongodb://localhost:27017/mongoosesample';
/**
* 连接
*/
mongoose.connect(DB_URL);
/**
* 连接成功
*/
mongoose.connection.on('connected', function () {
console.log('Mongoose connection open to ' + DB_URL);
});
/**
* 连接异常
*/
mongoose.connection.on('error',function (err) {
console.log('Mongoose connection error: ' + err);
});
/**
* 连接断开
*/
mongoose.connection.on('disconnected', function () {
console.log('Mongoose connection disconnected');
});
module.exports = mongoose;
2、schema
schema是mongoose里会用到的一种数据模式,可以理解为表结构的定义;每个schema会映射到mongodb中的一个collection,它不具备操作数据库的能力。
定义一个schema如下:
/**
* 用户信息
*/
var mongoose = require('./db.js'),
Schema = mongoose.Schema;
var UserSchema = new Schema({
username : { type: String }, //用户账号
userpwd: {type: String}, //密码
userage: {type: Number}, //年龄
logindate : { type: Date} //最近登录时间
});
Schema Types内置类型如下:
String
Number
Boolean | Bool
Array
Buffer
Date
ObjectId | Oid
Mixed
3、modal
model是由schema生成的模型,可以对数据库的操作
生成一个User的modal
/**
* 用户信息
*/
var mongoose = require('./db.js'),
Schema = mongoose.Schema;
var UserSchema = new Schema({
username : { type: String }, //用户账号
userpwd: {type: String}, //密码
userage: {type: Number}, //年龄
logindate : { type: Date} //最近登录时间
});
module.exports = mongoose.model('User',UserSchema);
常用数据库操作
1、插入 Model.save([fn])
2、更新 Model.update(conditions, update, [options], [callback])
根据_id:Model.findByIdAndUpdate(id, [update], [options], [callback])
ps:fn是回调函数
3、删除 Model.remove(conditions, [callback])
4、数量查询 Model.count(conditions, [callback])
其他详细的可以看它mongoose操作
使用Robo 3T
连接好数据库之后,打开Robo 3T就能自动连上