重要概念:
* 大数据量、可扩展、高性能、低事务
* 数据库、集合、文档
* 无需预定义的schema
根据官方文档,当数据量达到50GB以上数据时,Mongo数据库访问速度是MySQL10 倍以上。
启动数据库:mongod
启动数据库shell: mongo, 返回连接到test数据库的db. javascript shell(有扩展)
中止MongoDB实例:如果是前台进程,使用Ctrl-C。如果是后台进程,则使用kill -2 pid (SIGINT) 或 kill pid (SIGTERM)
连接远程数据库(linux):
sudo ./mongo 115.29.44.126:27017/abc
db.auth(‘abc_mongo_user', ‘123456')
show collections
MongoDB自带一个微型的web管理信息界面,需要修改/etc/mongod.conf中的一个配置项:
# Enable the HTTP interface (Defaults to port 28017). httpinterface=true
关闭Mongod服务,手动用命令启动:
./mongod -f /etc/mongod.conf --rest
需要开启启动,将上述的命令添加到/etc/rc.local中;
通过terminal使用ssh连接远端服务器启动mongodb后关闭终端,会导致mongodb停止。解决方法:
* ctrl - Z将该任务放到后端
* jobs查看后端mongod的程序序号
* bg %程序序号,在后端继续执行mongod
use microblog:使用其它数据库,db指向新数据库
CRUD:
* db.posts.insert(post)
* db.posts.find(), db.posts.findone(), db.posts.find({title:"xxx"});
* db.posts.update({title:"xxx"}, post);
* dp.posts.remove{title:"xxx"});
help:帮助
show collections:show数据库下的集合
调用函数时不带括号可看到JavaScript源码
指定返回的键
db.users.find({}, {"username":1, "email": 1})
指定不返回的键
db.users.find({}, {"fatal_weakness": 0})
查询条件
“$lt”、“$lte”、"$gt"、“$gte”、"$ne"
db.users.find({"age": {"$gte": 18, "$lte":30}})
OR
db.raffle.find({"ticket_no":{"$in":[725, 542, 390]}})
"$in"、"$nin"、"$or"
db.raffle.find({"$or": [{"ticket_no": 725}, {"winner": true}]})
"$mod"
db.users.find({"id_num":{"$mod":[5,1]}})
"$not"
db.users.find({"$not":{"id_num":{"$mod":[5,1]}}})
null
null不仅仅匹配自身,而且匹配“不存在的”
db.c.find({"z": {"$in": [null], "$exists": true)
索引
db.ensureIndex({"username":1, "date":-1})
1 - 升序
-1 - 降序
索引存储在B树中
索引存储在system.indexes集合
db.system.indexes.find({"ns": "test.c", "name": "age_1"})
唯一索引
db.people.ensureIndex({"username":1}, {"unique": true})
db.people.ensureIndex({"username":1}, {"unique": true, "dropDups": true}):删除重复键的文档
getLastError(): 获得操作的状态
db.foo.find().explain()
对游标调用,可得到查询细节:使用的索引情况,耗时及扫描文档数的统计信息。
复制
* 主从服务器
* mongod --dbpath C:\data\db --port 10000 --master //主服务器
* mongod --dbpath C:\data\slave --port 10001 --slave --source localhost:10000
* 副本集(Replica Set):有自动故障恢复功能的主从集群。没有固定的“主节点”。总会有一个活跃节点和一个或多个备份节点。当当前活跃节点不工作,一个备份节点将变成活跃节点。
* 官方推荐副本集的机器数量至少为3个
* 不能用localhost作为主机名,需要找到机器主机名。cat /etc/hostname
* mongod --dbpath C:\data\node1 --port 10001 --replset blort/morton:10002
* mongod --dbpath C:\data\node2 --port 10002 --replset blort/morton:10001
* mongod --dbpath C:\data\node3 --port 10003 --replset blort/morton:10001
* 初始化
* mongo morton:10001/admin
* db.runCommand({"replSetInitiate": {
* "_id": "blort",
* "members":[
* {
* "_id":1,
* "host":"morton:10001"
* },
* {
* "_id":2,
* "host":"morton:10002"
* }
* ]}})
* 从节点可用作备份的数据源,也可用来扩展读取性能,或是进行数据处理
* 数据复制并不同步
* slaveOkay: db.getMongo().setSlaveOk();
分片(sharding):将数据拆分,将其分散在不同的机器上的过程。
* MongoDB支持自动分片
* 分片之前要运行一个路由器,该进程名为mongos。这个路由器知道所有数据的存放位置,所以应用可以连接它来正常发送请求。
* 考虑分片的信号:
* 机器的磁盘不够用了
* 单个MongoDB已不能满足写数据的性能需要。
* 想将大量数据放在内存中提高性能。
* 片键(shard key): 该键的值作为数据拆分的依据。
* 可创建符合片键
* 分片的组成
* 片:单个的mongod服务器,也可以是副本集
* mongos: 路由器进程
* 配置服务器:存储了集群的配置信息-数据和片的对应关系。
* 启动服务器
* 创建配置服务器的数据目录
* mongod --dbpath C:\data\config --port 20000
* 200MB实际数据大约占用1KB的配置空间
* mongos --port 30000 --configdb localhost:20000
* mongos不需要数据目录
* 添加片:片就是普通的mongod实例
* mongod --dbpath C:\data\shard1 --port 10000
* mongo localhost:30000/admin
* db.runCommand({addshard:"localhost:10000", allowLocal:true})
* 当在localhost运行片时,得设定“allowLocal”键
* 切分数据
* 开启数据库分片功能
* db.runCommand({"enablesharding":"foo"})
* 对集合进行分片
* db.runCommand({"shardcollection":"foo.bar", "key":{"_id": 1}})
* 生产配置
* 多个配置服务器
* 多个mongos服务器
* 每个片都是副本集
* 正确设置w
* 设置多个配置服务器
* mongod --dbpath C:\data\config1 --port 20001
* mongod --dbpath C:\data\config2 --port 20002
* mongod --dbpath C:\data\config3 --port 20003
* mongos --port 30000 --configdb localhost:20001, localhost:20002, localhost:20003
* 可以把一个配置服务器、一些mongos进程和副本集的一个节点放到一台机器上
* 建议针对一个应用服务器只运行一个mongos进程
* 用副本集作为片
* db.runCommand({"addshard": "foo/prod.example.com:27017"})
* foo - 副本集, prod.example.com:27017 - 服务器
数据库扩展
* 读取密集型:副本集
* 写入密集型:分片