在以前我们使用数据库的时候,讨论的是使用哪一款关系数据库,如今非关系型数据库也渐渐成为一个可替代的选择,这篇文章将简单对非关系型数据库的代表之一MongoDB展开介绍。

为什么我们需要NoSQL?

    虽然像MySQL这数据库已经足够轻量级,但我们在使用存储和使用数据时,有时并不需要使用关系型数据库建立E-R的联系,表与表之间也不需要进行union操作,我们需要的仅仅是一个能让我们对结构化数据进行CRUD (Create, Retrieve, Update, Delete)操作。
    此外,NoSQL的火热也与近些年来XML或者JSON等数据结构的流行离不开关系。

MongoDB基础

    在官方文件中对MongoDB的介绍是“MongoDB is an open-source document database”, 所谓document,对应关系型数据库中的一行数据,且document中的数据是通过键值(key-value)对来组织的, 其对数据的定义类似于JSON或者Python中的dict数据集合, 如下所示,下面的一组数据在MongoDB中被视为表的一行。

{
	name:'QianchaoLiu',
	age:'20',
	School:'TJU'
}

    一些在RDBMS(关系型数据库)中的概念和MongoDB的对应概念如下表

RDBMSMongoDB
databasedatabase
tablecollection
columnfield

    接来下我们将从一些细节上学习MongoDB

  • 数据类型

    MongoDB中包含的数据存储类型包括String,Array,Double,Object,Date,Null等等,详见文档

  • 主键的处理

    每一个表(collection),都有一个默认的字段(field): “_id”, 系统会默认地对表中的数据建立主键索引。

CRUD操作

    下面以Python为例,对MongoDB的操作做出示例。

  • 连接数据库
from pymongo import MongoClient
# 连接数据库
conn = MongoClient('local', 27017)  # 和MongoClient('mongodb://localhost:27017/') 效果一样
# 切换到database
db = connection.test_database  # 和db = connection['test_database'] 效果一样
# 切换到collection
collection = db.test_collection

    当Colelction和database未提前创建时,这里是滞后创建的,先连接,在创建第一个ducoment后collection和database才会被创建。

  • Insert document

    插入单行数据时,采用下叙述方法:

post = {
	name:'QianchaoLiu',
	age:'20',
	School:'TJU'
}
posts = db.posts
posts.insert_one(post) # 插入一行数据
# 或插入数据并返回默认创建的_id:_id = posts.insert_one(post).inserted_id

    当批量插入数据时,一个方法是使用for循环进行逐条插入,另一种方式是使用 posts.insert_many([{},{}])

  • Select
posts.find_one({"author": "Mike"})

    在查询唯一一行数据时使用上述方法,当查询多会返回多个数据时,我们使用:

for item in posts.find({"author": "Mike"}):
	print item
  • Update
content = collection.find_one({"author": "Mike"})
content["author"] = "liuqianchao"
collection.save(content)

索引

    下面介绍Mongo常用的索引操作(以在Console里操作为例):

db.stats() # 查看数据库存储情况
use database; # 切换databse
show collections; # 查看所有tables
db.collection.getIndexes() # 查看目前存在的索引
db.collection.ensureIndex({"field":1}) # 添加新的索引, 1表示升序
db.collection.dropIndex({"filed":1}) # 删除某条索引

    需要注意,当某条索引为复合索引(Compound Index 同时索引多个字段)时, 单独调用前几个索引是能有效利用索引的,但如果只调用后续索引(比如跳过定义的第一个索引字段)则没能利用索引。

Mongo的内存管理

在使用Mongo,大家可能会发现Mongo进程所占用的内存是比较高的,这是因为Mongo的设计是基于“内存映射存储引擎”的,其会把数据读入内存,从而提高存储和读取的速度。