NoSQL数据库
NoSQL(Not Only SQL)简介
- 非关系型数据库,对象实体关联少, 如MongoDB,支持复杂度相对高的数据结构, 能够将相关联的数据以文档的方式接入,从而减少数据之间的关联操作
- 通过数据的分布式存储大幅地提供存储性能
- 提供了强大的数据可用性,在应用中,能快速反馈信息给使用者
- 事务处理跟一致性弱,如果对性能有要求, 只能做到数据最终一致
一个项目中,可以同时有NoSQL数据库和RDB数据库,将数据拆开设计
-
NoSQL分类
-
什么是MongoDB及特点
- 官网: docs.mongodb.com
- 由C++语言编写,基于分布式文件存储的开源NoSQL数据库系统
- 将数据存储为BSON文档(BSON规范),数据结构由键值对组成 key => value, 字段值可以包含其他文档,数组及文档数据, mongoDB 可以想象为一个超级大对象
注: field对应关系型数据库中的Column, 集合Collection对应关系型数据库中的Table
4. 查询功能非常强大, 类似于面向对象的程序语言
-
在Node.js中操作MongoDB
-
什么是Redis
官网:redis.io/
基于ANSI C编写的开源的,遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API
-
Redis 安装(macOS)
以macOS为例,其他系统参考:www.runoob.com/redis/redis…
-
安装homebrew(已安装忽略此步骤)
/bin/bash -c "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install.sh)" -
安装redis
brew install redis -
启动redis, redis会默认占用6379端口
redis-server // 或者后台启动 redis-server --daemonize yes使用 ps -ef | grep -i redis 查看redis是否启动
-
停止redis, 强制终止Redis进程可能导致数据丢失,所以,应该向Redis发送shutdown命令
redis-cli shutdown注: Redis可以妥善处理SIGTERM信号,所以使用kill Redis进程的PID也可以正常结束Redis
-
Redis持久化:默认为RDB方式, 可通过conf配置文件appendonly yes 改为AOF方式
-
Redis图形管理软件RDM
下载地址: rdm.dev/
-
在Node.js中操作Redis
Nodejs中可以操作Redis的软件包如下: redis.io/clients#nod… 以 ioredis(github.com/luin/ioredi…) 为例(ioredis使用较为广泛,如阿里,公司B2B商城等使用的是ioredis, 并且支持原生Promise)
-
基本使用
const Redis = require("ioredis");
const redis = new Redis(); // uses defaults unless given configuration object
// ioredis supports all Redis commands:
redis.set("foo", "bar"); // returns promise which resolves to string, "OK"
// the format is: redis[SOME_REDIS_COMMAND_IN_LOWERCASE](ARGUMENTS_ARE_JOINED_INTO_COMMAND_STRING)
// the js: ` redis.set("mykey", "Hello") ` is equivalent to the cli: ` redis> SET mykey "Hello" `
// ioredis supports the node.js callback style
redis.get("foo", function (err, result) {
if (err) {
console.error(err);
} else {
console.log(result); // Promise resolves to "bar"
}
});
// Or ioredis returns a promise if the last argument isn't a function
redis.get("foo").then(function (result) {
console.log(result); // Prints "bar"
});
// Most responses are strings, or arrays of strings
redis.zadd("sortedSet", 1, "one", 2, "dos", 4, "quatro", 3, "three");
redis.zrange("sortedSet", 0, 2, "WITHSCORES").then((res) => console.log(res)); // Promise resolves to ["one", "1", "dos", "2", "three", "3"] as if the command was ` redis> ZRANGE sortedSet 0 2 WITHSCORES `
// All arguments are passed directly to the redis server:
redis.set("key", 100, "EX", 10);
2. 管道(Pipelining)redis.io/topics/pipe…
const pipeline = redis.pipeline();
pipeline.set("foo", "bar");
pipeline.del("cc");
pipeline.exec((err, results) => {
// `err` is always null, and `results` is an array of responses
// corresponding to the sequence of queued commands.
// Each response follows the format `[err, result]`.
});
// You can even chain the commands:
redis
.pipeline()
.set("foo", "bar")
.del("cc")
.exec((err, results) => {});
// `exec` also returns a Promise:
const promise = redis.pipeline().set("foo", "bar").get("foo").exec();
promise.then((result) => {
// result === [[null, 'OK'], [null, 'bar']]
});
3. 事务
redis
.multi()
.set("foo", "bar")
.get("foo")
.exec((err, results) => {
// results === [[null, 'OK'], [null, 'bar']]
});
事务中默认带管道, 如果不需要管道(不建议,管道能提高效率),需要将{pipeline: false} 传递给multi, 每个命令将立即发送到Redis,而无需等待exec调用
4. 错误信息
启用showFriendlyErrorStack,优化错误堆栈