MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
关系模型和文档模型的区别在哪里?
关系模型需要你把一个数据对象,拆分成零部件,然后存到各个相应的表里,需要的是最后把它拼起来。举例子来说,假设我们要做一个CRM应用,那么要管理客户的基本信息,包括客户名字、地址、电话等。由于每个客户可能有多个电话,那么按照第三范式,我们会把电话号码用单独的一个表来存储,并在显示客户信息的时候通过关联把需要的信息取回来。
而MongoDB的文档模式,与这个模式大不相同。由于我们的存储单位是一个文档,可以支持数组和嵌套文档,所以很多时候你直接用一个这样的文档就可以涵盖这个客户相关的所有个人信息。关系型数据库的关联功能不一定就是它的优势,而是它能够工作的必要条件。 而在MongoDB里面,利用富文档的性质,很多时候,关联是个伪需求,可以通过合理建模来避免做关联。
虽然MongoDB的模型和关系型截然不同,但是关系型数据库的一些必不可少的功能如动态查询、二级索引、聚合等在MongoDB中也有非常完善的支持。
那么我们如何考虑MongoDB 文档模式设计的基本策略呢?
其实很简单,我们一般建议的是先考虑内嵌, 直接按照你的对象模型来设计你的数据模型。如果你的对象模型数量不多,关系不是很复杂,那么恭喜你,可能直接一种对象对应一个集合就可以了。
内嵌是文档模型的特色,可以充分利用MongoDB的富文档功能来享受我们刚才谈到的一些文档模型的性能和扩展性等特性。一般的一对一、一对多关系,比如说一个人多个地址多个电话等等都可以放在一个文档里用内嵌来完成。
但是有一些时候,使用引用则难以避免。比如说, 一个明星的博客可能有几十万或者几百万的回复,这个时候如果把comments放到一个数组里,可能会超出16M的限制。这个时候你可以考虑使用引用的方式,在主表里存储一个id值,指向另一个表中的 id 值。使用引用要注意的就是:从性能上讲,一般我们可能需要两次以上才能把需要的数据取回来。更加重要的是:需要把数据存放到两个集合里,但是目前为止MongoDB并不支持跨表的事务性,所以对于强事务的应用场景要谨慎使用。
MongoDB的模式设计和关系型大不相同,我们说MongoDB是为应用程序设计的,而不是为了存储优化的。如果可以达到最高性能的话,我们甚至可以做一些反范式的东西。
修改:ulimit -n
http://www.linuxidc.com/Linux/2013-07/87927.htm
sudo vi /etc/security/limits.conf
* soft noproc 60000
* hard noproc 64000
* soft nofile 60000
* hard nofile 64000
修改:ulimit -u
http://www.linuxidc.com/Linux/2013-10/91866.htm
sudo vi /etc/security/limits.d/20-nproc.conf
* soft nproc 60000
* hard nproc 64000
MongoDB提供了linux平台上32位和64位的安装包,下载地址:Try MongoDB Atlas Products | MongoDB
下载完安装包,并解压 tgz(以下演示的是 64 位 Linux上的安装) 。
#wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.2.9.tgz
#tar -zxvf mongodb-linux-x86_64-3.0.6.tgz 解压
#mv mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb # 将解压包拷贝到指定目录
MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:
export PATH=<mongodb-install-directory>/bin:$PATH
MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。
以下实例中我们将data目录创建于根目录下(/)。
注意:/data/db 是 MongoDB 默认的启动的数据库路径(--dbpath)。
mkdir -p /data/db
你可以再命令行中执行mongo安装目录中的bin目录执行mongod命令来启动mongdb服务。
注意:如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定。
$ ./mongod
2015-09-25T16:39:50.549+0800 I JOURNAL [initandlisten] journal dir=/data/db/journal
2015-09-25T16:39:50.550+0800 I JOURNAL [initandlisten] recover : no journal files present, no recovery needed
2015-09-25T16:39:50.869+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.16
2015-09-25T16:39:51.206+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.52
2015-09-25T16:39:52.775+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 7.7
如果你需要进入MongoDB后台管理,你需要先打开mongodb装目录的下的bin目录,然后执行mongo命令文件。
MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
当你进入mongoDB后台后,它默认会链接到 test 文档(数据库):
$ cd /usr/local/mongodb/bin
$ ./mongo
MongoDB shell version: 3.0.6
connecting to: test
Welcome to the MongoDB shell.
……
由于它是一个JavaScript shell,您可以运行一些简单的算术运算:
> 2+2
4
> 3+6
9
现在让我们插入一些简单的数据,并对插入的数据进行检索:
> db.runoob.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.runoob.find()
{ "_id" : ObjectId("5604ff74a274a611b0c990aa"), "x" : 10 }
>
第一个命令将数字 10 插入到 runoob 集合的 x 字段中。
MongoDB 提供了简单的 HTTP 用户界面。 如果你想启用该功能,需要在启动的时候指定参数 --rest 。
$ ./mongod --dbpath=/data/db --rest
MongoDB 的 Web 界面访问端口比服务的端口多1000。
如果你的MongoDB运行端口使用默认的27017,你可以在端口号为28017访问web用户界面,即地址为:http://localhost:28017。
MongoDb 的启动建议以配制文件的方式启动,指定参数 ./mongod –f 文件路径
$ /usr/local/mongodb/bin/mongod –f /usr/local/mongodb/conf/mongodb.conf
mongodb.conf 文件配制:
#端口
port=27017
#指定数据库文件存放路径
dbpath=/usr/local/mongodb/db
#指定日志文件存放路径
logpath=/usr/local/mongodb/log/mongodb.log
#日志以追加方式
logappend=true
#存入进程文件的路径
pidfilepath=/usr/local/mongodb/conf/27017.pid
#以后台方式运行
fork=true
#复制集文件的最大值,默认为所在分区的5%
oplogSize=10240
#指定复制集名称
replSet=yeexun
#是否开启验证
auth=true
#本机登陆不需要密码 复制集的通信密码keyFile
setParameter=enableLocalhostAuthBypass=1
keyFile=/usr/local/mongodb/.keyFile
1、内容 base64[a-z A-Z +/]
2、长度小于 1000 bytes
3、权限 chmod 600 keyFile
4、配制文件指定keyFile文件所在位置:keyFile=/usr/local/mongodb/.keyFile
复制集至少为三台机制,可两台为复制节点一台选举节点,也可三台都为复制节点。Mongodb遵循大多数原则(存活节点大于1/2),主节点宕机自动切换从节点为主节点。
1.复制集配制:
config={ _id:"panshi", members:[{_id:0,host:"172.16.200.41:27017"},{_id:1,host:"172.16.100.40:27017"},{_id:2,host:"172.16.100.41:27017","arbiterOnly":true} ] }
2.配制生效:
rs.initiate(config)
rs.reconfig(config, {force : true})
3.修改配制:
var cfg=rs.conf()
cfg.members[2].priority = 0
rs.reconfig(cfg)
4.删除节点:
rs.remove("172.16.200.20:27017")
5.主节点降为从节点:
rs.stepDown(15)
6.停止服务:
db.shutdownServer()
7.查看服务状态:
rs.status()
{
"set" : "yeexun",
"date" : ISODate("2016-10-13T02:10:20.099Z"),
"myState" : 7,
"term" : NumberLong(58),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "172.16.200.41:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1446109,
"optime" : {
"ts" : Timestamp(1476324609, 18),
"t" : NumberLong(58)
},
"optimeDate" : ISODate("2016-10-13T02:10:09Z"),
"lastHeartbeat" : ISODate("2016-10-13T02:10:16.466Z"),
"lastHeartbeatRecv" : ISODate("2016-10-13T02:10:18.733Z"),
"pingMs" : NumberLong(1),
"syncingTo" : "172.16.100.40:27017",
"configVersion" : 102282
},
{
"_id" : 1,
"name" : "172.16.100.40:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1446109,
"optime" : {
"ts" : Timestamp(1476324609, 18),
"t" : NumberLong(58)
},
"optimeDate" : ISODate("2016-10-13T02:10:09Z"),
"lastHeartbeat" : ISODate("2016-10-13T02:10:16.465Z"),
"lastHeartbeatRecv" : ISODate("2016-10-13T02:10:18.570Z"),
"pingMs" : NumberLong(0),
"electionTime" : Timestamp(1474263039, 1),
"electionDate" : ISODate("2016-09-19T05:30:39Z"),
"configVersion" : 102282
},
{
"_id" : 2,
"name" : "172.16.100.41:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1446111,
"infoMessage" : "could not find member to sync from",
"configVersion" : 102282,
"self" : true
}
],
"ok" : 1
}
db.createUser({
user:'admin',
pwd:'yx_2016',
roles:[{role:'root',db:'admin'}]
})
db.createUser({
user:'payment',
pwd:'payment_2016',
roles:[{role:'readWrite',db:'payment'}]
})
Roles:拥有的角色 db:所属的数据库用户
1.修改密码:
db.changeUserPassword('admin','ps_mobi2016');
2.删除用户:
db.dropUser("admin")
db.dropAllUsers()
3.验证身份:
use admin
db.auth('uname','pwd')
Mongodb jar包,下载地址:http://mongodb.github.io/mongo-java-driver/,或maven
连接数据库的Java代码如下:
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// 连接到 mongodb复制集
MongoClientURI connectionString = new MongoClientURI("mongodb://root:****@ 10.12.0.60:27017,10.12.0.61:27017/admin?replicaSet=panshi"); // ****替换为root密码
MongoClient client = new MongoClient(connectionString);
MongoDatabase database = client.getDatabase("mydb");
MongoCollection collection = database.getCollection("mycoll");
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
{
upsert:
multi:
writeConcern:
}
)
db.collection.remove(
)
db.COLLECTION_NAME.find()