文章目录
数据库类型
数据库有两种关系型数据库和非关系型数据库
关系型数据库
(1) sq|语句增删改查操作
(2) 保持事务的-致性事物机制(回滚)
常见的关系型数据库有:mysql,sqlserver,db2,oracle
非关系型数据库
(1) no sql:not only sql;
(2) 轻量,高效自由。
常见的非关系型数据库有:mongodb ,Hbase,Redis
MongoDB的优点
- 由于MongoDB独特的数据处理方式,可以将热点数据加载到内存,故而对查询来讲,会非常快(当然也会非常消耗内存) ;
- 采用了BSON(二进制的json)的方式存储数据,故而对JSON格式数据具有非常好的支持性以及友好的表结构修改性 ;
- 文档式的存储方式,数据友好可见;
- 主键MongoDB自动将_ id字段设置为主键
术语解释
sql术语 | MongoDB术语 | 解释、说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_ id字段设置为主键 |
MongoDB的下载安装使用
下载
这里使用它免安装版本:https://link.youkuaiyun.com/?target=https%3A%2F%2Ffastdl.mongodb.org%2Fwin32%2Fmongodb-win32-x86_64-2012plus-4.1.7.zip
下载之后进行解压就可以直接使用了
启动数据库
找到mongodb下的bin文件夹:mongodb-win32-x86_64-2012plus-4.1.7\bin
在此打开终端,输入命令:.\mongod.exe --dbpath=数据库文件存储路径
eg:
数据库启动,不要关闭窗口,否则数据库服务也就关了。
验证数据库是否启动成功:
再该文件夹下新打开一个终端,输入:.\mongo.exe
输出以下内容说明连接成功。
MongoDB数据库的简单命令
数据库的创建
show dbs
:查看数据库个数use 数据库名
:创建数据库,如果当前数据库存在就切换数据库
创建完成之后执行show dbs不能显示该数据库,需要向里面创建集合才能显示db.createCollection("集合名")
:创建集合db
:查看当前数据库db.dropDatabase()
:删除当前数据库db.getCollectionNames()
:获取当前数据库的所有集合db.集合名.drop()
:删除集合
eg:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> db
test
> use yang
switched to db yang
> db
yang
> db.createCollection("users")
{ "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
yang 0.000GB
> db.dropDatabase()
{ "dropped" : "yang", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
集合数据的增删改查
(1)增
db.集合名.save(数据)
:向集合添加数据
db.集合名.save(数据)可以一次存储多条数据db.集合名.find()
:查看集合的数据内容
eg:
> db.users.save({name:"yang",age:18})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 18 }
补充: 非关系型数据库对关系型数据库而言最大的一个特点是自由,就是说一个集合,可以存储不一样的字段,甚至字段的个数也可以不一样
eg:
> db.users.save([{name:"cheng",age:18},{name:"zhangsan",age:20}])
> db.users.save([{username:"lisi",password:18}])
> db.users.save([{username:"wangwu",password:123456,age:22}])
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 18 }
{ "_id" : ObjectId("62c6b617e6db789d05b42d08"), "username" : "lisi", "password" : 18 }
{ "_id" : ObjectId("62c6b62ee6db789d05b42d0a"), "username" : "wangwu", "password" : 123456, "age" : 22 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
(2)删
- db.集合名.remove({}):删除集合所有数据
- db.集合名.remove({password:18}):删除集合中password是18的数据
eg:
> db.users.remove({password:123456})
WriteResult({ "nRemoved" : 1 })
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
(3)改
db.集合名.update({查找的条件},{$set:{修改后的值}})
eg:db.users.update({name:“yang”},{$set:{age:200}})表示将users表中name是yang的数据的age设置成 200db.集合名.update({查找的条件},{$inc:{修改后的值}})
eg:db.users.update({name:“yang”},{$inc:{age:200}})表示将users表中name是yang的数据的age增加 200
> db.users.update({user:"yang"},{$set:{age:200}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
> db.users.update({name:"yang"},{$set:{age:200}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 200 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
> db.users.update({name:"yang"},{$inc:{age:-180}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
(4)查
db.集合名.find()
:查询数据库中的所有信息db.集合名.find({属性限制})
:查询数据库中满足属性限制的信息
> db.users.find({age:20})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
- $gt 表示大于
- $gte 表示大于等于
- $lt 表示小于
- $lte 表示小于等于
> db.users.find({age:{$gt:20}})
> db.users.find({age:{$gte:20}})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
> db.users.find({age:{$lt:20}})
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
> db.users.find({age:{$lte:20}})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
> db.users.find({age:{$lte:20,$gt:18}})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
db.users.find({age:{$lte:20,$gt:18}})
表示查找年龄大于18小于等于20的
模糊查询:正则
db.users.find({name:/y/})
:查找名字中包含y的数据
> db.users.find({name:/y/})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
db.users.find({},{name:1})
:表示只显示name(id属性默认显示)db.users.find({},{name:1,_id:0})
:真正的只显示name
> db.users.find({},{name:1})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang" }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng" }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan" }
> db.users.find({},{name:1,_id:0})
{ "name" : "yang" }
{ "name" : "cheng" }
{ "name" : "zhangsan" }
db.users.find().sort({age:1})
:将查找结果按年龄正序排序db.users.find().sort({age:-1})
:将查找结果按年龄逆序排序
> db.users.find().sort({age:1})
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
> db.users.find().sort({age:-1})
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
db.users.find().skip(2).limit(2)
:表示跳过两条数据,取两条数据
> db.users.find()
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d0f"), "name" : "aaa", "age" : 12 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d10"), "name" : "bbb", "age" : 17 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d11"), "name" : "ccc", "age" : 16 }
> db.users.find().skip(0).limit(2)
{ "_id" : ObjectId("62c6b44ee6db789d05b42d06"), "name" : "yang", "age" : 20 }
{ "_id" : ObjectId("62c6b675e6db789d05b42d0c"), "name" : "cheng", "age" : 18 }
> db.users.find().skip(2).limit(2)
{ "_id" : ObjectId("62c6b675e6db789d05b42d0d"), "name" : "zhangsan", "age" : 20 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d0f"), "name" : "aaa", "age" : 12 }
> db.users.find().skip(4).limit(2)
{ "_id" : ObjectId("62c6bee7e6db789d05b42d10"), "name" : "bbb", "age" : 17 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d11"), "name" : "ccc", "age" : 16 }
我们一般将skip当作页的概念,所以上述查询可以这样写:
*2代表每页两条数据
db.users.find().skip((1-1)*2).limit(2) :表示取第1页的两条数据
db.users.find().skip((2-1)*2).limit(2):表示取第2页的两条数据
db.users.find().skip((3-1)*2).limit(2):表示取第3页的两条数据
如果写成
db.users.find().skip((1-0)*3).limit(2):每页3条数据,表示取第1页的2条数据
db.users.find({$or:[{age:12},{age:17}]})
表示查找年龄是12或17的。
> db.users.find({$or:[{age:12},{age:17}]})
{ "_id" : ObjectId("62c6bee7e6db789d05b42d0f"), "name" : "aaa", "age" : 12 }
{ "_id" : ObjectId("62c6bee7e6db789d05b42d10"), "name" : "bbb", "age" : 17 }
db.users.findOne()
:查找第一条数据
> db.users.findOne()
{
"_id" : ObjectId("62c6b44ee6db789d05b42d06"),
"name" : "yang",
"age" : 20
}
db.users.find().count()
:表示查找数据共多少条
> db.users.find().count()
6
MongoDB的可视化工具
下载地址:https://pan.baidu.com/s/1p2hwJ75IWJV_dX0XPYv0Aw
nodejs操作MongoDB(express框架)
连接数据库
- 需要下载 mongoose 模块:
npm i mongoose
- 创建db.config.js:
填写如下内容:
// 连接数据库
const mongoose = require("mongoose")
mongoose.connect("mongodb://127.0.0.1:27017/yang_project")
// 插入集合和数据,yang_project会自动创建
//yang_project是要创建的数据库名称
- 在bin下的www文件中添加如下内容
// 引入数据库模块
require("../config/db.config")
这样就完成了数据库的连接。
编写数据库操作语句
- 创建一个模型(user,限制filed类型),对应数据库的集合(users)
如创建user模型:
UserModel.js
const mongoose = require("mongoose")
const UserType = {
username: String,
password: String,
age:Number
}
// 创建user模型
const UserModel = mongoose.model("user",new mongoose.Schema(UserType))
// 模型user将会对应 users集合(自动创建users集合)
module.exports = UserModel
- 增 :向数据库中添加内容
模型.create(添加的数据)
方法
eg:
router.post("/user/add", (req, res) => {
console.log(req.body)
// 插入数据库
//1.创建一个模型(user,限制filed类型),对应数据库的集合(users)
const { username, password, age } = req.body
// .create就相当于插入
UserModel.create({
username: username,
password: password,
age:age
}).then(data => {
console.log(data)
res.send({ok:1})
})
})
- 改:update修改数据库中的内容
模型.updateMany(查找条件,修改的内容)
:如果找到多项匹配修改多个
模型.updateOne(查找条件,修改的内容)
:如果找到多项匹配修改一个
router.post("/user/update/:id", (req, res) => {
console.log(req.body, req.params)
const {username,password,age} = req.body
UserModel.updateOne({ _id: req.params.id }, {
username,password,age
}).then(data => {
res.send({
ok:1
})
})
})
- 删:删除数据库中的内容
模型.deleteMany(查找条件)
:如果找到多项匹配删除多个
模型.deleteOne(查找条件)
:如果找到多项匹配删除一个
router.get("/user/delete/:id", (req, res) => {
UserModel.deleteOne({ _id: req.params.id }).then(data => {
res.send({
ok:1
})
})
})
- 查
模型.find()
:查找全部数据
router.get("/user/list", (req, res) => {
UserModel.find().then(data => {
res.send(data)
})
})
模型.find({},[字段名称])
:查找部分字段数据模型.find().sort(排序依据字段:-1/1)
:查找部分字段数据
1: 表示正序排(从小到大)
-1:表示逆序排
router.get("/user/list", (req, res) => {
UserModel.find({},["username","age"]).sort({age:1}).then(data => {
res.send(data)
})
})
- 分页查询:
模型.find().skip((page-1)*limit).limit(limit)
变量:page:第几页;limit:取几条数据
router.get("/user/list", (req, res) => {
console.log(req.query)
const {page,limit} = req.query
UserModel.find ({},["username","age"]).sort({age:1}).skip((page-1)*limit).limit(limit).then(data => {
res.send(data)
})
})
例子:
需求实现如下效果
代码:
目录:
users.js:
var express = require('express');
const UserModel = require('../model/UserModel');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.post("/user/add", (req, res) => {
console.log(req.body)
// 插入数据库
//1.创建一个模型(user,限制filed类型),对应数据库的集合(users)
const { username, password, age } = req.body
// .create就相当于插入
UserModel.create({
username: username,
password: password,
age:age
}).then(data => {
console.log(data)
res.send({ok:1})
})
})
// 更新updateMany:修改多个,updateOne修改一个
// 动态路由获取id
router.post("/user/update", (req, res) => {
console.log(req.body, req.query)
const {username,password,age} = req.body
UserModel.updateOne({ _id: req.query.id }, {
username,password,age
}).then(data => {
res.send({
ok:1
})
})
})
router.get("/user/delete/:id", (req, res) => {
console.log(req.params)
UserModel.deleteOne({ _id: req.params.id}).then(data => {
res.send({
ok:1
})
})
})
router.get("/user/list", (req, res) => {
console.log(req.query)
const {page,limit} = req.query
UserModel.find ({},["username","age"]).sort({age:1}).skip((page-1)*limit).limit(limit).then(data => {
res.send(data)
})
})
module.exports = router;
app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/api', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.ejs:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" href="/stylesheets/style.css" />
</head>
<body>
<div>
<div>用户名:<input id="username" /></div>
<div>密码:<input type="password" id="password" /></div>
<div>年龄:<input type="number" id="age" /></div>
<div><button id="register">登录</button></div>
<hr />
<div>
<button id = "update" value="62c7829583a8ba1ed48f92ed">更新</button>
<button id = "delete">删除</button></div>
<br>
<table border="1">
<thead>
<tr>
<td>id</td>
<td>用户</td>
<td>年龄</td>
<td>操作</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script type="text/javascript">
var register = document.querySelector("#register");
var username = document.querySelector("#username");
var password = document.querySelector("#password");
var update = document.querySelector("#update");
var mydelete = document.querySelector("#delete");
function updateFun(){
console.log(this.value)
fetch(`/api/user/update?id=${this.value}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: "名字",
password: "密码",
age: 1,
}),
})
.then((res) => res.json())
.then((res) => {
console.log(res);
});
};
register.onclick = () => {
console.log(username.value, password.value, age.value);
fetch("/api/user/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: username.value,
password: password.value,
age: age.value,
}),
})
.then((res) => res.json())
.then((res) => {
console.log(res);
});
};
update.onclick = updateFun
mydelete.onclick = () => {
fetch("/api/user/delete/62c7829583a8ba1ed48f92ed")
.then((res) => res.json())
.then((res) => {
console.log(res);
});
};
// 第一页数据,要两条
fetch("/api/user/list?page=1&limit=2").then(res=>res.json()).then((res)=>{
console.log(res)
var tbody = document.querySelector("tbody")
// map映射
tbody.innerHTML = res.map(item=>`
<tr>
<td>${item._id}</td>
<td>${item.username}</td>
<td>${item.age}</td>
<td> <button class="update" value="${item._id}"">更新</button><button class="delete">删除</button> </td>
</tr>
`).join("")
})
</script>
</body>
</html>
UserModel.js
// 使用mongos模块连接mongoDB
const mongoose = require("mongoose")
// 限制模型,必须和数据库一致
const UserType = {
username: String,
password: String,
age:Number
}
// 创建user模型
const UserModel = mongoose.model("user",new mongoose.Schema(UserType))
// 模型user将会对应 users集合(自动创建users集合)
module.exports = UserModel