2019年2月

本文采用知识共享 署名-相同方式共享 4.0 国际 许可协议进行许可。
访问 https://creativecommons.org/licenses/by-sa/4.0/ 查看该许可协议。

MongoDB

MongoDB体系结构

  • 传统SQL数据库:实例(N):数据库(1),这种情况在Oracle中称为RAC
  • MongoDB:实例(1):数据库(N)

逻辑存储结构

  • database
  • collection
  • document

    物理存储结构

  • 存储位置:默认存储在/data/db文件夹中
  • 存储文件(3.2版本后默认存储引擎改为wiredTiger,不再采用mmapv1(4.2版本被移除)内存映射,所以看不到命名空间和数据文件了)
  • 命名空间文件:后缀为.ns,默认大小16M
  • 数据文件:后缀为0,1,2,3,4..., 默认大小为0-64M, 1-128M, 2-256M...7-2048M, 8-2048M, 9-2048M
  • 开始文件Size:早期mmapv1为16M, 目前wiredTiger为64M
  • 最大文件Size:默认为2G
  • 日志文件
  • 直接存储在操作系统
  • 系统(进程)日志:默认存储在/var/log/mongodb
  • journal日志:redo重做日志, 用于恢复
  • 存储在Collection中
  • oplog:复制操作日志(主从复制log)
  • 慢查询(需要单独配置):一般用在生产系统中,查询大于200ms的log

Mongo shell

启动: mongo/mongo --username/-u --password/-p --host/-h --port/-p
指定编辑器: export EDITOR=vim

启动配置文件

// 优化显示
host=db.serverStatus().host;
cmdCount=1;
prompt=function() {
        return db + "@" + host + " " + (cmdCount++) + ">"
}

基本操作

  • show dbs - 查看所有数据库
  • use dbname - 选定一个数据库,如数据库不存在,当插入数据时自动创建
  • db - 当前Database
  • db.con1.insertOne({name: "wars"}) - 插入一条数据,如Collection不存在自动创建
  • show collections - 查看当前Database所有Collection

    数据类型

    https://docs.mongodb.com/manual/reference/bson-types/

  • Double(数字默认类型), 当查询某个数字字段时间, 筛选{"val": 9.9},只会查询Double类型的数据;筛选{"val": 10}, 会查询所有数字类型的数据
  • String
  • Object
  • Array
  • Binary data
  • Undefined
  • ObjectId(12byte type: BSON)
  • 当插入数据时,自动生成一个_id字段(主键)
  • Boolean
  • Date
  • Date() 表示当前时间,返回一个字符串
  • new Date()/ISODate() 返回一个ISODate类型, 格林威治标准时间
  • Null
  • Regular Expression
  • DBPointer
  • JavaScript
  • Symbol
  • JavaScript (with scope)
  • 32-bit integer
  • Timestamp
  • 64-bit integer
  • Decimal128
  • Min key
  • Max key

CRUD

插入

Insert数据可以嵌套
insertOne - 插入一条数据
insertMany - 接收数组,插入多条Document
insert - 单条多条皆可插入

查询

find() - 查询所有
find({"docname": "value"}) - 条件查询
find({$or: [{"deptno": 10], {"deptno": 20}})
find({"deptno": {$in: [10, 20]}}) - or或in查询10号或20号部门的员工
find({"sal": {$gt: 2000}, "deptno": 20}) - gt查询大于2000工资的20号部门员工
find({"a.b": {$lt: 10}}) - 查询a中b小于10的数据
find({"a": {"b": {$lt: 10}}}) - 匹配a中,只包含b且b小于10的数据
find({a: {$all: [10,20]}}) - 查询数组嵌套,使用$all
find({a: [10, 20, 30]}) - 匹配数组嵌套
find({a: {$elemMatch: {"b":"", "c": ""}}}) - 单字段,多条件匹配
find({a: {$type:10}}) - $type:10表示空,查询ae为null的数据
find(a: {$exits: true/false}) - 查询字段是否缺失

游标

定义
var cursor = db.emp.find()
循环访问Document
while(cursor.hasNext()) {
printjson(cursor.next())
}

游标转换Array
var arr = cursor.toArray()
arr[0]

分页查询
db.emp.find().limit(5)
db.emp.find().limit(5).skip(5)
db.emp.find().limit(5).skip(10)

更新

updateOne({"_id": 1}, {$set: {sal: 8000}})
updateMany({deptno: 10}, {$inc: {sal: 100}}) - 10号部门张100元
replaceOne()

删除

deleteOne({_id: 1})
deleteMany({deptno: 10})

批处理

支持insert update remove insertMany
bulkWrite([
{insertOne: {"document": {"_id": 001, "name": "wars", "age": 19}}},
{insertOne: {"document": {"_id": 002, "name": "cat", "age": 1}}},
{updateOne: {"filter": {"_id": 001}, "update": {"age": 20}}}
])

索引工作原理

当给emp表的depno字段建立一个索引

CREATE INDEX index1 ON EMP(deptno);

oracle会自动新建一张索引表,索引表

Title - Artist
0:00