最近由于某些原因,要培训两个非MongoDB 的DBA掌握MongoDB的一些知识,好投入战斗,想着写教案的时候,还不如写一个入门贴。

什么是MongoDB: MongoDB  是一款高性能的分布式存储可进行横向扩展的自带高可用协议和功能的存储数据以Json格式数据为主的数据库产品,客户可以选择的产品主要有三种,1 开源产品 2 付费企业级的数据库 3 MongoDB Atlas 

国内一般在使用产品的时候,多使用的是开源的产品,在数据的一些特殊功能方面有一些缺失,相对于企业版的数据库产品。

我们直接说,企业版多了什么功能,主要功能在审计和 in-memory引擎

In-Memory Storage Engine
Auditing
Kerberos Authentication
LDAP Proxy Authentication and LDAP Authorization
Encryption at Rest

所以对于审计功能有要求的可以考虑购买企业版的MongoDB.

MongoDB 中的一些术语和知识

1  表不叫表,叫collection 集合

2  行不叫行 ,称为document

3  在一行里面或者在一个doucument 里面会存在 key-value pairs, 这里我们称之为 fields and values .

4   replica set 副本集:在MongoDB,生产数据库是不允许单机呈现的,因为会出现数据安全性的问题,所以在生产环境中,应该是至少3节点的模式来进行数据库的安装和呈现的。

5   WiredTiger:  WiredTiger 是MongoDB的数据库处理引擎,与MySQL innodb 类似,也是第三方开发的数据库引擎,在MongoDB 上使用,最早的MongoDB的数据库引擎不是 wiredTiger ,WiredTiger 数据库引擎彻底改变了MongoDB 的一些数据处理方式和性能。

6 _id 与其他的数据库不同,在MongoDB 是自己产生主键,我们称之为object_id,这里我们建议,不要自定义主键,而是要使用object_id , 在MongoDB 中表达为_id

7  Schema  无模式,这里MongoDB 的数据组成方式并不是和传统数据库一样,而是可以每一行与每一行的数据组成的构成都可以不一样,但这里不建议这样进行设计。同时MongoDB 中也有约束,可以通过约束来指定文档中的结构。

8  Index ,与传统数据库类似,MongoDB中也存在索引,但使用的方式与类型与传统数据库略有不同,在属性上也有一些区别.

9  慢查询:在一些数据库中的慢查询以秒来计算,在MongoDB中的慢查询相对传统数据库维度要更小一点,比如一般慢查询的阀值在 500毫秒等

10  聚合:在MongoDB中也是可以对数据进行类似传统数据库的聚合操作的,有相关的一些语句的写法来进行相关的操作。

基本命令:

1  建立或打开一个数据库,这里注意,在MongoDB里面没有建库的命令,如果要建立或打开一个数据库,都用use 命令即可

> use test
switched to db test
> 
> 
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
> 
> db
test
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

2  建表 在mongoDB 中可以没有建表语句,通过插入数据的方式直接产生一张collection

> use test
switched to db test
> 
> 
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
> 
> db
test
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
> 
> 
> 
> db.myCollection.insertOne({
...   name: "Alice",
...   age: 30,
...   address: {
...     street: "123 Main St",
...     city: "Springfield"
...   },
...   hobbies: ["reading", "hiking", "coding"]
... })
{
 "acknowledged" : true,
 "insertedId" : ObjectId("61f8080cfa8251f3e6306e27")
}
> show collections;
myCollection
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

是否可以创建一个带有约束的MongoDB的collection,是可以可以的,比如下面这个例子。

这个例子中,限制了一个名字叫myCollection 的集合,里面限制了在文档中必须包含 name 和 age 两个并且要求,name必须是string类型的而age必须是 int 类型的。

db.createCollection("myCollection", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "age"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          description: "must be an integer and is required"
        }
      }
    }
  }
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

然后我们尝试在里面插入数据,失败,原因是 age中的数据被认为是double类型的所以插入失败。

> db.myCollection.insertOne({
...   name: "Charlie",
...   age: 19,
...   address: {
...     street: "789 Pine St",
...     city: "Springfield"
...   },
...   hobbies: ["gaming", "swimming"]
... })
WriteError({
 "index" : 0,
 "code" : 121,
 "errmsg" : "Document failed validation",
 "op" : {
  "_id" : ObjectId("61f80d1efa8251f3e6306e2e"),
  "name" : "Charlie",
  "age" : 19,
  "address" : {
   "street" : "789 Pine St",
   "city" : "Springfield"
  },
  "hobbies" : [
   "gaming",
   "swimming"
  ]
 },
 "errInfo" : {
  "failingDocumentId" : ObjectId("61f80d1efa8251f3e6306e2e"),
  "details" : {
   "operatorName" : "$jsonSchema",
   "schemaRulesNotSatisfied" : [
    {
     "operatorName" : "properties",
     "propertiesNotSatisfied" : [
      {
       "propertyName" : "age",
       "details" : [
        {
         "operatorName" : "bsonType",
         "specifiedAs" : {
          "bsonType" : "int"
         },
         "reason" : "type did not match",
         "consideredValue" : 19,
         "consideredType" : "double"
        }
       ]
      }
     ]
    }
   ]
  }
 }
}) :
WriteError({
 "index" : 0,
 "code" : 121,
 "errmsg" : "Document failed validation",
 "op" : {
  "_id" : ObjectId("61f80d1efa8251f3e6306e2e"),
  "name" : "Charlie",
  "age" : 19,
  "address" : {
   "street" : "789 Pine St",
   "city" : "Springfield"
  },
  "hobbies" : [
   "gaming",
   "swimming"
  ]
 },
 "errInfo" : {
  "failingDocumentId" : ObjectId("61f80d1efa8251f3e6306e2e"),
  "details" : {
   "operatorName" : "$jsonSchema",
   "schemaRulesNotSatisfied" : [
    {
     "operatorName" : "properties",
     "propertiesNotSatisfied" : [
      {
       "propertyName" : "age",
       "details" : [
        {
         "operatorName" : "bsonType",
         "specifiedAs" : {
          "bsonType" : "int"
         },
         "reason" : "type did not match",
         "consideredValue" : 19,
         "consideredType" : "double"
        }
       ]
      }
     ]
    }
   ]
  }
 }
})
WriteError@src/mongo/shell/bulk_api.js:465:48
mergeBatchResults@src/mongo/shell/bulk_api.js:871:49
executeBatch@src/mongo/shell/bulk_api.js:940:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1182:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:264:9
@(shell):1:1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.

在我们标记好相关的数字的类型后,数据可以插入。

> db.myCollection.insertOne({
...   name: "Charlie",
...   age: NumberInt(19),
...   address: {
...     street: "789 Pine St",
...     city: "Springfield"
...   },
...   hobbies: ["gaming", "swimming"]
... })
{
 "acknowledged" : true,
 "insertedId" : ObjectId("61f8109cfa8251f3e6306e2f")
}
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

所以MongoDB中是可以进行相关的无结构的文档的约束设计的,也就是在无结构中可以保证有些结构是存在的,并且值也是要符合要求的。

今天就先写到这里,后面继续...

Austindatabases 公众号,主要围绕数据库技术(PostgreSQL, MySQL, Mongodb, Redis, SqlServer,PolarDB, Oceanbase 等)和职业发展,国外数据库大会音译,国外大型IT信息类网站文章翻译,等,希望能和您共同发展。