# 数据库

# 定义

数据库是用来组织存储和管理数据的仓库

# 分类

# 关系型

(传统型、关系型、SQL 数据库)

①MySQL 数据库(目前使用最广泛,流行度最高的开源免费数据库)

②Oracle 数据库(收费)

③SQL Server 数据库(收费)

# 非关系型

(新型、非关系型、NoSQL 数据库)

④Mongodb 数据库 (一定程度上弥补了传统型数据库的缺陷)

# 区别

1、MySQL 是关系型数据库,而 mongodb 是非关系型数据库;
2、MySQL 中支持多种引擎,不同引擎有不同的存储方式,而 mongodb 以类 JSON 的文档的格式存储;
3、MySQL 使用传统 SQL 语句进行查询,而 mongodb 有自己的 查询方式类似JavaScript的函数 );
4、 MySQL占用空间小 ,支持 join,而 mongodb 占用空间大,不支持 join。

对比:

数据库MongoDBMySQL
数据库模型非关系型关系型
存储方式以类 JSON 的文档的格式存储不同引擎有不同的存储方式
查询语句MongoDB 查询方式(类似 JavaScript 的函数)SQL 语句
数据处理方式基于内存,将热数据存放在物理内存中,从而达到高速读写不同引擎有自己的特点
成熟度新兴数据库,成熟度较低成熟度高
广泛度NoSQL 数据库中,比较完善且开源,使用人数在不断增长开源数据库,市场份额不断增长
事务性仅支持单文档事务操作,弱一致性支持事务操作
占用空间占用空间大占用空间小
join 操作MongoDB 没有 joinMySQL 支持 join

# 四、MySQL 数据库

# 介绍

# 数据组织结构

数据库(database)、数据表 (table)、数据行 (row)、字段 (field)

# 库、表、行、字段

①一般每个项目都对应独立的数据库 ②不同数据要存储到不同的表中 ③存储信息由字段决定

# 安装

MySQL Server 和 MySQLWorkbench 软件

①MySQL Server: 提供数据存储和服务的软件 ②MySQLWorkbench 可视化管理 MySQL

# MySQLWorkbench

用 MySQLWorkbench 管理数据库:

(1)创建数据库、创建数据表、设置字段(MySQLWorkbench 中)

设置字段的唯一标识:

①PK (Primary Key 主键、唯一标识)

②NN (Not Null 值不为空)

③UQ (Unique 值唯一)

④AI (Auto Increment 值自动增长)

⑤设置默认值

(2)向数据库中写入数据

①右键 table --> Select Rows - Limit 1000 (设置 AI 和默认值的字段不必完全填写)

# SQL 语言

# 介绍

①SQL 是结构化查询语言,专门用来访问和处理数据库的编程语言,能够让我们以编程的形式,操作数据库里面的数据

②SQL 是一门数据库编程语言,用 SQL 语言编写出的代码叫做 SQL 语句,SQL 只能在关系型数据库中使用,非关系型(mongodb)不支持

③SQL 能查询数据,插入数据,跟新数据,删除数据,创建数据库,在数据库中创建表,数据库中创建存储过程、视图等

# SQL 语法

(关键字大小写相同,<> 和!= 都表示不等于)

①查询数据

select   *  from  表名称                              //指定表中,查询所有数据
select   列名称1 , 名称2   from   表名称               //指定表中,查询指定列(字段) 的数据

②数据表中插入新的数据行

insert  into  表名 (列1  ,  列2.....) values  (值1  ,  值2 ,.......)      //指定表中,插入指定的数据

③修改(更新)表中的数据

update 表名称 set 列名称  =  新值 where 列名称 = 指定值   //指定表中,更新某一列的指定值为新值(不加where更新全部)
update  表名称  set  列名称  = 新值  ,  列名称2 = 新值   where   列名称 = 指定     //指定表中,更新指定一行中多列

④删除表中数据

delete  from  表名  where  列名称  =  指定值     //删除指定行数据

⑤运算符

!= 和 <> 表示不等于 、 and 相当于 && 、 or 相当于 ||

⑥order by 子句(对结果集进行排序)

默认升序 (asc) 对记录进行排序,降序需要使用 desc 关键字

例如: select * from  表名称  order  by  status  desc       //降序
select * from  表名称  order  by  status  desc , id  asc     //多重排序(status降序,id升序)

⑦count (*) (统计查询结果的总数据条数)

例如: select  count(*)  from  表名称  where  status  =  0     //统计表中status为0的数据条数

⑧使用 AS 为列设置别名

例如: select count(*) AS  total  from  users  where  status  =  0    //设置统计表中数据条数的列名为total

# 项目中使用

(1)、安装 MySQL 数据库的第三方模块 (mysql)

npm  install  mysql

(2)、通过 mysql 模块配置并连接到 MySQL 数据库

const  mysql  = require('mysql') ;         //导入mysql模块
const   db  =  mysql.createPool({          //建立与MySQL数据库的连接
host:'127.0.0.1'  , user:'root'  , password:'dmq0216'  , database:'mydb01' //连接数据库ip,登录账号和密码、连接待操作的数据库
})

(3)通过 mysql 模块执行 SQL 语句

# 测试 mysql 模块
db.query('select  1' ,(err,result)=>{         
if(err)  return  console.log(err.message)
console.log(result)
})
# 查询所有数据

(执行 select 语句查询到的是数组)

db.query('select * from users' ,(err,result)=>{         
if(err)  return  console.log(err.message)
console.log(result)
})
# 插入数据

(用(?,?)符进行占位)

const  user  =  { username:'Spider-Man' , password:'dmq0216' }
const  sqlStr 'insert  into  users  ( username , password ) values ( ? , ? )'
db.query(sqlStr , [user.username , user.password ] , (err , result) => {
if(err) return console.log(err.message)
if( result.affectedRows === 1 ){  console.log('插入数据成功'  )  }
})

或 便捷方式:

const  user  =  { username:'Spider-Man' , password:'dmq0216' }
const  sqlStr 'insert  into  users  set ?'
db.query(sqlStr , user , (err , result) => {
if(err) return console.log(err.message)
if( result.affectedRows === 1 ){  console.log('插入数据成功'  )  }
})
# 更新数据

(使用?占位符)

const  user  =  {id=6, username:'Spider-Man' , password:'dmq0216' }
const  sqlStr 'update users set username=? , password=? where id=?'
db.query(sqlStr , user.username , user.password , user.id, (err , result) => {
if(err) return console.log(err.message)
if( result.affectedRows === 1 ){  console.log('更新数据成功'  )  }
})

或 便捷方式:

const  user  =  {id=6 , username:'Spider-Man' , password:'dmq0216' }
const  sqlStr 'update users set ? where id=?'
db.query(sqlStr , [ user , user.id ], (err , result) => {
  if(err) return console.log(err.message)
  if( result.affectedRows === 1 ){  console.log('更新数据成功'  )  }
})
# 删除数据

( 推荐使用 id )

const  sqlStr ' delete from users where id=? '
db.query(sqlStr , 6 , (err , result) => {
if(err) return console.log(err.message)
if( result.affectedRows === 1 ){  console.log('删除数据成功'  )  }
})

标记删除 (为了考虑安全性:在表中设置类似于 status 的状态字段,标记当前数据是否被删除,实际上是 update 语句)

db.query('update users set status=1 where id=?', 6 , (err , result) => {
if(err) return console.log(err.message)
if( result.affectedRows === 1 ){  console.log('删除数据成功'  )  }
})

# 5、MySQL ORM

# 介绍

在 Node.js 项目中,数据库操作是常见的任务之一。而 MySQL 作为一种广泛使用的关系型数据库,与 Node.js 的集成具有重要意义。为了简化数据库操作和提高开发效率,我们可以使用 ORM(对象关系映射)框架。ORM 框架能够将数据库表映射为 JavaScript 对象,使得开发者可以使用面向对象的方式进行数据库操作。

# 优势

一、ORM 框架的优势

  1. 简化数据库操作:ORM 框架提供了丰富的 API,使得开发者无需编写繁琐的 SQL 语句即可完成数据库操作。
  2. 提高开发效率:ORM 框架通常提供了自动化的数据映射、关联查询、事务管理等功能,可以大大提高开发效率。
  3. 增强代码可维护性:使用 ORM 框架可以使得代码更加清晰、易于维护,降低因数据库变更导致的代码修改成本。

二、ORM 框架选择标准

  1. 兼容性:确保所选 ORM 框架与 Node.js 和 MySQL 版本兼容。
  2. 性能:考虑 ORM 框架的性能表现,包括查询速度、内存消耗等。
  3. 社区支持:选择有良好社区支持和文档完善的 ORM 框架,便于解决问题和学习。
  4. 扩展性:考虑 ORM 框架是否支持自定义查询、关联查询等高级功能。
# 常见框架

三、常见的 Node.js ORM 框架

  • Sequelize:一款基于 Promise 的 Node.js ORM 框架,支持多种数据库,包括 MySQL。
  • TypeORM:一个面向 TypeScript 和 JavaScript(ES5,ES6,ES7,ES8)的 ORM 框架,可以在 NodeJS、Cordova、PhoneGap、Ionic、Browser 和 Cordova 中使用。
  • Objection.js:一个基于 SQL 查询生成器的 ORM 库,专为 PostgreSQL 和 MySQL 设计。
# 项目中使用

实践:使用 Sequelize 进行 Node.js 与 MySQL 的集成

  1. 安装依赖
npm install mysql sequelize
  1. 配置数据库连接
const { Sequelize } = require('sequelize');const sequelize = new Sequelize('database', 'username', 'password', {  host: 'localhost',  dialect: 'mysql'});
  1. 定义模型
const User = sequelize.define('user', {  username: {    type: Sequelize.STRING,    allowNull: false  },  password: {    type: Sequelize.STRING,    allowNull: false  }});
  1. 执行数据库操作
// 创建记录const user = await User.create({ username: 'alice', password: '123456' });// 查询记录const users = await User.findAll();// 更新记录await user.update({ password: 'newpassword' });// 删除记录await user.destroy();
# 总结

通过 ORM 框架,我们可以更加便捷地在 Node.js 项目中与 MySQL 数据库进行交互。在选择 ORM 框架时,需要考虑兼容性、性能、社区支持和扩展性等因素。实践中,我们可以使用 Sequelize 等成熟的 ORM 框架来简化数据库操作,提高开发效率。当然,ORM 框架并非银弹,对于复杂的查询和性能要求较高的场景,我们仍然需要编写原生的 SQL 语句。

# 五、Mongodb 数据库

# 使用

# 优势
  • MongoDB 是一个基于分布式文件存储的数据库,官方地址为 http://www.mongodb.com/

  • 数据库是按照数据结构来组织、存储和管理数据的应用程序

数据库的主要作用就是管理数据,对数据进行增、删、改、查

  • 相比于纯文件管理数据,数据库管理数据的特点:①速度更快②扩展性更强③安全性更高

  • 语法与 javascript 相似,容易上手

# 三个概念
  • 数据库(database)

  • 集合(collection)

  • 文档(document)

# 安装
  • MongoDB 安装,与创建默认文件( c:/data/db )

  • 文件中打开 cmd,输入命令 mongod,启动数据库服务(端口号为 27017)

  • 文件中新开 cmd,输入命令 mongo , 请求数据库服务,输入命令 show dbs 显示数据库信息

  • 配置文件环境变量,以方便全局使用

  • 全局命令:mongo 使用数据库、mongoose 启动数据库服务

# 命令

(1) 数据库命令:

show dbs              查看当前数据库下有哪些服务
use 库名             切换到指定的数据库下,没有则创建
db                 显示当前所在的数据库
use 库名
switched to db 库名          转到那个数据库
db.dropDatabase()           删除当前数据库

(2) 集合命令

db.createCollection()           创建集合
show collections             显示当前数据库中的所在
db.集合名.drop()             删除某个集合
db.集合名.renameCollection(‘newName’)   重命名集合

(3) 文档命令

db.集合名.insert({文档对象})              插入文档
db.集合名.find({查询条件})               查询文档
db.集合名.update({查询条件},{新的文档内容})     更新新的文档(属性全部更新)
db.集合名.update({name:’张三’},{$set:{age:19}})     更新文档(部分更新)
db.集合名.remove({查询条件})
# 使用场景

(1) 新增:用户注册、发布视频、发布商品、发布评论等

(2) 删除:删除评论、删除商品、删除文章等

(3) 更新:更新个人信息、修改商品价格等

(4) 查询:商品列表、朋友圈列表等

# Mongoose(DOM)

文档对象模型链接 mongdb 数据库

# 介绍

mongoose 文档对象模型库,官网:http://www.mongoosejs.net/

# 使用

(发送请求服务时必须确保数据库服务启动中)

1 项目初始化

npm init

2 安装 mongoose

npm i mongoose@6.8.0

3 导入 mongoose

const mongoose = require('mongoose');

设置取消部分提示

mongoose.set('strictQuery', true);

4 连接 mongodb 数据库服务

mongoose.connect('mongodb://127.0.0.1:27017/bilibili');

(协议名称://ip 地址:端口号 / 数据库名称)

5 设置回调

设置连接成功的回调

mongoose.connection.once('open', () => {
  // 连接成功的处理代码
});

6 创建文档的结构对象

设置集合中文档的属性以及属性值的类型

let BookSchema =new mongoose.Schema({
  name: String,
  author: String,
  price: Number,
  ishot: Boolean
});

7 创建模型对象 对文档操作的封装对象 (mongoose.model (' 集合名称 ', 结构对象))

let BookModel = mongoose.model('books', BookSchema);

8 文档中新增内容

BookModel.create({
    name: '西游记',
    author: '吴承恩',
    price: 20,
   ishot: true
  },((err, data) => {
    if (err) {
     console.log(err);
      return;
    } console.log(data);
  }))
  // 关闭数据库连接 (项目运行时不使用)
   mongoose.disconnect();
// 设置连接错误的回调
mongoose.connection.on('error', () => {
  console.log('连接失败');
});
// 设置连接关闭的回调
mongoose.connection.on('close', () => {
  console.log('连接关闭');
});
// 手动关闭 mongodb 的连接
 setTimeout(() => {
   mongoose.disconnect();
 }, 2000);
# 字段类型

(在 new 的 mongoose.Schema 和创建的 mongoose.model.create 中注册和写入)

(1) String 类型(字符串)

(2) Number 类型(数字)

(3) Boolean 类型(布尔值)

(4) Array 类型(数组,也可以用 [ ] 来标识)

(5) Date 类型(日期)

(6) Buffer 类型(Buffer 对象)

(7) Mixed 类型(任意对象,需要使用 mongoose.Schema.Types.Mixed 指定)

(8) Objectld 类型(对象 ID,需要使用 mongoose.Schema.Types.Objected 指定)

(9) Decimal128 类型(高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定)

# 字段值验证

(对文档属性的值进行校验,校验通过的值才会被存入数据库,在创建文档结构对象中操作)

(1) 例如给数据库文档中的 name 属性添加字段

name: {
      type: String,
      // 必填项
      required: true,
     // 默认值
      default: '西游记',
     // 枚举值,设置后只能设置在枚举项内的值
      enum: ['言情', '城市', '志怪', '恐怖'],
      // 唯一值,设置为独一无二的值 (在集合里面不能重复)
      unique: true 
    },
# 删除数据

(1) 删除单条文档数据

// 9 删除单条文档
  BookModel.deleteOne({ _id: '647ec30caecaf3c1f3724a84' }, ((err, data) => {
    if(err) {
      console.log('删除失败');
      return;
    } console.log(data);
  }))

(2) 批量删除文档数据

// 10 批量删除
  BookModel.deleteMany({ ishot: true }, (err, data) =>{
    if(err) {
      console.log('删除失败');
      return;
    } console.log(data);
  });
# 更新数据
// 更新单条文档数据
BookModel.updateOne({ name: '西游记' }, { price: 5 }, (err,data)=>{
    if(err) {
      console.log('更新失败');
      return;
    } console.log(data);
  })
// 更新多条文档数据
BookModel.updateMany({ name: '西游记' }, { ishot: false }, (err, data) => {
  if (err) {
    console.log('更新失败');
    return;
  }
  console.log(data);
});
# 读取文档
// (1) 获取单条文档数据
BookModel.findOne({ price: '5' }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// 根据 id 获取单条数据
BookModel.findOne({ '647f11344d39a14410f61725' }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (2) 获得多条文档数据
BookModel.find({ name: '西游记' }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (*)不加条件时获取全部文档数据
# 条件控制
// (1) 运算符:
// > 使用 $gt
// < 使用 $lt
// >= 使用 $gte
// <= 使用 $lte
// !== 使用 $ne
// 14 读取多条文档数据
BookModel.find({ name: '西游记' }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (2) 日志运算
// $or 逻辑或的情况
// db.students.find({$or:[{age:18},{age:24}]}) ;
// $and 逻辑与的情况
// db.students.find({$and:[{age:{$lt:20}},{age:{$gt:15}}]}) ;
BookModel.find({$or:[{author:'曹雪芹'},{author:'余华'}]}, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (3) 正则匹配(条件中可以使用 js 的正则语法,通过正则进行模糊查询)
// 普通正则表达式:
BookModel.find({ name: // }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// 使用变量的正则表达式
BookModel.find({ name: new RegExp('三') }, (err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
# 个性化读取
// (1) select 做字段的筛选(0 表示不要的字段,1 表示要的字段)
BookModel.find().select({ name: 1, author: 1 }).exec((err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (2) sort 进行数据排序(1 是升序,-1 是倒序)
BookModel.find().sort({ price: -1 }).exec((err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (3) limit 进行数据截取,skip 进行第几个数据开始取
BookModel.skip(3).limit(3).exec((err, data) => {
  if (err) {
    console.log('读取失败');
    return;
  }
  console.log(data);
});
// (*)注意多个属性之间可以复用
BookModel.find()
  .select({ name: 1, price: 1 })
  .sort({ price: -1 })
  .skip(3)
  .limit(3)
  .exec((err, data) => {
    if (err) {
      console.log('读取失败');
      return;
    }
    console.log(data);
  });
# 模块化

一、代码模块化

(1) db.js 中创建模块

module.exports = function (success, error) {
  // 导入 mongoose
  const mongoose = require('mongoose');
  // 设置取消部分提示
  mongoose.set('strictQuery', true);
  // 连接 mongodb 数据库服务
  mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
  // 设置连接成功的回调
  mongoose.connection.once('open', () => {
    success();
  });
  // 设置连接错误的回调
  mongoose.connection.on('error', () => {
    error();
  });
  // 设置连接关闭的回调
  mongoose.connection.on('close', () => {
    console.log('连接关闭');
  });
}
// BookModel 中创建模块
const mongoose = require('mongoose');
// 创建文档的结构对象
// 设置集合中文档的属性以及属性值的类型
let BookSchema = new mongoose.Schema({
  name: {
    type: String,
    // 必填项
    required: true,
    // 默认值
    default: '西游记',
    // 枚举值,设置后只能设置在枚举项内的值
    //enum: [' 言情 ', ' 城市 ', ' 志怪 ', ' 恐怖 '],
    // 唯一值,设置为独一无二的值 (在集合里面不能重复)
    // unique: true
  },
  author: String,
  price: Number,
  ishot: Boolean,
  tags: Array,
  pubtime: Date
});
// 创建模型对象 对文档操作的封装对象 (mongoose.model (' 集合名称 ', 结构对象))
let BookModel = mongoose.model('books', BookSchema);
// 暴露模型对象
module.exports = BookModel;

(3) index 文件中引用模块

// 导入 db 文件
const db=require('./db/db');
// 导入 monfoose
const mongoose=require('mongoose');
// 导入 BookModel
const BookModel **=** require('./models/BookModel');
// 调用函数
db(()=>{
   // 8 文档中新增内容
   BookModel.create({
     name: '西游记',
     author: '吴承恩',
     price: 20,
     ishot: true
   },((err,data)=>{
     if(err) {
       console.log(err);
       return;
     } console.log(data);
   }))
}, ()=>{
  console.log('连接失败');
});

二、配置文件模块化

(1)config.js 中暴露模块

// 配置文件
module.exports={
  DBHOST: '127.0.0.1',
  DBPORT: 27017,
  DBNAME: 'bilibili'
}

(2)db.js 中使用模块

导入配置文件

const {DBHOST,DBPORT,DBNAME}=require('../config/config.js');

连接 mongodb 数据库服务

mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`);
# 图形化工具

(Robo3T 和 navicate)

作用:代替 mongo 命令进行操作数据库,便于操作 mongod 数据库服务启动再去进行操作

# 六、CouchDB 数据库

# 介绍

  • CouchDB 数据常用作 npm 等包管理仓库的数据库

  • CounchDB 数据库和 mongodb 数据库一样都支持文档存储,是典型的 NOSQL 数据库

  • CouchDB 数据库使用分布式架构,可以简单地将数据复制到多个服务器上,并且能自动进行同步,适合处理分布式数据和离线应用

  • CouchDB 倾向于提供强一致性,使用 MVCC(多版本并发控制)来处理并发写操作,并在复制和同步时保持一致性

  • CouchDB 非常适合于离线应用程序,用户可以继续使用并修改数据,当网络重新连接时,数据会自动同步。

  • CouchDB 是一个 RESTful 数据库,其操作完全走 HTTP 协议。

# 使用场景

选择 CouchDB 还是 MongoDB 取决于具体的应用需求和场景:

  • 如果需要一个支持强一致性、适合离线应用、并且需要在多个设备之间同步数据的数据库,CouchDB 可能是更好的选择
  • 如果需要高性能、灵活的文档模型、丰富的查询语言、并且需要支持大规模数据集的水平扩展,MongoDB 可能是更好的选择
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

dmq 微信支付

微信支付

dmq 支付宝

支付宝