MongoDB 数据库介绍
特点
面向集合存储
丰富的查询语句
复制集机制
支持文件存储
模式自由
多级索引
易水平扩展
跨平台支持语言众多
可插入式存储引擎(3.0)
适用场景
数据缓存
JSON 格式的数据
局伸如性场景
弱事务类型业务
MongoDB 更多适合于大数据量高并发弱事务的互联网应用, 其内置的水平扩展 机制提供了从几百万到十亿级别的数据处理能力, 可以很好的满足 web2.0 和移动互联网应 用的数据存储要求
MongoDB 的相关网站
官方文档: https://docs.mongodb.com/tutorials/
中文网站: http://www.mongoing.com/
谷歌 Group:https://groups.google.com/forum/
MongoDB 概念解析
SQL 术语 / 概念 | MongoDB 术语 / 概念 | 解释 / 说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表 / 集合 |
row | document | 数据记录行 / 文档 |
column | field | 数据字段 / 域 |
index | index | 索引 |
table joins | embedded documents/reference | 表连接 /(内嵌 / 引用) |
primary key | primary key | 主键, MongoDB 自动将_id 字段设置为主键 |
通过下图实例, 可以更直观的的了解 Mongo 中的一些概念:
数据库
多个文档组成集合, 而多个集合组成了数据库一个 MongoDB 实例可以 承载多个数据库, 每个数据库都有独立的权限, 在磁盘上, 不同的数据库也 可放置在不同的文件夹中(启动时加 directoryperdb 选项)
为了更好的组织数据, 一般情况下, 会把属于同一个应用程序 (或同一种 业务类型) 的所有数据放到一个数据库中
show dbs 命令可以显示所有数据的列表
- ? at [09/10/17][0:21:00]
- ? ? mongo
- MongoDB shell version: 3.2.11
- connecting to: test
- > exit
- bye
- ? at [09/10/17][0:21:04]
- ? ? mongo
- MongoDB shell version: 3.2.11
- connecting to: test
- > show dbs
- local 0.000GB
执行 "db" 命令可以显示当前数据库对象或集合
> db test
运行 use db_name 命令, 切换数据库, 没有数据库时自动创建
- > use local
- switched to db local
- > db
- local
- >
以上实例命令中, local 是你要链接的数据库
在下一个章节我们将详细讲解 MongoDB 中命令的使用
数据库也通过名字来标识数据库名可以是满足以下条件的任意 UTF-8 字符串
不能是空字符串("")
不得含有 (空格).$/\ 和 \ 0 (空字符)
数据库名字区分大小写(建议数据库名全部使用小写)
最多 64 字节
不要与系统保留的数据库名字相同, 这些数据库包括: adminlocal config 等
有一些数据库名是保留的, 可以直接访问这些有特殊作用的数据库
admin: 从权限的角度来看, 这是 "root" 数据库要是将一个用户添加到这个数据库, 这个用户自动继承所有数据库的权限一些特定的服务器端命令也只能从这个数据库运行, 比如列出所有的数据库或者关闭服务器
local: 这个数据永远不会被复制, 可以用来存储限于本地单台服务器的任意集合
config: 当 Mongo 用于分片设置时, config 数据库在内部使用, 用于保存分片的相关信息
相关操作
命令 | 操作 |
---|---|
db | 查看当前数据库 |
show dbs | 查看当前端口有多少数据库 |
use db_name | 切换数据库,没有数据库时自动创建 |
db.dropDatabase() | 删除数据库 |
文档
文档是 MongoDB 最核心的概念, 本质上是一种类 JSON 的 BSON 格式的数据
BSON 是一种类 JSON 的二进制格式数据, 它可以理解为在 JSON 基础上添加了 _些新的数据类型, 包括曰期 int32int64 等
BSON 是由一组组键值对组成, 它具有轻量性可遍 历性和高效性三个特征可遍历性是 MongoDB 将 BSON 作为数据存储的主要原因
BSON 官网地址: http://bsonspec.org/
- {
- fieldl:valuel,
- field2:value2,
- field3:value3,
- ...
- fieldN:valuen
- }
下表列出了 RDBMS 与 MongoDB 对应的术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
数据库服务 | 客户端 |
---|---|
Mysqld/Oracle | mysql/sqlplus |
mongod | mongo |
需要注意的是:
文档中的键 / 值对是有序的 MongoDB 会尽量保持文档被插入时键值对的顺序
文档中的值不仅可以是在双引号里面的字符串, 还可以是其他几种数据类型(甚至可以是整个嵌入的文档)
MongoDB 区分类型和大小写
MongoDB 的文档不能有重复的键
文档的键是字符串除了少数例外情况, 键可以使用任意 UTF-8 字符
MongoDB 中写操作的原子性限制在文档级别, 对文档的保存修改删除 等都是原子操作
单个文档占用的存储空间不能超过 16MB
关于文档键的命名需要注意以下几点:
_id 是系统保留的关键字, 它是默认的主键, 该值在集合中必须唯一, 且不可更改
.(命名空间)和 $(操作符)有特别的意义, 只有在特定环境下才能使用
以下划线 "_" 开头的键是保留的(不是严格要求的)
键不能包含 \ 0 或空字符, 这个字符用于表示键的结尾
键是区分大小写的且不能重复例如:{foo:l,Foo:l}
内嵌文档
文档可以作为键的值, 这样的文档称为内嵌文档内嵌文档可以使数据不用保存成扁平结构的键值对, 从而使数据组织方式更加自然
例如: 下面是一个与博客管理有关的文档
- {
- _id: <Objectldl>,
- title: MongoDBDateModeln,
- author: foo,
- comments:[
- {who:"John",comment:"Good"},
- {who:"Joe",comment:"ExceUent"}
- ]
- }
上面的文档可以进行如下的拆分:
即拆分成引用文档.
内嵌文档特点
子文档比较少时, 可以保证原子性, 同时具备高速查询;
子文档比较多时, 会影响查询和更新速度, 同时也带来数据冗余
集合
把一组相关的文档放到一起组成了集合, 如果将 MongoDB 的一个文档比喻 为关系型数据库中的一行, 那么一个集合就相当于一张表
MongoDB 的集合是模式自由的, 一个集合里面的文档可以是各式各样
例如: 下面的两个文档可以出现了同一个集合中
- {"x":1}
- {"x":1,"y":2}
- {"x":1,"y":2,"z":5}
当第一个文档插入时, 集合就会被创建
MongoDB 提供了一些特殊功能的集合, 例如: cappedcollection system.indexessystem.namespaces 等
合法的集合名
集合名不能是空字符串 ""
集合名不能含有 \ 0 字符(空字符), 这个字符表示集合名的结尾
集合名不能以 system. 开头, 这是为系统集合保留的前缀
用户创建的集合名字不能含有保留字符有些驱动程序的确支持在集合名里面包含, 这是因为某些系统生成的集合中包含该字符除非你要访问这种系统创建的集合, 否则千万不要在名字里出现 $(注: 可包含.)
如下实例:
- db.col.findOne()
- capped collections
Capped collections 就是固定大小的 collection
它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似
Capped collections 是高性能自动的维护对象的插入顺序它非常适合类似记录日志的功能 和标准的 collection 不同, 你必须要显式的创建一个 capped collection, 指定一个 collection 的大小, 单位是字节 collection 的数据存储空间值提前分配的
要注意的是指定的存储大小包含了数据库的头信息
db.createCollection("mycoll", {capped:true, size:100000})
在 capped collection 中, 你能添加新的对象
能进行更新, 然而, 对象不会增加存储空间如果增加, 更新就会失败
数据库不允许进行删除使用 drop()方法删除 collection 所有的行
注意: 删除之后, 你必须显式的重新创建这个 collection
在 32bit 机器中, capped collection 最大存储为 1e9( 1X109)个字节
命名空间
把数据库名添加到集合名字前面, 中间用点号连接, 得到集合的完全限定 名, 就是命名空间, 例如: 命名空间 parent.sub
需要说明的是, 点号还可以出现在集合名字中, 例如: parent.subling0,parent.subling2 可以将 subling0 和 subling2 集合看作是 parent 集合的子集合
使用子集合可以使我们更好的组织数据, 使数据的结构更加清晰明了
元数据
数据库的信息是存储在集合中它们使用了系统的命名空间:
dbname.system.*
在 MongoDB 数据库中名字空间 < dbname>.system.* 是包含多种系统信息的特殊集合(Collection), 如下:
集合命名空间 | 描述 |
---|---|
db.system.namespaces | 列出所有名字空间。 |
db.system.indexes | 列出所有索引。 |
db.system.profile | 包含数据库概要 (profile) 信息。 |
db.system.users | 列出所有可访问数据库的用户。 |
db.local.sources | 包含复制对端(slave)的服务器信息和状态。 |
对于修改系统集合中的对象有如下限制
在 {{system.indexes}} 插入数据, 可以创建索引但除此之外该表信息是不可变的(特殊的 drop index 命令将自动更新相关信息)
{{system.users}}是可修改的 {{system.profile}}是可删除的
MongoDB 数据类型
BSON 可以理解为在 JSON 基础上添加了一些新的数据类型, 包括 Date, 正贝 IJ 表达式, 对数值类型的更进一步划分等
数据类型 | 类型编号 | 数据类型 | 类型编号 |
---|---|---|---|
Double | 1 | Regular Expression | 11 |
String | 2 | JavaScript | 13 |
Object | 3 | Symbol | 14 |
Array | 4 | JavaScript(Scope) | 15 |
Binarydata | 5 | 32-bit integer | 16 |
Object id | 7 | Timestamp | 17 |
Boolean | 8 | 64-bit integer | 18 |
Date | 9 | Min Key | 255 |
Null | 10 | Max Key | 127 |
可以使用类型编号进行条件查询如下:
db.collection.find({name:{$type:2}})
基本数据类型
null 表示空值或不存在的字段例如: db.collection.find({nyn:null})
布尔有两个值 true 或 false 例如:{"y":true}
数值类型支持 32-int64-int 以及 64-double
注: JavaScript 只支持 64 位浮点数
例如:
- {"y":10} - double
- {"y":Numberlnt(10)} - 32
- {"y":NumberLong(10)} - 64
- 7 Documents:0 > db.demo.insert({y:10})
- WriteResult({ "nInserted" : 1 })
- 8 Documents:1 > db.demo.find({y:{$type:1}})
- { "_id" : ObjectId("5a7863305640374fb2cd5620"), "y" : 10 }
- 9 Documents:1 > db.demo.insert({y:NumberInt(10)})
- WriteResult({ "nInserted" : 1 })
- 10 Documents:2 > db.demo.find({y:{$type:16}})
- { "_id" : ObjectId("5a78636d5640374fb2cd5621"), "y" : 10 }
- 11 Documents:2 > db.demo.insert({y:NumberLong(10)})
- WriteResult({ "nInserted" : 1 })
- 12 Documents:3 > db.demo.find({y:{$type:18}})
- { "_id" : ObjectId("5a7863915640374fb2cd5622"), "y" : NumberLong(10) }
字符串使用 UTF-8 对字符串进行编码例如:{"y":"HelloMongoDB"}
二进制数据可以保存由任意字节组成的字符串, 例如: 图片视频等
正则表达式: 主要用于查询, 使用正则表达式作为限定条件
例如:
{name:/foo/} name 字段含有 foo 的文档
{name:/foo/i} name 字段含有 foo 的文档, 且不区分大小写
{name:/^foo/i} name 字段以 foo 幵头, 且不区分大小写
JavaScript 代码: 文档中可以包含任意的 JavaScript 代码
例如:{"func":function(){}}
Date 日期
MongoDB 中, 日期类型是一个 64 位的整数, 它代表的是距 Unixepoch 的毫秒数
MongoDB 在存储时间时, 先转化为 UTC 时间
北京时间(CST) = UTC + 8 个小时
MongoDBShell 中可以使用 newDate 或 ISODate 来创建时间对象, 在进行显示时, Shell 会根据本地时间去设置显示日期对象
- 14 Documents:3 > var mydate0 = new Date()
- 15 Documents:3 > var mydate9 = ISODate()
- 16 Documents:3 > mydate0
- ISODate("2018-02-05T14:04:43.243Z")
- 17 Documents:3 > mydate9
- ISODate("2018-02-05T14:04:57.715Z")
- 18 Documents:3 > mydate9.toString()
- Mon Feb 05 2018 22:04:57 GMT+0800 (CST)
- Timestamp
时间戳类型有两部分组成:
Timestmp 只供 MongoDB 数据库服务内部使用, 用于记录操作的详细时间
Timestamp 类型和 Date 类型是没有关系的, 对于我们来说使用更多的 Date 类型
相关函数: Timestamp()
Objectld
Objectld 由 24 个十六进制字符构成, 每个字节存储两位十六进制数字, 总共需 12 字节存储空间
每个字节代表的含义如下:
这种方式生成的 Objectld 在分布式仍然是唯一的.
相关函数:
Objectld()
用于取得 Objectld
getTimestamp()
用于取得 Objectld 的时间戳
valueOf()
用于取得 Objectld 的字符串表示
- 19 Documents:3 > x = ObjectId()
- ObjectId("5a7866e75640374fb2cd5623")
- 20 Documents:3 > x.getTimestamp()
- ISODate("2018-02-05T14:15:03Z")
- 21 Documents:3 > x.valueOf()
- 5a7866e75640374fb2cd5623
数组
数组是使用方括号来表示的一组值, 它既可以作为有序对象 (列表栈队 歹 | J), 也能作为无序对象(如集合) 来操作
数组中可以包含不同数据类型的元素(字符串浮点数文档等)
例如:[3.14,"hello",[l2,3],{"key":"MongoDB"}]
针对数组 MongoDB 提供了许多特定的操作符, 例如:$push,$pop, $pull,$slice,$addToSet 等
MongoDB 可自动的为数组元素建立 Multikey 索引
来源: http://www.bubuko.com/infodetail-2499517.html