mongodb数据库使用分享
Posted 香菜+
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb数据库使用分享相关的知识,希望对你有一定的参考价值。
基本概念
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库
NoSQL
非关系型数据库的一系列统称,常见的比如redis,mongodb,neo4j;mongodb 以文档的形式存储数据,数据表现形式和JSON类似,MongoDB里面叫BSON,BSON会支持一些JSON不支持的数据格式,如Date,BinData
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | lookup | 表连接 |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
应用场景
如果项目的数据模式是固定的,而且不需要频繁变更,推荐使用 mysql,因此项目维护容易,而且确保了数据的完整性和可靠性。
另一方面,如果项目中的数据持续增加,而且数据模式不固定,MongoDB 是最合适的选择。由于它属于非关系数据库,数据可以自由使用,不需要定义统一的数据结构,所以对数据进行更新和查询也很方便。MongoDB 通常用于需要对内容进行管理、处理物联网相关业务、进行实时分析等功能的项目中。
技术解析
系统架构
主从模式(Master-Slave)
热备,读写分离,oplog同步数据;数据一致性问题;主节点宕机需要手动把slave节点指定为master节点,无法自愈(不推荐)
副本集模式(Replica Set)
和redis的哨兵模式类似
"脑裂"问题
分片模式(sharding)
可以简单地理解为是副本集模式的集群模式,并且加了一层代理层和配置层
代理层:访问数据时路由到具体的副本集
配置层:帮忙做负载均衡的
事务
4.0开始支持事务(副本集模式)
4.2及以上支持(分片模式的事务)
建议做合理的数据表格设计,尽量做单文档操作
数据存储引擎
WiredTiger:数据存放在磁盘上
In-Memory:数据存放在内存中(mongo进程杀掉之后就没数据量,需要通过oplog日志来恢复)
一般来讲主节点一定要WiredTiger,从节点可以用In-Memory提高效率
索引
b树(索引+数据)
非关系型数据库mongodb 设计表格时区别于关系型数据库的设计;关系型数据设计需要遵循3范式,多表查询遍历多,需要读取更多的索引;非关系型数据库 比较适合单一查询,不涉及遍历操作
基本语法
常用指令
xshell 登录172.26.1.247
cd /home sh enter_container.sh mongo mongosh
enter_container.sh
#!/bin/bash echo "container name: $1" containerId=$(docker ps |grep "$1" | awk 'print $1') echo "get containerId: $containerId" docker exec -it "$containerId" /bin/sh
#查看已有数据库 show dbs #创建使用数据库 use ccp_monitor #mongo中不需要事先建立表格,插入数据时自动生成 db.userinfo.insert("name":"lsj","age":18) #但需要自己创建索引,注意要设置background=true 不然会锁表 #创建普通索引 db.userinfo.createIndex("name":1,background:true) #创建唯一索引 db.userinfo.createIndex("userId":1,background:true,unique:true) #创建联合索引 db.userinfo.createIndex("name":1,"sex":1,background:true)
增删改查
添加记录
#添加记录 db.tablename.insert(json数据) #example db.userinfo.insert("name":"lsj","age":18)
修改记录
#修改记录 db.tablename.update(条件,操作) #example db.userinfo.update("name":"cd","sex":1,$set:"age":99) #插入或更新 db.userinfo.update("name":"cjf","sex":1,$set:"age":99,"upsert":true)
查询记录
#查询记录 db.tablename.find(条件,返回字段(可选)) #example #查询user表的所有数据 db.userinfo.find(); #多个检索条件封装成json db.userinfo.find("name":'cd',"sex":1) db.userinfo.find("name":'cd',"sex":1,"name":1)
删除记录
#删除记录 db.tablename.remove(条件(可选)) #example db.userinfo.remove("name":'lsj')
内嵌函数
db.userinfo.find("$where":function()return this.age>40;) db.userinfo.find("$where":function()return this.age>40&&this.sex==1;)
查询内嵌文档中满足条件的记录
#查询child年龄小于等于5的记录(全部) db.userinfo.find("child.age":$lte:5) [ _id: ObjectId("632bd90a29dd2c5a24dbf033"), name: 'cjf', sex: 1, age: 99, child: [ name: 'a', age: 10 , name: 'b', age: 5 ] ] #查询child年龄小于等于5的记录(符合条件的child) db.userinfo.find("child.age":$lte:5,"child.$":1) [ _id: ObjectId("632bd90a29dd2c5a24dbf033"), child: [ name: 'b', age: 5 ] ]
原子指令操作
应用场景,需要修改某个实体下的某个属性;这个属性可能是一个基本数据类型,也可能是内嵌文档
为了解决这类并发问题,mongo提供了一系列操作符来简化操作
$inc:inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作 $set:用来指定一个键并更新键值,若键不存在并创建;对于内嵌文档在使用$set更新时,使用"."连接的方式 $unset:删除键 $push:数组修改器,向文档的某个数组类型的键添加一个数组元素,不过滤重复的数据 添加时键存在,要求键值类型必须是数组;键不存在,则创建数组类型的键 $pull:从数组field内删除一个等于value值 $addToSet:增加一个值到数组内,而且只有当这个值不在数组内才增加 $pop:删除数组尾部元素(参数1) 删除数组头部元素(参数-1)
表连接查询(基本不用)
db.gameapp.aggregate([ $match: name: 'qysg10001' , $lookup: from: 'hosts', localField: 'host_id', foreignField: '_id', as: 'host_info' , $unwind: path: '$host_info', preserveNullAndEmptyArrays: true, , $project: _id: 0, 'host_info.host': 1, 'host_info.private_ip': 1, 'host_info.status': 1, ])
图形化界面工具
robo 3t
MongoDB Compass(官方提供的,建议使用)
两个软件都支持页面编辑和指令编辑,都有代码提示
主要演示一下robo 3t的使用,具体看演示
配置连接信息
查看数据
会自动生成一个查询模板
添加/编辑/删除数据
右键
语言集成
java
springboot集成了mongodb驱动,客户端,只需要在pom文件中导入jar包,配置连接信息,利用spring的自动装配原理,管理连接
python
pymongo
from pymongo import MongoClient if __name__ == '__main__': client = MongoClient(host='172.26.1.247', port=27017) userinfo = client['ccp_monitor']['userinfo'] result = userinfo.find_one("name": 'lsj') print(result)
更多使用方法:API Documentation — PyMongo 4.2.0 documentation
经验分享
1.建索引
本身mongo就是基于b树做索引的,检索的时候索引和数据都会读到,没有索引会导致全表扫描,响应慢
2.创建索引,注意要设置background=true 不然会锁表(生产环境很危险!)
3.原子操作尽量使用数据库自带的
4.尽量使用单表操作,避免外联查询
5.避免使用数据库的唯一id做检索条件
知识拓展
GeoJson
如果不想用postgis,mongodb的GeoJson是最佳选择
以上是关于mongodb数据库使用分享的主要内容,如果未能解决你的问题,请参考以下文章