曾自己借助阿里云和hexo搭了個(gè)站點(diǎn),現(xiàn)已廢棄,過(guò)往寫(xiě)的博客暫挪到此處。
title: MongoDB 初接觸
date: 2017-01-22 16:21:56
tags:
- 技術(shù)
- TODO
- NoSQL
應(yīng)工作要求,學(xué)習(xí)MongoDB,然后需要對(duì)結(jié)果進(jìn)行培訓(xùn)驗(yàn)收。本文只針對(duì)同事會(huì)感興趣的點(diǎn)。
MongoDB優(yōu)劣
dynamic schemas 動(dòng)態(tài)模式
怕翻譯的不好,摘錄部分原文。
meaning that you can create records without first defining the structure, such as the fields or the types of their values. You can change the structure of records (which we call documents) simply by adding new fields or deleting existing ones. This data model give you the ability to represent hierarchical relationships, to store arrays, and other more complex structures easily.
flexible data model : your database schema can evolve with business requirements
For example, schema changes that took days of weeks in The Weather Channel's MySQL databases could be made in just hours with MongoDB.
我個(gè)人簡(jiǎn)單粗暴的理解,就是沒(méi)有結(jié)構(gòu)限制,你不用預(yù)先定義結(jié)構(gòu),也可以隨時(shí)往一個(gè)集合(mongoDB中的集合collection即RDBMS中的table)里存取不同結(jié)構(gòu)的數(shù)據(jù)。
例子中說(shuō)到對(duì)MySQL而言,改變schema需要幾天甚至幾周,對(duì)mongoDB而言只需要幾個(gè)小時(shí)。
high availability and scalability 高可用性(or有效性)、高擴(kuò)展
MongoDB can also be scaled within and across multiple distributed data centers
As your deployments grow in terms of data volume and throughput, MongoDB scales easily with no downtime, and without changing your application.
隨著數(shù)據(jù)量的增大,MongoDB可以完全沒(méi)有宕機(jī),無(wú)需改變你的應(yīng)用的擴(kuò)展
Scalability is not just about speed. It's about 3 different metrics, which often work together:
* Cluster Scale. Distributing the database across 100+ nodes, often in multiple data centers
* Performance Scale. Sustaining 100,000+ database read and writes per second while maintaining strict latency SLAs
* Data Scale. Storing 1 billion+ documents in the database
如何實(shí)現(xiàn)需進(jìn)一步學(xué)習(xí)。
out-of-the-box replication 隨手可用的復(fù)制功能
詳情參考
Replica sets provide redundancy and high availability, and are the basis for all production deployments.
這個(gè)特性實(shí)現(xiàn)了冗余和高可用性。
auto-sharding(自動(dòng)分區(qū)) 或者說(shuō) 分布式系統(tǒng)
分布式計(jì)算的優(yōu)點(diǎn)
可靠性(容錯(cuò)) :
分布式計(jì)算系統(tǒng)中的一個(gè)重要的優(yōu)點(diǎn)是可靠性。一臺(tái)服務(wù)器的系統(tǒng)崩潰并不影響到其余的服務(wù)器。可擴(kuò)展性:
在分布式計(jì)算系統(tǒng)可以根據(jù)需要增加更多的機(jī)器。資源共享:
共享數(shù)據(jù)是必不可少的應(yīng)用,如銀行,預(yù)訂系統(tǒng)。靈活性:
由于該系統(tǒng)是非常靈活的,它很容易安裝,實(shí)施和調(diào)試新的服務(wù)。更快的速度:
分布式計(jì)算系統(tǒng)可以有多臺(tái)計(jì)算機(jī)的計(jì)算能力,使得它比其他系統(tǒng)有更快的處理速度。開(kāi)放系統(tǒng):
由于它是開(kāi)放的系統(tǒng),本地或者遠(yuǎn)程都可以訪問(wèn)到該服務(wù)。更高的性能:
相較于集中式計(jì)算機(jī)網(wǎng)絡(luò)集群可以提供更高的性能(及更好的性價(jià)比)。
分布式計(jì)算的缺點(diǎn)
故障排除:
故障排除和診斷問(wèn)題。軟件:
更少的軟件支持是分布式計(jì)算系統(tǒng)的主要缺點(diǎn)。網(wǎng)絡(luò):
網(wǎng)絡(luò)基礎(chǔ)設(shè)施的問(wèn)題,包括:傳輸問(wèn)題,高負(fù)載,信息丟失等。安全性:
開(kāi)發(fā)系統(tǒng)的特性讓分布式計(jì)算系統(tǒng)存在著數(shù)據(jù)的安全性和共享的風(fēng)險(xiǎn)等問(wèn)題。
分區(qū)詳情參考:https://docs.mongodb.com/manual/sharding/
查詢速度快
我理解的原因之一是,文檔存儲(chǔ)方式。比如跟一個(gè)用戶相關(guān)的東西,存儲(chǔ)在一個(gè)集合(SQL中的表)中,所以相對(duì)SQL的多表聯(lián)合查詢,要快。但有冗余的問(wèn)題。
比如產(chǎn)品評(píng)論,在產(chǎn)品集合中存了一遍,在用戶集合中也存了一遍。
肯定還有其他的原因,需進(jìn)一步學(xué)習(xí)。
參考文檔:
http://www.cnblogs.com/crazylights/archive/2013/05/08/3066056.html
劣勢(shì):不支持復(fù)雜的事務(wù)
MongoDB不支持事務(wù),但是mongodb提供了許多原子操作,比如文檔的保存,修改,刪除等,都是原子操作。
劣勢(shì)(uncertain):MongoDB為了性能更快,所以數(shù)據(jù)會(huì)有冗余
文檔存儲(chǔ)方式的可能的劣勢(shì)。
what's more
MongoDB適用場(chǎng)景,與MySQL對(duì)比之下
MongoDB適用
The most common use cases for MongoDB include Single View, Internet of Things, Mobile, Real-Time Analytics, Personalization, Catalog, and [Content Management](Content Management).
MySQL適用
Applications that require complex, multi-row transactions (e.g., a double-entry bookkeeping system)
比如booking system。這種需要強(qiáng)事務(wù)性的,需要復(fù)雜事務(wù)的。
MongoDB 和mySQL一起使用的情況
比如電商系統(tǒng)中的產(chǎn)品 詳情,分類,屬性等等,而checkout system(我理解的就是購(gòu)買和支付等行為)用MySQL
MongoDB結(jié)合nodejs的實(shí)現(xiàn)
MongoDB Server的安裝運(yùn)行
安裝
-
運(yùn)行MongoDB服務(wù)
mongod -
打開(kāi)MongoDB后臺(tái)管理shell
mongo用shell操作數(shù)據(jù)庫(kù)的方式,如若用代碼操作數(shù)據(jù)庫(kù)則不用打開(kāi)shell
一些常用指令
//列出所有db show dbs //列出當(dāng)前db db //使用某db use test //列出當(dāng)前db下所有collection show collections //顯示當(dāng)前collection中的數(shù)據(jù) db.collection_name.find().pretty() //針對(duì)特殊的collection名 db[collection_name].find() db.getCollection(collection_name).find() //pretty()用于格式化 //清空collection中的數(shù)據(jù),移除整個(gè)collection db.collection_name.drop() //插入數(shù)據(jù) db.collection.insert() //Shell help help //命令行help mongo —help //db help db.help() //collection help db.collection.help()
-
可以啟動(dòng)MongoDB web用戶界面
mongod --dbpath=/data/db --rest默認(rèn)端口28017: http://localhost:28017/
不過(guò)需要關(guān)閉2運(yùn)行的服務(wù)??赡苁峭粋€(gè)實(shí)例 mongod instance。
如果以上命令不能直接執(zhí)行,需要進(jìn)入mongodb安裝目錄的bin目錄下。取決于安裝方式,如果用brew安裝的就不需要進(jìn)入bin目錄
使用mongo-native(官方驅(qū)動(dòng))實(shí)現(xiàn)nodejs的增(刪改查類似就未嘗試)
-
安裝
npm install mongodbhttps://docs.mongodb.com/getting-started/node/client/
https://github.com/mongodb/node-mongodb-native?jmp=docs -
代碼
var model = { uid: json.u, …… } var insertDocuments = function (db, callback) { // Get the documents collection var collection = db.collection('ma_pv'); // Insert some documents collection.insert(model, function (err, result) { assert.equal(err, null); console.log("Inserted documents into the collection"); callback(result); }); } var MongoClient = require('mongodb').MongoClient, assert = require('assert'); // Connection URL var url = 'mongodb://localhost:27017/ma'; // Use connect method to connect to the server MongoClient.connect(url, function (err, db) { assert.equal(null, err); console.log("Connected successfully to server"); insertDocuments(db, function () { db.close(); }); });
使用mongoose(ORM)實(shí)現(xiàn)nodejs增
-
安裝
npm install mongoose -
代碼
連接數(shù)據(jù)庫(kù)
var mongoose = require('mongoose'); mongoose.Promise = global.Promise mongoose.connect('mongodb://localhost:27017/ma');//;連接數(shù)據(jù)庫(kù) var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log("we're connected!"); }); module.exports = db;定義model
var mongoose = require('mongoose'); var db = require('./db'); var maPV_schema = mongoose.Schema({ uid: String, …… create_time: Date }); // 定義了一個(gè)新的模型,但是此模式還未和maPV_schema集合有關(guān)聯(lián) var maPV = mongoose.model('maPV', maPV_schema); // 與maPV_schema集合關(guān)聯(lián) module.exports = maPV;數(shù)據(jù)增
var PVmodel = require("../model_mongoose/ma_pv"); var pvData = new PVmodel({ uid: json.u, …… }); pvData.save(function (err,pv,num) { if (err) { console.error(err) } // throw err; console.log('pvData saved successfully!'); }); -
what's more
https://scotch.io/tutorials/using-mongoosejs-in-node-js-and-mongodb-applications
分析
With Mongoose, everything is derived from a Schema.
mongoDB是動(dòng)態(tài)schema的,基本就沒(méi)有schema,無(wú)論什么結(jié)構(gòu)的數(shù)據(jù)都可以往一個(gè)集合(collection,相當(dāng)于RDBMS的table)中存。
但是mongoose確是先設(shè)定schema,但是后續(xù)可以通過(guò)mongoose的方法隨時(shí)更改schema。
遇到的問(wèn)題
報(bào)錯(cuò):
(node:21132) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead:
bugid:
https://github.com/Automattic/mongoose/issues/4291
臨時(shí)解決方案:
在collect數(shù)據(jù)庫(kù)之前 mongoose.Promise = global.Promise
http://stackoverflow.com/questions/38138445/node3341-deprecationwarning-mongoose-mpromise
MongoDB -> MySQL
首先,為什么要從MongoDB轉(zhuǎn)移至MySQL?
個(gè)人考慮,三種情況:
通過(guò)定時(shí)服務(wù),分析MongoDB中的一些數(shù)據(jù),存儲(chǔ)到MySQL中。這樣的話,不需要解決什么技術(shù)問(wèn)題,寫(xiě)API而已,API取數(shù)據(jù)通過(guò)MongoDB的驅(qū)動(dòng)連接MongoDB數(shù)據(jù)庫(kù),存數(shù)據(jù)通過(guò)MySQL的驅(qū)動(dòng)連接MySQl。
如果是把數(shù)據(jù)直接遷移至MySQL,就只是數(shù)據(jù)庫(kù)之間的遷移。但是是否有必要?為什么不直接存儲(chǔ)到MySQL
-
如果是為了實(shí)時(shí)分析數(shù)據(jù)所以需要遷移至MySQL,MongoDB也支持。
https://www.mongodb.com/collateral/apache-spark-and-mongodb-turning-analytics-into-real-time-action
所以需要細(xì)細(xì)考慮,結(jié)論如下:
- 只用MongoDB實(shí)現(xiàn):MongoDB好像可以解決所有問(wèn)題。
- 部分MongoDB部分MySQL,不涉及遷移問(wèn)題:根據(jù)業(yè)務(wù)不同使用不同sql。
- 遷移MySQL。
阿里云MongoDB
除了安裝需要按照他們的要求,其他看起來(lái)沒(méi)什么區(qū)別;
因?yàn)闆](méi)有環(huán)境,所以沒(méi)辦法測(cè)試。需要阿里云ECS