法拉利_Node.js(day5)

一、NOSQL

NOSQL是Not Only SQL的简称,与关系型数据库对应,一般称为非关系型数据库。关系型数据库遵循ACID规则,而NOSQL存储数据时不需要严格遵循固定的模式,因此在大数据的今天NOSQL为存储大数据提供了有效的途径。

1.关系型数据库的ACID原则

事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:

  • 1、A (Atomicity) 原子性
    原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
    比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
  • 2、C (Consistency) 一致性
    一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
    例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
  • 3、I (Isolation) 独立性
    所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
    比如现在有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
  • 4、D (Durability) 持久性
    持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

2.NOSQL中的ACP理论

在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer"s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性(Consistency) (所有节点在同一时间具有相同的数据)
  • 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
  • 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:

  • CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
  • CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
  • AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

二、MongoDB

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
更多说明请参考:菜鸟教程-MongoDB

1.安装

  • 下载安装包
    官网下载安装包进行安装:https://www.mongodb.com/
  • 配置环境变量
    安装成功之后需要配置环境变量:
    比如安装目录为:C:Program FilesMongoDB
    那么就需要配置环境变量到bin目录下,即:C:Program FilesMongoDBServer4.0in
  • 测试
mongod --version

查看是否有相关版本信息。

2.在命令行中简单使用

  • 启动数据库
mongod

注意:数据库需要保存数据的位置,默认是安装目录所在盘符下的/data/db目录(如果没有,需要手动创建)。如果需要修改默认存储目录使用mondod --datapath==路径.

2. zai ming ling hang zhong jian dan shi yong qi dong shu ju ku mongod zhu yi: shu ju ku xu yao bao cun shu ju de wei zhi, mo ren shi an zhuang mu lu suo zai pan fu xia de data db mu lu ru guo mei you, xu yao shou dong chuang jian. ru guo xu yao xiu gai mo ren cun chu mu lu shi yong mondod datapath lu jing.

  • 关闭数据库
    直接关闭命令行窗口或Ctrl + C即可。
  • 连接数据库
mongo
  • 断开连接
exit
  • 显示所有数据库
show dbs
  • 切换数据库
use 数据库名
  • 插入一条数据
db.模型名.insertOne(数据json对象)

这里的模型名相当于关系型数据库的表名。

  • 查看数据
db.模型名.find()

这里就不再赘述更多命令,我们很少使用命令行来操作数据库。

3.在Node.js中使用

  • 安装官方驱动包(不推荐)
    mongodb提供了node.js使用的驱动包,但方法比较原生,且有封装较完善的第三方包mongoose,所以这里推荐直接使用第三方包即可。
    可参考官网地址
  • 安装第三方包mongoose(推荐)
    官网地址
  • 安装

    npm install --save mongosse
    注意,可能会被墙,如果安装失败,可使用cnpm等镜像进行安装。
  • 使用
//加载mongoose模块
var mongoose = require("mongoose");
//连接mongo本地数据库:test
mongoose.connect("mongodb://localhost/test");

//设计数据库模块 ==> 相当于设计数据库表
var Cat = mongoose.model("Cat", { name: String });

//实例化Cat
var kitty = new Cat({ name: "Zildjian" });

//持久化kitty
kitty.save((error) => {
    if(error){
        console.log(error);
    }else{
        console.log("meow");
    }
});
  • 增删改查
    更多请参考官方文档:
    https://mongoosejs.com/docs/guide.html
    增:save()
    查:findById() | find() | findOne()
    删:findByIdAndRemove() | remove() | findOneAndRemove()
    改:findByIdAndUpdate()| update() | findOneAndUpdate()

三、案例:使用MongoDB修改之前的案例

略,即使用mongodb来代替之前的db.json和fs模块。

四、promise对象

1.回调地狱

回调函数可以为我们返回异步操作的数据,但回调函数还是无法保证异步函数的执行顺序。比如我们有三个文件:a.txt、b.txt、c.txt。我们使用fs.readFile()按顺序来读取a.txt、b.txt、c.txt。
那我们就需要使用嵌套的写法才能实现自定义顺序异步操作:

var fs = require("fs");

fs.readFile("./a.txt","utf8",(err,data) => {
    if(err)
        return console.log(err);
    console.log(data);
    fs.readFile("./b.txt","utf8",(err2,data2) => {
        if(err)
            return console.log(err2);
        console.log(data2);
        fs.readFile("./c.txt","utf8",(err3,data3) => {
            if(err)
                return console.log(err3);
            console.log(data3);
        });
    });
});

对于这种层层嵌套的回调函数,我们一般称为“回调地狱”,首先我们发现这种回调函数不美观易错不好维护。所以es6出现了Promise对象,专门用来处理这种回调地狱问题。

2.Promise对象

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
我们可以看一下示意图:

大致意思就是:

  • Promise对象以一个异步操作为参数,保存了其执行状态。
  • 异步操作的失败与否决定了Promise的状态。
  • 而每一个状态执行之后的返回值为Promise对象,这样就实现了顺序链式执行回调函数。
    具体看如下实例:
var fs = require("fs");

//将异步操作封装为Promise对象
var q1 = new Promise((resoleve,reject) => {
    fs.readFile("./a.txt","utf8",(err,data) => {
        if(err){
            reject(err);
        }else{
            resoleve(data);
        }
    });
});
var q2 = new Promise((resoleve,reject) => {
    fs.readFile("./b.txt","utf8",(err,data) => {
        if(err){
            reject(err);
        }else{
            resoleve(data);
        }
    });
});
var q3 = new Promise((resoleve,reject) => {
    fs.readFile("./c.txt","utf8",(err,data) => {
        if(err){
            reject(err);
        }else{
            resoleve(data);
        }
    });
});

//利用Promise的链式特性决定异步操作的顺序:使用then方法执行异步操作
q1.then((data) => {
    console.log(data);
    return q2;//这句话的意思是返回的对象为q2,那么q1执行之后就是q2执行
},(err) => {
    console.log(err);
}).then((data) => {
    console.log(data);
    return q3;
},(err) => {
    console.log(err);
}).then((data) => {
    console.log(data);
},(err) => {
    console.log(err);
});
  • then方法有两个回调函数参数,当Promise的状态为resolved是执行第一个回调函数,状态为rejected时执行第二个参数。
  • 上面说then()执行异步操作有点问题,其实应该是new Promise()后就执行了,因为需要先判断异步操作状态。
  • 使用return语句和then()方法就可以链式操作回调函数,还能决定顺序。(其实并没有改变执行顺序,但可以控制数据的输出顺序。)

上面Promise创建的方法可以进行封装让代码更简洁:

var fs = require("fs");

//将异步操作封装为Promise对象
function readFilePromise(filepath){
    return new Promise((resoleve,reject) => {
        fs.readFile(filepath,"utf8",(err,data) => {
            if(err){
                reject(err);
            }else{
                resoleve(data);
            }
        });
    });
}
var q1 = readFilePromise("./a.txt"),
    q2 = readFilePromise("./b.txt"),
    q3 = readFilePromise("./c.txt");

//利用Promise的链式特性决定异步操作的顺序:使用then方法"执行"异步操作
q1.then((data) => {
    console.log(data);
    return q2;//这句话的意思是返回的对象为q2,那么q1执行之后就是q2执行
},(err) => {
    console.log(err);
}).then((data) => {
    console.log(data);
    return q3;
},(err) => {
    console.log(err);
}).then((data) => {
    console.log(data);
},(err) => {
    console.log(err);
});

其实Jquery中的ajax的相关方法已经实现了Promise的相关方法,这里应用场景不再举例,更多可参考:MDN-Promise

当前文章:http://www.vcr-dvd.com/l9i5qyb/713623-742848-38305.html

发布时间:14:20:27

管家婆六合网??管家婆中特网一线图库??白小姐一肖中特马免费资料??香港马会资料大全??844440.com??1861图库开奖结果彩图??www.622633.com??382000.com六合银行??www.7890006.com??壮元红心水论坛??