基于MongoDB的非关系型数据库的设计与应用
2022-06-08武佳丽余啟旺谢楚源鲁健华董元和
白 洁,武佳丽,余啟旺,谢楚源,鲁健华,董元和
(湖北师范大学 计算机与信息工程学院,湖北 黄石 435002)
0 引言
随着互联网的不断发展,数据库技术也为适应不同环境,不断取得进展。当传统的关系型数据库难以适应动态网站的快速响应速度时,便产生了新型非关系型数据库,旨在解决大规模数据的多重数据种类带来的诸多性能难题。本文通过对非关系型数据库的代表MongoDB数据库和SQLsever数据库的性能对比,用实例对MongoDB数据库关键技术进行分析,用node.js技术来对MongoDB数据库进行封装操作,来阐述ModgoDB等非关系数据库在响应式Web应用的优越性能。
1 MongoDB技术
1.1 数据库介绍
数据库是长期存储在计算机内的有组织的、可共享的数据集合,是按照数据的结构来组织和管理数据的仓库。内存中运行的程序多多少少都会出现数据丢失的问题,因此需要将运行的数据持久化的保存到硬盘中,以确保数据的安全,数据库则成为了数据持久化的最佳选择。
数据库主要分为关系型数据库(SQL)和非关系型数据库(NoSQL)两大类。关系型数据库主要采用基于行和列的二维表关系模型来组织和存储数据,其代表有MySQL、Microsoft SQL Server等。非关系型数据库则主要是利用键值对方式来组织和存储[1]数据,不局限于固定的结构,其代表有MongoDB等。两者比较如下:
1)存储结构:以Microsoft SQL Server和MongoDB数据库[2]为例,前者是从数据库、表、记录三个层次构建数据库,最终以表格形式存储;后者则是从数据库、集合、文档对象三个层次进行构建,用键值对实现存储。
2)成本:NoSQL容易部署,基本都是开源软件,不需要像使用Oracle那样花费大量成本,相比SQL数据库来说成本较低。
3)查询速度:NoSQL数据库将数据存储在缓存之中,不需要经过SQL层解析,而SQL存储在硬盘当中,因此查询速度远不及NoSQL数据库。
4)可扩展性:SQL数据库有类似join的多表查询机制,导致扩展较为困难;而Nosql数据库是基于键值对的存储,数据之间耦合度低,独立性较好,容易扩展。
5)持久性存储:NoSQL数据库不适合持久存储,海量数据的持久存储应该选择SQL数据库。
1.2 MongoDB简介
MongoDB是一个基于分布式文件存储的非关系型数据库,它是为快速开发Web应用而产生,可以对应用进行插入、更新与查询等实时数据处理操作,并具备实时数据存储所需的复制及高度伸缩性。MongoDB具有面向文档的、易操作、易部署、易存储等特点。
MongoDB是非关系型数据库中最像关系型数据库的,其中文档(Document)是 MongoDB 中数据的基本单位,类似于关系数据库中的行数据,有多个键和关联的值有序结合而组成;集合(Collection)类似于关系数据库中的表,可将文档分类放在不同的集合中,结构清晰,以便高效地进行查询操作;数据库(DataBase)则是由多个集合组成。
MongoDB数据库的层次结构如图1所示,其基本的层次关系为:一套数据库管理软件可以包括多个数据库,而每个数据库下又可以包含多个集合,集合则为该数据库中同一类的数据,每个集合中又可以包含多个文档,文档则是具体一条条的数据,而每条数据的属性名称又可以叫做字段。
图1 MongoDB数据库层次结构
在本设计中,主要使用Mongoose,它是MongoDB的一个对象模型工具,是基于node-MongoDB-native开发的MongoDB的node.js驱动,可以在异步的环境下执行,同时也是针对MongoDB操作的一个对象模型库[2],封装了MongoDB对文档的一些增删改查等常用方法,让node.js操作[3]MongoDB数据库变得更加容易。Mongoose提供了几个新的对象:Schema,Model,Document,其中Schema定义且约束了数据库中的文档结构,Model相当于collection集合。
2 MongoDB数据库设计实现
本文实例项目是旅游类的电子导游项目[4],系统中数据库模型包括管理员、新闻、消息、用户等模型,其系统总体E-R图如图2所示。
图2 系统总体E-R图
下面主要以用户登录功能为例,介绍ModgoDB的基本操作与应用过程。其对应的数据库设计的用户集合如表1以及E-R图如图3所示。举例说明用MongoDB的对象模型Mongoose实现数据库的基本操作。
表1 用户集合
图3 用户E-R图
1)数据库连接。首先用require语句来加载模块,创建一个新的数据库,然后用connect语句来对数据库进行连接,语句中的url用来指定服务器的地址。
const mongoose = require('mongoose')
mongoose.set('useCreateIndex', true)
mongoose.connect('mongodb://localhost:27017/server', {
useNewUrlParser: true,
useUnifiedTopology: true
})
2)创建集合。在数据库连接成功后,则要设定集合规则和创建集合,主要分为两步:一是通过定义schema,来设定集合规定,描述该集合中有哪些字段以及字段类型,类似于表结构中行的作用;二是应用规则进行创建,且只有schema中定义的属性才可被创建。其中主要是用到Mongoose中的schema以及model方法,model函数的构造方法中第一个参数是集合名称(首字母要大写),而第二个参数就是集合规则,若短可以直接写对象在其中。model方法返回当前集合的构造函数,若想在集合中追加内容,就需要先通过该构造函数创建文档[3]。
创建文档也分为两步:一是创建集合实例;二是调用实例对象下的save方法将数据保存到数据库中。另外一种方法则是构造create函数来对文档进行创建。
const schema = new mongoose.Schema({
username:{ type: String },
password:{
type: String,//select:false密码默认不能被查询到
select:false,//对密码进行散列加密处理
set(val){
return require('bcrypt').hashSync(val, 10)
} },
avatar:{ type: String }
},
{ timestamps: true})
module.exports = mongoose.model('AdminUser',schema)
3)基本操作的实现。同关系型数据库一样,MongoDB数据库也可以实现增删改查的基本操作。本项目通过如图4所示node.js操作数据库[5],即数据库提供的API去操作数据库,借助Mongoose来对数据库中的model进行调用,实现数据的增删改查操作。
图4 node.js操作数据库
下面以数据库的增加信息为例,演示代码实现数据添加的过程,其余集合中的操作与此类似。
一般来说,MongoDB 使用 insert()或 save()方法向集合中插入数据,它们二者的区别在于:前者如果插入的数据主键存在,则会显示主键存在,对当前数据不进行保存;后者则是主键如果存在,就可以对数据进行更新,若不存在就插入。插入过程中需要创建一个新的users文件,调用save函数来存储新增用户的信息。其代码实现如下:
const User = require('./users');
const user = new User({
username: '李思思',
password: '123',
age: 22,
tel: '13248099856',
sex: '女',
city: '山西'
})
user.save((err)=> {
if(err)throw err;
console.log('用户插入成功')
})
3 结语
在本项目的设计过程中,充分体现了MongoDB数据库低成本,易操作、方便写入的优良性能。同时也暴露出其诸多缺点,一方面,若旅游数据量过大,对其查询速度有明显的影响;另一方面,在删除记录后不主动释放空间,对空间的占用较大。因此在设计实践过程中还需要对数据库进行合理的优化设计。