Nodejs+mySQL和Redis和MongoDB的數(shù)據(jù)庫互聯(lián)互通

blockchain

Nodejs開發(fā)環(huán)境的搭建

  • 簡單的說 Node.js 就是運行在服務端的 JavaScript。
  • V8引擎執(zhí)行Javascript的速度非巢┲快险污,性能非常好。 [1] Node.js是一個基于Chrome JavaScript運行時建立的平臺, 用于方便地搭建響應速度快蛔糯、易于擴展的網(wǎng)絡應用拯腮。Node.js 使用事件驅(qū)動, 非阻塞I/O 模型而得以輕量和高效蚁飒,非常適合在分布式設備上運行數(shù)據(jù)密集型的實時應用动壤。

應用方向

  1. 大型高流量網(wǎng)站都采用Node.JS進行開發(fā),
  2. 開發(fā)一些快速移動Web框架淮逻,
  3. 應用程序監(jiān)控琼懊、媒體流、遠程控制爬早、桌面和移動應用等等[2]哼丈。

以上資料均來自百度百科


下載:Node.js 中文網(wǎng)

使用 node -v 命令來查看當前的 Node 版本,出現(xiàn)以下情況就安裝成功

image1.png

Node.js文檔 有Nodejs自帶的一些模塊。
如果需要其他的模塊凸椿,只需

npm install jquery

引入下載的模塊

var res = require("http.js");

引入自寫的模塊

var res = require("./foo.js");

更多操作和說明可參見 https://www.runoob.com/nodejs/nodejs-callback.html


Node.js 與MySQL互聯(lián)互通

MySQL操作,就不多講削祈,更多教程可參見 http://www.runoob.com/mysql/mysql-tutorial.html

MySQL不是nodejs自帶的模塊翅溺,需下載

npm install mysql

連接數(shù)據(jù)庫

var mysql = require('mysql');
var connection = mysql.createConnection({ 
    host : 'localhost',  //主機地址 (默認:localhost)
    user : 'root',  //用戶名
    password : '123456',  //密碼
    database : 'test'  //數(shù)據(jù)庫名
});
connection.connect();
connection.query('SELECT * FROM login_table', function (err, result) {
  
});
connection.end();

使用MySQL的連接池:

var pool = mysql.createPool({
    host : 'hostName', 
    user : 'username',
    password: 'password'
});
var  sql = 'SELECT * FROM websites';
pool.getConnection(function(err, connection){
  connection.query(sql,  function(err, rows){
  
  });
  connection.release();
});

數(shù)據(jù)庫操作( CURD ):增脑漫、刪、改咙崎、查對數(shù)據(jù)庫進行操作优幸。

//查
var  sql = 'SELECT * FROM websites';
pool.getConnection(function(err, connection){
  connection.query(sql,  function(err, rows){
  
  });
  connection.release();
});
//增
var  addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
var  addSqlParams = ['菜鳥工具', 'https://c.runoob.com','23453', 'CN'];
pool.getConnection(function(err, connection){
  connection.query(addSql,addSqlParams,function(err, rows){
  
  });
  connection.release();
});
//改
var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['菜鳥移動站', 'https://m.runoob.com',6];
pool.getConnection(function(err, connection){
  connection.query(modSql,modSqlParams,function(err, rows){

  });
  connection.release();
});
//刪
var delSql = 'DELETE FROM websites where id=6';
pool.getConnection(function(err, connection){
  connection.query(delSql,function(err, rows){
    
  });
  connection.release();
});

更多操作和說明可參見: http://www.runoob.com/nodejs/nodejs-mysql.html
可視化工具:Navicat for MySQL

demo案例 - 使用MySQL數(shù)據(jù)庫的登錄注冊系統(tǒng)

st=>start: 開始
e1=>end: 進入頁面
op1=>operation: 登錄
op2=>operation: 登錄成功
op3=>operation: 登錄失敗
op4=>operation: 注冊
op5=>operation: 注冊成功
op6=>operation: 注冊失敗
cond1=>condition: 數(shù)據(jù)庫是否存在該用戶
cond2=>condition: 數(shù)據(jù)庫是否存在該用戶
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4

node.js與mongodb互聯(lián)互通

  • MongoDB 是一個基于分布式文件存儲的數(shù)據(jù)庫。由C++語言編寫褪猛。旨在為WEB應用提供可擴展的高性能數(shù)據(jù)存儲解決方案网杆。
  • MongoDB 是一個介于關系數(shù)據(jù)庫和非關系數(shù)據(jù)庫之間的產(chǎn)品,是非關系數(shù)據(jù)庫當中功能最豐富伊滋,最像關系數(shù)據(jù)庫的碳却。他支持的數(shù)據(jù)結(jié)構非常松散,是類似json的bson格式笑旺,因此可以存儲比較復雜的數(shù)據(jù)類型昼浦。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向?qū)ο蟮牟樵冋Z言筒主,幾乎可以實現(xiàn)類似關系數(shù)據(jù)庫單表查詢的絕大部分功能关噪,而且還支持對數(shù)據(jù)建立索引。 [3]

以上資料均來自百度百科

下載地址: https://www.mongodb.com/download-center#community

MongoDB服務的配置

  • 啟動mongodb服務之前需要必須創(chuàng)建數(shù)據(jù)庫文件的存放文件夾乌妙,否則命令不會自動創(chuàng)建使兔,而且不能啟動成功。
  • 創(chuàng)建數(shù)據(jù)庫文件的存放位置藤韵,比如d:/data/db;
  • 在d:\data下新建文件夾log(存放日志文件)并且新建文件mongodb.log;
  • 在d:\data新建文件mongo.config;
  • 用記事本打開mongo.config輸入:
dbpath=D:\data\db
logpath=D:\data\log\mongodb.log  

在MongoBD的bin目錄下虐沥,(也可以配置環(huán)境變量)
輸入如下的命令啟動mongodb服務:

mongod.exe --dbpath d:\data\db

如圖打開服務,出現(xiàn)以下情況則配置成功

image2 (2).png

更多操作和說明可參見:
http://www.runoob.com/mongodb/mongodb-tutorial.html

創(chuàng)建連接泽艘、集合

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function (err, db) {
    if (err) throw err;
    console.log('數(shù)據(jù)庫已創(chuàng)建');
    var dbase = db.db("runoob");
    dbase.createCollection('site', function (err, res) {
        if (err) throw err;
        console.log("創(chuàng)建集合!");
        db.close();
    });
});

數(shù)據(jù)庫操作( CURD )

//插入一條數(shù)據(jù)
//插入多條數(shù)據(jù)可以使用 insertMany():
 var myobj = { name: "菜鳥教程", url: "www.runoob" };
  dbase.collection("site").insertOne(myobj, function(err, res) {
    if (err) throw err;
    console.log("文檔插入成功");
    db.close();
  });
//查詢數(shù)據(jù)
//指定條件數(shù)據(jù)
 var whereStr = {"name":'菜鳥教程'};  // 查詢條件
  dbo.collection("site"). find(whereStr).toArray(function(err, result) { // 返回集合中所有數(shù)據(jù)
      if (err) throw err;
      console.log(result);
      db.close();
  });
// 更新一條數(shù)據(jù)
// 如果要更新所有符合條的文檔數(shù)據(jù)可以使用 updateMany():
    var whereStr = {"name":'菜鳥教程'};  // 查詢條件
    var updateStr = {$set: { "url" : "https://www.runoob.com" }};
    dbo.collection("site").updateOne(whereStr, updateStr, function(err, res) {
        if (err) throw err;
        console.log("文檔更新成功");
        db.close();
    });
//刪除一條數(shù)據(jù)
    var whereStr = {"name":'菜鳥教程'};  // 查詢條件
    dbo.collection("site").deleteOne(whereStr, function(err, obj) {
        if (err) throw err;
        console.log("文檔刪除成功");
        db.close();
    })
// 如果要刪除多條語句可以使用 deleteMany() 方法

更多操作和說明可參見:https://www.runoob.com/nodejs/nodejs-mongodb.html
可視化工具下載: http://www.treesoft.cn/dms.html
demo案例 - 使用MySQL數(shù)據(jù)庫的登錄注冊系統(tǒng)

st=>start: 開始
e1=>end: 進入頁面
op1=>operation: 登錄
op2=>operation: 登錄成功
op3=>operation: 登錄失敗
op4=>operation: 注冊
op5=>operation: 注冊成功
op6=>operation: 注冊失敗
cond1=>condition: 數(shù)據(jù)庫是否存在該用戶
cond2=>condition: 數(shù)據(jù)庫是否存在該用戶
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4

node.js與redis的互聯(lián)互通

  • Redis是一個開源的使用ANSI C語言編寫欲险、支持網(wǎng)絡奈搜、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫盯荤,并提供多種
    語言的API馋吗。
  • Redis 與其他 key - value 緩存產(chǎn)品有以下三個特點:
    • Redis支持數(shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中秋秤,重啟的時候可以再次加載進行使用宏粤。
    • Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list灼卢,set绍哎,zset,hash等數(shù)據(jù)結(jié)構的存儲鞋真。
    • Redis支持數(shù)據(jù)的備份崇堰,即master-slave模式的數(shù)據(jù)備份
  • 優(yōu)勢
    • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
    • 豐富的數(shù)據(jù)類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作涩咖。
    • 原子 – Redis的所有操作都是原子性[4]的海诲,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個操作是原子性的檩互。多個操作也支持事務特幔,即原子性,通過MULTI和EXEC指令包起來闸昨。
    • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性蚯斯。

以上資料均來自網(wǎng)上
Window 下安裝
下載地址:https://github.com/MSOpenTech/redis/releases循诉。
Redis 支持 32 位和 64 位横辆。
Redis教程: http://www.redis.net.cn/tutorial/3501.html
可視化工具下載: http://www.treesoft.cn/dms.html

demo案例 - Nodejs+Redis+socketio的聊天室和訂閱模式

技術要點:

  • 開啟服務、連接Redis數(shù)據(jù)庫
var redis = require('redis');
var http = require('http');
var socketio = require('socket.io');
// 開啟服務
var server = http.createServer(function (req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  });
  res.end('服務器開啟成功');
}).listen(4000);
// 連接Redis數(shù)據(jù)庫
var redisPool = redis.createClient(6379, '127.0.0.1', {});
// 數(shù)據(jù)庫的密碼
redisPool.auth('123456');
// 共用16個數(shù)據(jù)庫
redisPool.select(1, function () {
  console.log('選擇數(shù)據(jù)庫第2個數(shù)據(jù)庫');
});
redisPool.on('connect', function () {
  console.log('Redis連接成功.');
})
var io = socketio(server);
io.on('connection', function (socket) {
  console.log('socketio已連接成功');
// 后續(xù)的操作都這里進行
})
  • 連接socketio
<script src="https://cdn.bootcss.com/socket.io/2.1.0/socket.io.js"></script>

socket = io.connect('http://127.0.0.1:4000');
socket.on('connect', function () {
// socket與后端成功建立鏈接 
});

訂閱模式

  • 后臺
// 消息訂閱者打洼,即subscribe客戶端龄糊,需要獨占鏈接,
  var subscribe = redis.createClient();
  subscribe.auth('123456');
//scoket監(jiān)聽訂閱者在客戶端訂閱一個channel  
  socket.on('subscribe', function (channel, username) {
    //這里我們把用戶每次訂閱的channel放到了一個set中
    credis.sadd('user:' + username, channel); 
    // 給前端發(fā)送消息
    socket.emit('message', {});
    subscribe.subscribe(channel);
  }) 

  • 前端
// 訂閱
var socket.emit('subscribe', channel, username);
// 接受消息
socket.on('message', function (message) {

})

取消訂閱

  • 后臺
 //scoket監(jiān)聽訂閱者在客戶端取消訂閱一個channel  
  socket.on('unsubscribe', function (channel, username) {
    socket.emit('message', {});
    subscribe.unsubscribe(channel);
  })
  • 前端
 socket.emit('subscribe', channel, username);

發(fā)布消息

//消息發(fā)布者募疮,即publish客戶端炫惩,無需獨占鏈接
  var publish = redis.createClient();
  publish.auth('123456');
// 當前發(fā)布者向某一個channel中發(fā)布消息,
publish.publish(channel, data);
//發(fā)布者在某個channel發(fā)送消息的時候,訂閱頻道的redis鏈接監(jiān)聽這個消息和該頻道  
subscribe.on('message', function (channel, message, pattern) {
    socket.emit('message', {})
})

redis作為緩存對消息的存儲和查詢
根據(jù)5種數(shù)據(jù)類型有不同的存儲和查詢方法:

  1. string(字符串)
redisPool.set('test-key', '12354', function (err) {
});
redisPool.get('test-key', function (err, reply) {
    console.log(reply);
});
  1. hash(哈希)
redisPool.hset('hashKey', "field1", "someValue124", redis.print);
redisPool.hmset("keys", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {

});
redisPool.hgetall('hashKey', function (err, replies) {
  console.log(replies);
});
  1. list(列表)
// 頭部(左邊 lpush)或者尾部(右邊 rpush)
redisPool.lpush('runoobs', "rediss", function (err, reply) {
  console.log(reply);
});
redisPool.rpush('runoobs', 'valuess', function (err, reply) {
  console.log(reply);
});
redisPool.lrange('runoobs', 0, 10, function (err, reply) {
  console.log(reply);
});
  1. Set(集合)
redisPool.sadd('runoob', ['redis', '456', 'mongodb', '798'], function (err, reply) {
  console.log(reply);
});
redisPool.smembers('runoob', function (err, reply) {
  console.log(reply);
});
  1. zset(sorted set:有序集合)
redisPool.zadd('runoobz', 1, 'mongodb', function (err, reply) {
  console.log(reply);
});
redisPool.zrangebyscore('runoobz', 0, 100, function (err, reply) {
  console.log(reply);
});
  • 升級方案(優(yōu)化)
  1. 增加了群發(fā)和點對點發(fā)送(以名字為唯一標識符)
  2. 頁面的優(yōu)化
  3. 對已訂閱的客戶端定時發(fā)送消息,需要socketio連接的外面執(zhí)行
setInterval(function () {
    publishs.publish('訂閱者', '發(fā)布的消息');
}, 1000 * 5);

更多教程可參見: http://www.runoob.com/redis/redis-sets.html

源代碼下載地址: https://gitee.com/ityangzhiwen/knowledge-redis-mongodb-mysql

技術分享markdown頁面下載地址:https://gitee.com/ityangzhiwen/technology_sharing


  1. Node.js Wiki .維基百科[引用日期2014-01-09] ?

  2. NodeJS無所不能:細數(shù)十個令人驚訝的NodeJS開源項目 .TechTarget[引用日期2015-10-31] ?

  3. 分布式文檔存儲數(shù)據(jù)庫 MongoDB .開源社區(qū)網(wǎng)[引用日期2012-09-08] ?

  4. 什么是原子性,什么是原子性操作阿浓?
    舉個例子:
    A想要從自己的帳戶中轉(zhuǎn)1000塊錢到B的帳戶里他嚷。那個從A開始轉(zhuǎn)帳,到轉(zhuǎn)帳結(jié)束的這一個過程,稱之為一個事務筋蓖。在這個事務里卸耘,要做如下操作:
    1.. 從A的帳戶中減去1000塊錢。如果A的帳戶原來有3000塊錢粘咖,現(xiàn)在就變成2000塊錢了蚣抗。
    2.. 在B的帳戶里加1000塊錢。如果B的帳戶如果原來有2000塊錢瓮下,現(xiàn)在則變成3000塊錢了翰铡。
    如果在A的帳戶已經(jīng)減去了1000塊錢的時候,忽然發(fā)生了意外讽坏,比如停電什么的锭魔,導致轉(zhuǎn)帳事務意外終止了,而此時B的帳戶里還沒有增加1000塊錢路呜。那么迷捧,我們稱這個操作失敗了,要進行回滾胀葱∧铮回滾就是回到事務開始之前的狀態(tài),也就是回到A的帳戶還沒減1000塊的狀態(tài)巡社,B的帳戶的原來的狀態(tài)膛堤。此時A的帳戶仍然有3000塊手趣,B的帳戶仍然有2000塊晌该。
    我們把這種要么一起成功(A帳戶成功減少1000,同時B帳戶成功增加1000)绿渣,要么一起失敵骸(A帳戶回到原來狀態(tài),B帳戶也回到原來狀態(tài))的操作叫原子性操作中符。
    如果把一個事務可看作是一個程序,它要么完整的被執(zhí)行,要么完全不執(zhí)行姜胖。這種特性就叫原子性。 ?

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淀散,一起剝皮案震驚了整個濱河市右莱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌档插,老刑警劉巖慢蜓,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異郭膛,居然都是意外死亡晨抡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耘柱,“玉大人如捅,你說我怎么就攤上這事〉骷澹” “怎么了镜遣?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長士袄。 經(jīng)常有香客問我烈涮,道長,這世上最難降的妖魔是什么窖剑? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任坚洽,我火速辦了婚禮,結(jié)果婚禮上西土,老公的妹妹穿的比我還像新娘讶舰。我一直安慰自己,他們只是感情好需了,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布跳昼。 她就那樣靜靜地躺著,像睡著了一般肋乍。 火紅的嫁衣襯著肌膚如雪鹅颊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天墓造,我揣著相機與錄音堪伍,去河邊找鬼。 笑死觅闽,一個胖子當著我的面吹牛帝雇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛉拙,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼尸闸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了孕锄?” 一聲冷哼從身側(cè)響起吮廉,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畸肆,沒想到半個月后宦芦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡恼除,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年踪旷,在試婚紗的時候發(fā)現(xiàn)自己被綠了曼氛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡令野,死狀恐怖舀患,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情气破,我是刑警寧澤聊浅,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站现使,受9級特大地震影響低匙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碳锈,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一顽冶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧售碳,春花似錦强重、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至艺智,卻和暖如春倘要,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背十拣。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工封拧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人父晶。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓哮缺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甲喝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348