mongodb学习系列2:概念和CRUD操作

概念和CRUD操作

Posted by Chris on October 7, 2019

1 简介

MongoDB是为了快速开发互联网Web应用而生的数据库系统。下面,将从快速开发、互联网web应用和数据库系统三个方面来说明。

  • 数据库系统

    首先,mongodb是一个数据库系统,类似于mysql关系型数据库。与mysql的作用是一样的,都是用来持久化的存储数据的。但是,在最直观的使用方面,mysql存储需要将数据结构化之后存储,即分割为多个字段再存储;mongodb则是直接存储整个文档(文档,可以认为是一个json对象,后面再介绍概念),不需要再拆分为多个字段。注意,mongodb和mysql一样,目的都是用来做持久存储的,而不是用来做缓存的。

  • 快速开发

    1. 由于mongodb可以直接存储json对象,则有利于用户直接将前端展示的json对象或者后端处理的对象json化之后存储到mongodb中。这样,就省去字段的拆分过程。
    2. 由于mongodb是直接存储json对象,则后面维护时添加属性很方便。
    3. 通过json对象的嵌套或者mongodb的引用,在有些情况下可以代替mysql中JOIN操作,从而可以做到快速开发。
  • 互联网web应用

    互联网应用一般都具有很大的数据量,因此,要求存储具有高扩展性和高性能。mongodb的数据模型和持久化策略支持高性能的读/写,支持高扩展性。相比mysql,mongodb很容易做到读写的扩展。

2 为什么使用mongodb

mongodb和mysql都是作为持久化存储的设备,那么,什么时候应该选取mongodb呢?先看看mongodb相对于mysql的不同。mongodb相关的概念在后面介绍。

3 基本概念

  • 文档(document):mongodb的文档,相当于关系数据库中的一行记录。
  • 集合(collection):多个文档组成一个集合,相当于关系型数据库中的一个表。
  • 数据库(database):多个集合,逻辑上组织在一起,就是一个数据库。
  • 一个运行的mongodb server支持多个数据库。

4 CRUD操作

下面的示例中,使用的mongodb服务端和客户端版本都是4.0之后的版本。

4.1 数据库的操作

  • 创建新的数据库

语法: use {DATABASE_NAME},然后插入一条记录

示例

> use db_test // 切换到使用db_test数据库,虽然db_test还不存在。
> db.col_test.save(o)  // o为一个json对象。这里创建一个名为col_test的集合,然后插入一条记录。

注意:使用use {DATABASE_NAME}命令之后,必须插入记录,才会真正创建一个数据库。

  • 删除数据库

先切换到目标数据库,然后使用db.dropDatabase()

示例

> use db_test
> db.dropDatabase()
  • 显示所有数据库
> show dbs
  • 显示当前正在使用的数据库
> db

4.2 数据表(集合)的操作

  • 创建集合

语法: 使用db.createCollection(name, options)命令。options参数可以省略。

示例

> db.createCollection("col_test") // 创建一个col_test集合
  • 删除集合

语法: 使用db.{COLLECTION_NAME}.drop()命令

示例

> db.col_test.drop() // 删除col_test集合
  • 显示当前使用的集合

使用show tables或者show collections命令

> show collections // 显示所有的集合

4.3 文档(数据行)的操作

  • 插入文档

语法

使用db.{COLLECTION_NAME}.insert(document)命令或者db.{COLLECTION_NAME}.save(document)命令

示例

> db.col_book.save({
    "title":"Head First Java",
    "price":10
})

或者先将json对象赋给一个变量,再插入。

> var book = {
    "title":"Head First Java",
    "price":10
};
> db.col_book.save(book)

insert()和save()的区别是,如果不指定_id字段save()方法类似于insert()方法。如果指定_id字段,则会替换该_id对应的文档数据。

  • 查询文档

语法

使用db.{COLLECTION_NAME}.find(query, projection)命令

query:使用查询操作符组成的查询条件,可选。若省略该参数,则返回集合中的所有文档。
projection :使用投影操作符指定的返回的键,可选。若省略该参数,则查询时返回文档中所有键值。

示例

> db.col_book.find() // 返回集合col_book所有文档,文档中的所有字段

下面的示例,查询所有title为”Head First Java”的书,只返回title键。

> var query = {
    "title": "Head First Java"
};
> var projection = {
    "title": 1
};
> db.col_book.find(query, projection);
{ "_id" : ObjectId("5d99d7aade304a0a030ff95e"), "title" : "Head First Java" }

可以看到,上面的返回结果中出现了_id这个键。存储在mongodb中的每个文档都有一个默认的主键_id,作用类似于mysql的主键,用来唯一标志每个文档。但是,在数据类型和生成方式上不一样。 _id可以在插入文档时指定,可以是任何类型;如果不指定,则默认生成一个数据类型为ObjectId的主键。默认生成的_id主键并不是自增的,而是通过snowflake算法类似的算法生成的,定位于分布式存储系统,其格式如下图所示。

  • 更新文档

语法

db.{COLLECTION_NAME}.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

query:update的查询条件,类似于sql update语句后面的where条件部分。
update:需要更新的键和一些有关的操作符(如$set,$inc…)等,可以理解为sql update语句set后面的部分
upsert:如果不存在update的记录,是否插入新的文档。true为插入,false为不插入,默认是false。该参数可选。
multi:是否只更新找到的第一条记录,默认为false。若为true,则把按条件查出来多条记录全部更新。
writeConcern:可选,抛出异常的级别

示例

> var query = {
    "title": "Head First Mysql"
};
> var update = {
    "$set": {
        "price": 100
    }
};
> var params = {
    "multi": true
};
> db.col_book.update(query, update, params)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

或者通过指定_id键方式的save()命令来替换整个文档。

> var data = {
    "_id": ObjectId("5d99d746ac39b2706ef53073"),
    "title": "Head First Mysql",
    "price": 2000
};
> db.col_book.save(data)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  • 删除文档

语法

db.{COLLECTION_NAME}.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

query:删除条件。可选。
justOne:是否只删除符合条件的一个文档,可选。默认为false,即默认删除符合条件的所有文档。
writeConcern:抛出异常的级别,可选。

示例

下面的代码,删除title为”Head First Mysql”的其中一个文档。

> var query = {
    "title": "Head First Mysql"
};
> var params = {
    "justOne": true
}
> db.col_book.remove(query, params)

如果要删除某个集合下的所有文档,则可以使用db.{COLLECTION_NAME}.remove({})命令

参考

MongoDB 进阶模式设计
MongoDB Vs MySQL: The Differences Explained
MongoDB开发规范