MongoDB基本介绍
传统的关系型数据库(如MySQL),在数据操作的“三高”需求以及应对Web2.0的网站需求面前,显得力不从心。 解释:“三高”需求:
- High performance - 对数据库高并发读写的需求。
- Huge Storage - 对海量数据的高效率存储和访问的需求。
- High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求。
而MongoDB可应对“三高”需求。
具体的应用场景如:
- 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
- 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。
- 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。
- 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
- 视频直播,使用 MongoDB 存储用户信息、点赞互动信息等。
这些应用场景中,数据操作方面的共同特点是: 数据量大 、写入操作频繁(读写都很频繁)、价值较低的数据,对事务性要求不高对于这样的数据,我们更适合使用MongoDB来实现数据的存储。
所以什么是MongoDB?
MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最 像关系型数据库(MySQL)的非关系型数据库。
它支持的数据结构非常松散,是一种类似于 JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。
MongoDB中的记录是一个文档,它是一个由字段和值对(field:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。
什么东西都是这样,类比一下,一下子就清晰了很多:
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据行/文档 |
column | filed | 数据库字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
嵌入文档 | MongoDB通过嵌入式文档来替代多表连接 | |
primary key | primary key | 主键/MongoDB自动将_id字段设置为主键 |
数据类型
MongoDB的最小存储单位就是文档(document)对象。文档(document)对象对应于关系型数据库的行。数据在MongoDB中以 BSON(Binary-JSON)文档的格式存储在磁盘上。
BSON(Binary Serialized Document Format)是一种类似json的一种二进制形式的存储格式,简称Binary JSON。BSON和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。
BSON采用了类似于 C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。
单机部署(安装流程)
Windows安装
下载安装包
MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址: https://www.mongodb.com/download-center#community
下载zip压缩包,然后解压到一个文件夹中,在解压目录中自己手动简历一个文件夹用来放数据:例如:data/db
启动方式:
- 在 bin 目录中打开命令行提示符,输入如下命令:
mongod --dbpath=..\data\db
在启动信息中可以看到,mongoDB的默认端口是27017,如果我们想改变默认的启动端口,可以通过–port来指定端口。 为了方便我们每次启动,可以将安装目录的bin目录设置到环境变量的path中, bin 目录下是一些常用命令,比如 mongod 启动服务用的, mongo 客户端连接服务用的。
- 配置文件方式启动服务
在解压目录中新建 config 文件夹,该文件夹中新建配置文件 mongod.conf ,内如参考如下:
storage:
#指定数据文件位置,也就是上面创建的文件夹
dbPath: D:\学习资源\mongodb\mongodb-win32-x86_64-windows-4.4.6\data\db
详细配置项内容可以参考官方文档:https://docs.mongodb.com/manual/reference/configuration-options/
[ PS ]:配置文件中如果使用双引号,比如路径地址,自动会将双引号的内容转义。如果不转义,则会报错:
启动方式:mongod -f ../config/mongod.conf
或 mongod --config ../config/mongod.conf
其他配置参考:
systemLog:
destination: file
#生成的日志文件放在那个位置
path: "D:/mongodb-win32-x86_64-2008plus-ssl-4.0.1/log/mongod.log"
#产生的日志以追加的方式添加
logAppend: true
storage:
journal:
enabled: true
#数据文件
dbPath: "D:/mongodb-win32-x86_64-2008plus-ssl-4.0.1/data"
net:
#bindIp: 127.0.0.1
port: 27017
setParameter:
#
enableLocalhostAuthBypass: false
Shell连接(mongo命令)
在命令提示符输入以下shell命令即可完成登陆 mongo
或 mongo --host=127.0.0.1 --port=27017
查看已经有的数据库 : >show databases(其实这个数据库和MySQL有点像,只不过MySQL存储数据是拆散,这个是一个文档也就是完整的存储,然后二者的语法使用不同罢了)
退出:exit
Compass-图形化界面客户端
到MongoDB官网下载MongoDB Compass 地址:https://www.mongodb.com/try/download/compass
如果是下载安装版,则按照步骤安装;如果是下载加压缩版,直接解压,执行里面的 MongoDBCompassCommunity.exe
文件即可。 在打开的界面中,输入主机地址、端口等相关信息,点击连接:然后输入对应的IP和端口即可。
Linux系统安装
其实和Windows差不多也是这几个操作,步骤如下:(有点坑最好使用docker部署)
-
下载对应的安装包:mongod-linux-x86_64-4.0.10.tgz 。
-
上传压缩包到Linux中,解压到当前目录:
tar -xvf mongodb-linux-x86_64-4.0.10.tgz
-
移动解压后的文件夹到指定的目录中:
mv mongodb-linux-x86_64-4.0.10 /usr/local/mongodb
-
新建几个目录,分别用来存储数据和日志:
#数据存储目录 mkdir -p /mongodb/single/data/db #日志存储目录 mkdir -p /mongodb/single/log
-
新建并修改配置文件:
vi /mongodb/single/mongod.conf
配置文件的内容如下:
systemLog: #MongoDB发送所有日志输出的目标指定为文件 destination: file #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径 path: "/mongodb/single/log/mongod.log" #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。 logAppend: true storage: #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。 dbPath: "/mongodb/single/data/db" journal: #启用或禁用持久性日志以确保数据文件保持有效和可恢复。 enabled: true processManagement: #启用在后台运行mongos或mongod进程的守护进程模式。 fork: true net: #服务实例绑定的IP,默认是localhost bindIp: localhost,192.168.0.2 #绑定的端口,默认是27017 port: 27017
注意格式是yaml格式!!!
-
启动MongoDB服务:
/usr/local/mongodb/bin/mongod -f /mongodb/single/mongod.conf
如果出错了,自行百度吧,不多不说21世纪了,用docker还是最舒服的。
docker安装方式
首先拉去镜像:docker pull mongo
然后启动容器运行这个镜像:docker run --name mongodb -p 27017:27017 -d mongo:latest
上面两种安装方式,如果有数据损坏,则需要进行如下操作(了解):
- 删除lock文件:
rm -f /mongodb/single/data/db/*.lock
- 修复数据:
./mongod --repair --dbpath=/mongodb/single/data/db
常用命令大全
基本案例
存放文章评论的数据存放到MongoDB中,数据结构参考如下:
数据库:articledb
数据库相关操作
-
选择和创建数据库:
use DBName
,如果这个数据库不存在会自动的创建。所以创建也是这个命令。 -
查看有权限查看的数据库:
show dbs
或者show databases
-
查看当前使用的数据库:
db
MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。
-
删除数据库:
db.dropDatabase()
,主要用来删除已经持久化的数据库
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin:保存的就是用户的基本信息以及对应的一个权限
- local: 用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
集合相关操作
集合,类似关系型数据库中的表。 可以显示的创建,也可以隐式的创建
-
集合的创建
db.createCollection(name)
,这个name就是创建的集合名字。例如:创建一个sheep,db.createCollection(“sheep”).
-
查看当前数据库的集合:
show collections
或者show tables
(好家伙,直接和MySQL一样) -
集合的删除:
db.collection.drop()
【删除所有集合】 或者db.集合名字.drop()
【删除指定集合】如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
例如删除上面创建的这个集合:
db.mycollection.drop()
当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
文档操作(CRUD)
文档(document)的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式
文档插入
- 单个插入,使用insert() 或 save() 方法向集合中插入文档,语法如下:
db.collection.insert(
{
json数据格式即可
}
)
# 例如:
db.comment.insert(
{
"articleid":"100000",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
}
)
# 说明:
1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用 new Date()
4)插入的数据没有指定 _id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。
如果执行之后返回:WriteResult({ "nInserted" : 1 })
代表插入成功。
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)。
- 批量插入,没什么好说的,就是多个json数据而已
db.comment.insert(
{
"_id":"1",
"articleid":"100000",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
},
{
"_id":"2",
"articleid":"100001",
"content":"今天天气真好,阳光明媚",
"userid":"1002",
"nickname":"Lisi",
"createdatetime":new Date(),
"likenum":NumberInt(32),
"state":null
}
)
插入时指定了 _id ,则主键就是该值。 如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。 因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。如(了解):
try {
db.comment.insertMany(
[{
"_id":"1",
"articleid":"100000",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
},
{
"_id":"2",
"articleid":"100001",
"content":"今天天气真好,阳光明媚",
"userid":"1002",
"nickname":"Lisi",
"createdatetime":new Date()