MongoDB的入门与使用
什么是MongoDB?
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组:
主要特点
- 1.MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。安装简单。
- 可以在MongoDB记录中设置任何属性的索引 (如:FirstName=“Sameer”,Address=“8 Gandhi Road”)来实现更快的排序。
- 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
- 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
- Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
- 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
- Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。主要是用来对数据进行批量处理和聚合操作。
- GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
- 允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
- 支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
适用场景:网站数据;缓存;大尺寸,低价值的数据;高伸缩性的场景;用于对象及JSON 数据的存储。
不适用场景:高度事务性的系统;传统的商业智能应用;需要SQL 的问题。
概念解析
在mongodb中基本的概念是文档、集合、数据库,下表将帮助您更容易理解Mongo中的一些概念:
数据库
数据库名可以是满足以下条件的任意UTF-8字符串:
- 不能是空字符串。
- 不得含有空格、.、$、/、\和空字符。
- 应全部小写。
- 最多64字节。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
admin:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
集合
注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
集合命名规范:
集合名不能是空字符串""。
集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
集合名不能以"system."开头,这是为系统集合保留的前缀。
用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$
集合中索引不能超过64个;索引名的长度不能超过125个字符;一个复合索引最多可以有31个字段
文档(Document)
文档中的键/值对是有序的。
文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
MongoDB区分类型和大小写。
MongoDB的文档不能有重复的键。
文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
BSON文档尺寸:一个document文档最大尺寸为16M;大于16M的文档需要存储在GridFS中。
文档内嵌深度:BSON文档的结构(tree)深度最大为100。
文档键命名规范:
键不能含有空字符。这个字符用来表示键的结尾。
.和$有特别的意义,只有在特定环境下才能使用。
以下划线"_"开头的键是保留的(不是严格要求的)。
MongoDB 数据类型
常用命令
常用命令 | 释义 |
---|---|
db.help(); | 查看命令提示 |
db.getPrevError(); | 查询之前的错误信息 |
db.dropDatabase() | 删除当前使用数据库 |
db.createCollection(name, options) | 创建集合 |
db.collName.count(); | 查询当前集合的数据条数 |
db.collName.drop(); | 删除集合 |
db.collName.distinct(“field”); | 查询去掉后的当前集合中的某列的重复数据 |
db.collName.find({field1: /mongo/},{field2:1,_id: 0}); | 字符模糊查询,//相当于%%,只显示指定字段field2 |
db.collName.find().sort({field: 1}); | 排序查询,升序1,降序-1 |
db.collName.find().skip(1).limit(1); | 查询第2条数据 |
db.collName.ensureIndex({field1:1,field2:1}); | 创建索引 |
db.collName.dropIndex(“name_1″); | 删除指定索引 |
db.collName.save({name: ‘zhangsan’, age: 25, sex: true}); | 添加的文档 |
db.collName.update({age: 25}, {$set: {name: ‘changeName’}}); | 修改文档 |
db.collName.remove({age: 25}); | 删除文档 |
MongoDB副本
MongoDB的副本集与我们常见的主从有所不同,主从在主机宕机后所有服务将停止,而副本集在主机宕机后,副本会接管主节点成为主节点,不会出现宕机的情况。
分片-待补充
索引-待补充
MongoDB 关系
MongoDB 的关系表示多个文档之间在逻辑上的相互联系。文档间可以通过嵌入和引用来建立联系。MongoDB 中的关系可以是:1对1,1对多,多对1,多对多。
1. 嵌入式关系
{
"_id":ObjectId("52ffc33cd85242f436021234"),
"name": "Tom Cat",
"address": [
{
"building": "大梅沙高级别墅区D1",
"city": "深圳市"
},
{
"building": "天健创业大厦",
"city": "深圳市"
}
]
}
2. 引用式关系
{
"_id":ObjectId("52ffc33cd85242f436021234"),
"name": "Tom Cat",
"address": [
ObjectId("52ffc4a5d85242602e666666"),
ObjectId("52ffc4a5d85242602e888888")
}
MongoDB引用
- Manual References(手动引用)
{
"_id":ObjectId("52ffc33cd85242f436021234"),
"name": "Tom",
"address": [
ObjectId("52ffc4a5d85242602e666666"),
ObjectId("52ffc4a5d85242602e888888")
}
- DBRefs
{ $ref : “集合名称”, $id : “引用的_id”, $db : “数据库名称,可选” }
{
"_id":ObjectId("52ffc33cd85242f436021234"),
"name": "Tom,
"address": [
DBRef("testAddress", ObjectId("59379e0c2e7a03e326cc7553")),
DBRef("testAddress",ObjectId("59379e0c2e7a03e326cc7558"))
}
db.testUser.find({name:"Tom"}).address[0].fetch();
安全性
- 默认配置安全问题。MongoDB默认通过最简单部署方式,最大限度提高运行速度,以在虚拟机(低配机)上运行而定制的,并未充分考虑MongoDB的安全性。MongoDB官方文档,如针对身份验证,传输加密,网络配置的文档、指南并不规范,容易误导MongoDB管理员。一些MongoDB环境是为了单一项目或者是测试环境搭建,搭建者并不关心MongoDB的安全问题。
- 自身安全问题。根据CVE列表,MongoDB从2009年面世至今共发现13个漏洞,主要存在敏感数据泄露、越权操作和登录调用的函数存在缓冲区溢出漏洞,会导致服务宕机问题。
- Web安全问题。鉴于MongoDB的部署环境和使用领域,导致从Web向MongoDB发动的攻击才是MongoDB面临的最大威胁。这种攻击主要分成两类:Rest和CSRF联合攻击,注入攻击。