一、数据库(Database)
1.1 数据简介
- 数据库是按照数据结构来组织、存储和管理数据的仓库。
- 我们的程序都是在内存中运行的,一旦程序运行结束或者计算机断电,程序运行中的数据都会丢失。
- 所以我们就需要将一些程序运行的数据持久化到硬盘之中,以确保数据的安全性。而数据库就是数据持久化的最佳选择。说白了,数据库就是存储数据的仓库。
1.2 数据库分类
数据库主要分成两种:
1.2.1 关系型数据库(RDBMS)
MySQL、Oracle、DB2、SQL Server...
关系数据库中全都是表
1.2.2 非关系型数据库(No SQL)
MongoDB、Redis
文档数据库MongoDB
二、MongoDB
2.1 MongoDB简介
- MongoDB是为快速开发互联网Web应用而设计的数据库系统。
- MongDB的设计目标是极简、灵活、作为Web应用栈的一部分。
- MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据中存的是各种各样的JSON。(BSON)
三个概念
- 数据库-数据库是一个仓库,在仓库中可以存放集合。
- 集合-集合类似于数据,在集合中可以存放文档。
- 文档-文档数据库中的最小单元,我们存储和操作的内容都是文档。
2.2 MongoDB下载
2.2.1 下载地址
http://www.mongodb.org/dl/win32/
MongoDB的版本偶数版本为稳定版,奇数版本为开发版。
MongDB对于32位系统支持不佳,所以3.2版本以后没有再对32位系统的支持。
2.2.2 安装
1.双击文件
2.配置环境变量
3.在D盘根目录
-创建一个文件夹data
-在data中创建一个文件夹db
4.打开cmd命令行窗口
输入mongod 启动mongodb服务器
32位注意
启动服务器时,需要输入如下内容
mongod --storageEngine==mmapv1
设置mongodb的db路径和端口号
mongod --dbpath D:\data\db --port 27017
5. 再打开一个cmd窗口
输入mongo 连接mongodb,出现>
6.数据库
-数据库的服务器
- 服务器用来保存数据
- mongod用来启动服务器
数据库的客户端
- 客户端用来操作服务器,对数据进行增删改查的操作
- mongo用来启动客户端
7.将MongoDB设置为系统服务,可以自动在后台启动,不需要每次都手动启动
-在D盘根目录创建data--在data下创建db和log文件夹
-创建配置文件
在目录D:\StudySoftware\MongoDB下添加一个配置文件
-以管理员的身份打开命令行窗口
执行如下的命令
sc.exe create MongoDB binPath="\"D:\mongod的bin目录\mongod.exe\" --service --config=\"mongo的安装目录\mongod.cfg\" DisplayName="MongoDB" start= "auto"
sc.exe create MongoDB binPath="\"D:\StudySoftware\MongoDB\bin\mongod.exe\" --service --config=\"D:\StudySoftware\MongoDB\mongod.cfg\" DisplayName="MongoDB" start= "auto"
8.启动mongodb服务
以管理员身份执行
net start mongodb
net stop mongodb
9.启动失败
如果启动失败,证明上边的操作有误,在控制台输入 sc delete MongoDB删除之前配置的服务,然后从第一步再来一次
2.3 数据库操作
2.3.1 基本概念
数据库(database)、集合(collection)、文档(document)
在MongoDB中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合。
2.3.2 基本指令
--显示所有的数据库
show dbs
show databases
-- 进入数据库,不管有没有可以直接进入,会在第一次插入文档的时候,创建
use test
--查看当前所处的数据库
db
--显示数据库中所有的集合
show collections
2.3.3 数据库的CRUD(增删改查)的操作
-向数据库中插入文档
db.<collection>.insert(doc)
-向集合中插入一个或多个文档
-当我们向集合中插入文档时,如果没有给文档指定_id属性,则数据库会自动为文档添加_id
-_id我们可以自己指定,如果我们指定了数据库就不会再添加了,如果自己指定_id也必须确保它的唯一性
-例子:向test数据库中的,stus集合中插入一个新的学生对象{name:"孙悟空",age:18,gender:"男"}
db.stus.insert({name:"孙悟空",age:18,gender:"男"});
db.stus.insert([{name:"1"},{name:"2"]);
-插入一个文档对象
db.collection.insertOne()
-插入多个文档对象
db.collection.insertMany()
数据库和集合不需要手动创建,会自动创建
-查询数据
db.<collection>.find()
-查询当前集合中的所有的文档
db.stus.find()
-find()可以接收一个对象作为条件参数
db.stus.find({})表示查询集合中所有的文档
-{属性:值}查询属性是指定值的文档
db.stus.find({_id:"hello"});
-用来查询集合中符合条件的第一个文档
-findOne()返回的是一个文档对象,find()返回的是一个数组
db.collection.findOne();
db.collection.findOne({age:28}).name;
-查询所有结果的数量
db.collection.find({}).count();
db.collection.find({}).length();
-修改数据
db.collection.update(查询条件,新对象)
-update()默认情况下会使用新对象来替换旧的对象
-如果需要修改指定的属性,而不是替换需要使用"修改操作符"来完成修改
db.stus.update({name:"1"},{age:28});
$set可以用来修改文档中的指定属性
db.stus.update({"name":"1",
{$set:{gender:"男"}}
)
$unset 可以用来删除文档的指定属性
db.stus.update({"name":"1",
{$unset:{gender:"男"}}
)
-修改一个符合条件的文档
db.collection.updateOne()
-同时修改多个符合条件的文档
db.collection.updateMany()
-替换一个文档
db.colection.replaceOne()
-删除数据
-remove()可以根据条件来删除文档,传递条件的方式和find()一样
-删除符合条件的所有的文档,默认情况下会删除多个
-如果remove()第二个参数传递一个true,则只会删除一个
db.stus.remove({age:28},true);
db.collection.remove()
db.stus.remove({_id:"hello"});
db.collection.deleteOne()
db.collection.deleteMany()
//清空集合(性能略差),删除所有的文档,集合还在
db.stus.remove({});
//删除集合,集合没有了
db.stus.drop();
//删除数据库
db.dropDatabase();
2.4 练习
--1.进入my_test数据库
use my_test
--2.向数据库的user集合中插入一个文档
db.users.insert({username:"1});
--3.查询user集合中的文档
db.users.find();
--4.向数据库的user集合中插入一个文档
db.users.insert({username:"2"});
--5.查询数据库user集合中的文档
db.users.find();
--6.统计数据库user集合中的文档数量
db.users.find().count();
--7.查询数据库user集合中username为1的文档
db.users.find({username:"1"});
--8.向数据库user集合中的username为"1"的文档,添加一个address属性,属性值为1
db.users.update({username:"1",{$set:{address:"1"});
--9.使用{username:"1"}替换username为"2"的文档
db.users.replaceOne({username:"1"},{username:"2"});
--10.删除username为“1”的文档的address属性
db.users.update({username:"1",{$unset:{address:1}});
--11.向username为“1”的文档中添加一个hobby:{cities:["1","2"], "movies":["1","2"]}
//MongoDB的文档的属性值也可以是一个文档,当一个文档的属性值是一个文档时,我们称这个文档叫做内嵌文档
db.users.update({username:"1",{$set:{hobby:{cities:["1","2"],movies:["1","2"]}}}
--12 查询喜欢电影hero的文档
--MongoDB支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档则可以通过.的形式来匹配
--如果要通过内嵌文档来对文档进行查询,此时属性名必须使用引号
db.users.find({"hobby.movies":"hero"});
--13.向tangseng中添加一个新的电影Interstellar
--$push用于向数组中添加一个新的元素
--$addToSet向数组中添加一个新元素,如果数组中已经存在了该元素,则不会添加
db.users.update({username:"tangseng"},{$push:{"hobby.movies":"Insterstellar"});
db.users.update({username:"tangseng"},{$addToSet:{"hobby.movies":"Insterstellar"});
--14.删除喜欢beijing的用户
db.users.remove({"hobby.cities":"beijing"});
--15.删除user集合
db.users.remove({});
db.users.drop();
--16.向numbers中插入20000条数据 7.5s
for(var i=1; i<=20000;i++) {
db.numbers.insert({num:i});
}
--0.4s
var arr = [];
for (var i=1; i<=20000; i++) {
arr.push({num:i});
}
db.numbers.insert(arr);
--17.查询numbers中num为500的文档
db.numbers.find({num:500})
--18.查询numbers中num大于500的文档
db.numbers.find({num:{$gt:500}});
db.numbers.find({num:{$eq:500}});
--19.查询numbers中num小于30的文档
db.numbers.find({num:{$lt:30}});
--20.查询numbers中num大于40小于50的文档
db.numbers.find({num:{$gt:40,$lt:50}});
--21.查询numbers中num大于19996的文档
db.numbers.find({num:{$gt:19996}});
--22.查询numbers集合中的前10条数据
db.numbers.find({num:{$lte:10}});
--limit()设置显示数据的上限
db.numbers.find().limit(10);
--在开发时,我们绝对不会执行不带条件的查询
db.numbers.find();
--23.查看numbers集合中的第11条到20条数据
分页 每页显示10条
1-10 11-20 21-30
skip()用于跳过指定数量的数据
MongoDB会自动调整skip()和limit()的顺序
db.numbers.find().skip(10).limit(10);
--24.查看numbers集合中的第21条到30条数据
db.numbers.find().skip(20).limit(10);
2.5 文档间的关系
2.5.1 一对一(one to one)
-夫妻(一个丈夫对应一个妻子)
-在MongoDB,可以通过内嵌文档的形式来体现一对一的关系
db.wifeAndHusband.insert([
{name:"黄蓉",husband:{name:"郭靖"},
{name:"杨过",husband:{name:"小龙女"}
])
2.5.2 一对多(one to many)/多对一(many to one)
-父母 - 孩子
用户-订单
文章-评论
也可以通过内嵌文档来映射一对多的关系
--一对多 用户(users)和订单(orders)
db.users.insert([{username:"swk"},
{username:"zbj"}]);
db.order.insert({list:["苹果","香蕉"],
user_id:ObjectId("sdfsfsdfs")
});
--查找用户swk的订单
var user_id = db.users.findOne({username:"swk"})._id;
db.order.find({user_id:user_id});
2.5.3 多对多(many to many)
分类-商品
老师-学生
db.teachers.insert([{name:"洪七公"},
{name:"黄药师"},
{name:"龟仙人"}
]);
db.stus.insert([
{name:"郭靖",
tach_ids:[
ObjectId("sdfs"),
ObjectId("sdfa")
]},
{name:"孙悟空",
tach_ids:[
ObjectId("sdfs"),
ObjectId("sdfa")
]}
]);
2.6 练习
--1.查询工资小于2000的员工
db.emp.find({sal:{$lt:2000}});
--2.查询工资在1000-2000之间的员工
db.emp.find({sal:{$lt:2000, $gt:1000}});
--3.查询工资小于1000或大于2500的员工
db.emp.find($or:[sal:{$lt:1000}},{sal:{$gt:2500}}]});
--4.查询财务部的所有员工
var depno = db.dept.findOne({dname:"财务部"}).deptno;
db.emp.find({depno:depno});
--5.查询所有mgr为7698的所有员工
db.emp.find({mgr:7698})
--6.为所有薪资低于1000的员工增加工资400元
db.emp.updateMany({sal:{$lte:1000}},{$inc:{sal:400}});
2.7 sort和投影
//查询文档时,默认情况是按照_id的值进行排列(升序)
//sort()可以用来指定文档的排序的规则,sort()需要传递一个对象来指定排序规则,1表示升序 -1表示降序
//limit skip sort可以以任意的顺序进行调用
db.emp.find({}).sort({sal:1,empno:-1});
//在查询时,可以在第二个参数的位置来设置查询结果的投影
db.emp.find({},{ename:1, _id:0, sal:1});