MongoDB将几个月的成果总结成一篇文章,总结了一些大神相关MongoDB的资料和本人相关技术的应用案例,经验,希望可以帮到你能够更好的了解MogoDB,废话不多说,下面开始简要介绍mon
MongoDB
将几个月的成果总结成一篇文章,总结了一些大神相关MongoDB的资料和本人相关技术的应用案例,经验 ,希望可以帮到你能够更好的了解MogoDB,废话不多说,下面开始
简要介绍mongodb
MongoDB是一个基于分布式文件存储的数据库。 MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能。mongodb中有三元素:数据库,集合,文档,其中“集合”就是对应关系数据库中的“表”,“文档”对应“行”。
功能:
* 面向集合的存储:适合存储对象及JSON形式的数据。
* 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
* 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
* 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
* 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
* 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)
* 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。
下载安装和配置
MongoDB最新版本下载在官网的DownLoad菜单下:http://www.mongodb.org/downloads
解压mongodb-win32-x86_64-2.6.6.zip ,创建路径C:\mongodb ,将解压后的Bin文件Copy to 此文件夹下
C:\mongodb 下建立Data文件夹 C:\mongodb\data ,然后分别建立db,log两个文件夹,至此mongodb下有以下文件夹
在log文件夹下创建一个日志文件MongoDB.log,即C:\mongodb\data\log\MongoDB.log
程序启动方式:
运行cmd.exe 进入DOS命中界面
>cd C:\mongodb\bin
>C:\mongodb\bin>mongod -dbpath "C:\mongodb\data\db"
执行此命令即将mongodb的数据库文件创建到C:\mongodb\data\db 目录,会看到命令最后一行sucess的成功提示,此时数据库就已启动,该界面为Mongo的启动程序,关闭后可直接双击bin下的mongod.exe,启动程序开启后,再运行mongo.exe
将MongoDB安装为windows服务:
运行cmd.exe
> cd C:\mongodb\bin
> C:\mongodb\bin>mongod --dbpath "C:\mongodb\data\db" --logpath "C:\mongodb\data\log\MongoDB.log" --install --serviceName "MongoDB"
这里MongoDB.log就是开始建立的日志文件,--serviceName "MongoDB" 服务名为MongoDB
>NET START MongoDB (开启服务)
>NET stop MongoDB (关闭服务)
安装完毕!!!
MongoDB认证
步骤分解
1.MongoDB安装时不添加任何参数,默认是没有权限验证的,登录的用户可以对数据库任意操作而且可以远程访问数据库,需以--auth参数启动。
1.在刚安装完毕的时候MongoDB都默认有一个admin数据库,此时admin数据库是空的,没有记录权限相关的信息。当admin.system.users一个用户都没有时,即使mongod启动时添加了--auth参数,如果没有在admin数据库中添加用户,此时不进行任何认证还是可以做任何操作(不管是否是以--auth 参数 启动),直到在admin.system.users中添加了一个用户。
1.MongoDB的访问分为连接和权限验证,即使以--auth参数启动还是可以不使用用户名连接数据库,但是不会有任何的权限进行任何操作
1.admin数据库中的用户名可以管理所有数据库,其他数据库中的用户只能管理其所在的数据库。
1.在2.4之前版本中,用户的权限分为只读和拥有所有权限;2.4版本的权限管理主要分为:数据库的操作权限、数据库用户的管理权限、集群的管理权限,建议由超级用户在admin数据库中管理这些用户。不过依然兼容2.4版本之前的用户管理方法。
用户操作
认证
db.auth("user","password")
全部用户
show users // db.system.users.find()
// 超级用户 root
db.createUser({user: "root",pwd: "123456",roles: [ "root" ]})
// 修改密码
db.changeUserPassword("root", "root")
// 删除原用户
db.dropUser("test") // db.system.users.remove({user:"test"});
MongoDB索引
索引的优点
1.不需要做全表扫描,只需要扫描索引索引只存储了这个表的数据的一小部分,这小部分可以帮我们实现快速查询,因此扫描的时候只扫描这一小部分即可,如果将这小部分装载入内存中的话,速度会更快
2.大大减少了服务器需要扫描的数据量
3.索引可以帮助服务器避免排序或使用临时表
4.索引可以将随机I/O转换为顺序I/O
索引的缺点
1. 索引是保存了数据表上的一小部分数据,那么这些数据是需要额外存储的,毫无疑问如果更新了表中的数据,那么响应的索引数据也要跟着更新,加速了查找操作,但是减少了写入速度对查找的加速是否有用还是有待评估的,比如我们将一个表中的按年龄实现了索引创建(在年龄上创建了索引)平时大多数操作都是按照名字上去查找的,那么索引则无任何作用,所谓索引必须跟查找建完全匹配才有意义,但我们要知道大多数的查找未必只在有限字段上执行,也就意味着创建索引必须包含多个段,需要看索引是如何去生成的,对于多个条件可以将索引做为组合索引来查找,所以索引的设计是非常有技巧的
2. 索引本身带来的未必是优势,如果一张表中索引非常的多的话,可能对于整个系统性能的影响是非常大的,如果一张表的本身非常小只有十几行,创建索引反而会减慢速度的,因为全表扫描也未必用不了多长时间
3. 但如果表非常大的话,索引则非常有用,如果数据量过大那么索引反而也未必有意义,比如一张表非常大,上T的数据,可以想象一下创建什么样的索引才可以,所以只能将大表切割成小表,并且分布在不同的物理节点上,对mysql来说叫做分区;对mongodb来讲叫shaerd
索引类型
1. 单键索引(创建在一个字段上的索引)
2. 组合索引(上面提到了)
3. 多键索引(一个文档中某个字段的值可以是数组,如果创建在这么个字段上,一个字段上有多个值,则为多键索引,(一个值为一个数组))
4. 空间索引(只能使用空间索引函数,与mysql一致)
5. 文本索引(全文索引)
6. 哈希索引
操作
使用ensureIndex来创建索引,1为升序,-1为倒序
> db.foo.ensureIndex({“x”:1, “y”:-1})
tip:查询要返回集合中一半以上的结果,反而没有必要创建索引,直接一条条扫描数据会高效一些
创建唯一索引
> db.test.ensureIndex({“x”:1}, {“unique”:true})
创建唯一索引前可能会有重复数据,我们可以使用”dropDups”来鲁莽的删除这些重复数据,写法如下
> db.test.ensureIndex({“x”:1}, {“unique”:true, “dropDups”:true})
当然,最好还是写个脚本预处理好这些数据在建立唯一索引是更好的解决方法
我们可以在创建索引时,为索引起个名字,而不是用系统自动生成的名字
> db.test.ensureIndex({“x”:1}, {“name”: “myindex”})
当我们的集合数据量很大的时候,创建索引是一件费时费力的事情,我们可以这些写创建索引的语句,是创建索引的过程在后台完成:
> db.test.ensureIndex({“x”:1}, {“background”:true})
当索引不再使用的使用我们可以用dropIndexes来删除索引
> db.runCommand({“dropIndexes”: “test”, “index”: “myindex”})
数据库常用命令
* 切换/创建数据库
use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库
* 查询所有数据库
show dbs;
* 删除当前使用数据库
db.dropDatabase();
* 从指定主机上克隆数据库
db.cloneDatabase(“127.0.0.1”); 将指定机器上的数据库的数据克隆到当前数据库
* 从指定的机器上复制指定数据库数据到某个数据库
db.copyDatabase("mydb", "temp", "127.0.0.1");将本机的mydb的数据复制到temp数据库中
* 修复当前数据库
db.repairDatabase();
* 查看当前使用的数据库
db.getName();
* 显示当前db状态
db.stats();
* 当前db版本
db.version();
* 查看当前db的链接机器地址
db.getMongo();
* 创建一个聚集集合(table)
db.createCollection(“collName”, {size: 20, capped: 5, max: 100});
* 得到指定名称的聚集集合(table)
db.getCollection("account");
* 得到当前db的所有聚集集合
db.getCollectionNames();
* 显示当前db所有聚集索引的状态
db.printCollectionStats();
用Python操作MongoDB需要通过PyMongo,下面就介绍一下PyMongo
PyMongo是Mongodb的Python接口开发包,是使用Python和Mongodb的推荐方式。本文将对PyMongo的使用进行介绍。
安装
PyMongo包含在PythonPackage Index中
https://pypi.python.org/pypi/pymongo/。
PyMongo的安装不需要依赖其他包,但可以通过其他包来扩展应用(参见参考链接)。
其安装方式包括一下几种:
* 使用pip安装:
pip install pymongo 默认安装
pip install pymOngo==2.8 安装指定版本
pip install –upgrade pymongo 升级PyMongo
* 使用easy_install安装:
easy_install pymongo
easy_install –U pymongo
* 使用源文件进行安装
git clonegit://github.com/mongodb/mongo-python-driver.git pymongo
cd pymongo/
pythonsetup.py install
使用简介
* 使用条件
在使用前需要保证PyMongo安装成功,并且Mongodb已经启动,且下图命令运行成功无报错:
`>>> import pymongo`
* 建立与MongoClient连接
连接默认host和port
`>>> from pymongo import MongoClient>>> client = MongoClient()`
连接指定host和port
`>>> client = MongoClient('localhost', 27017)`
* 获取数据库 Database
一个Mongodb实例可以支持多个独立的databases。可以通过以下方式获得数据库:
`>>> db = client.test_database`
如果数据库名使用属性风格无法通过上述方式获取,可以使用字典风格(dictionary)获取:
`>>> db = client['test-database']`
* 获取集合(collection)
集合是一组文档,Mongodb中的文档类似于关系数据库中的行,而集合如同表。获取Mongodb集合的方式与获得database的方式相同:
`>>> collection = db.test_collection或>>> collection = db['test-collection']`
* 文档(documents)操作
1. MongoDB中的数据以JSON格式存储和表示。在PyMongo中,我们使用字典(dictionaries)来表示文档。作为示例,下面的字典为某blog的POST请求:
>>> import datetime>>> post = {"author": "Mike",
"text": "My first blog post!",
"tags": ["mongodb", "python", "pymongo"],
"date": datetime.datetime.utcnow()}`
文档中可以包含原生Python类型(如datetime.dateime),这些会被自动转换至/自相应的BSON类型。
2. 插入文档
Insert_one() 方法可以将一个文档插入一个集合:
>>> posts = db.posts>>> post_id = posts.insert_one(post).inserted_id>>> post_idObjectId('...')
文档中如果不包含id字段时,其文档的’_id’字段会自动插入,且该字段需唯一。函数返回InsertOneResult的实例。
当有文档插入后,server才会生成非空的集合posts,我们可以通过列出数据库中所有的集合来验证:
>>> db.collection_names(include_system_collectiOns=False)[u'posts']
3. 批量插入(insert_many)
insert_many()函数可以接受list格式的参数作为第一参数,进行批量插入操作。该函数会将list中每一个文档都插入数据库中,实例如下:
>>> new_posts= [{"author":"Mike",
"text":"Another post!",
"tags": ["bulk","insert"],
"date": datetime.datetime(2009,11,12, 11,14)},
{"author":"Eliot",
"title":"MongoDB is fun",
"text":"and pretty easy too!",
"date": datetime.datetime(2009,11,10, 10,45)}]
>>> result= posts.insert_many(new_posts)
>>> result.inserted_ids
[ObjectId('...'), ObjectId('...')]
4. 同时查询多个文档
find()函数可以用来查询返回多个满足条件的文档。find()函数的返回结果为cursor(游标)对象实例,我们可以通过它来遍历整个匹配结果文档。下例返回了我们之前插入到posts集合中的所有文档:
>>> for postin posts.find():
5. 查询返回结果数目
查询集合内文档数目:
>>> posts.count()
查询集合内满足查询条件的文档数目
>>> posts.find({"author":"Mike"}).count()
Python操作MongoDB案例
#!python
# -*- coding:utf-8 -*-
import sys,json
from pymongo import MongoClient
from pymongo import ASCENDING, DESCENDING
sys.path.append("..")
import uuid,time
from core.logger import mLogger
class MongoAdapter(NoSQLBase):
"""MongoDB数据库的接口类"""
def __init__(self,pconf):
super(MongoAdapter, self).__init__()
self.cOnf= pconf
self.client = MongoClient(‘10.11.115.74’'27017')
self.db = self.client['default_db']
def save(self,data):
sucSaves = 0
try:
myCol = self.db[‘colName’]
myCol.save({"data":“data”, "datastore_timestamp": time.time()})
#self.db.ensure_index(sid, unique=False)#以ID创建索引
except Exception, e:
mLogger.error(e)
if sucSaves > 0:
return True
else:
return False