MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

MongoDB数据库的创建与管理指南

2023-04-017.0k 阅读

MongoDB 数据库基础概念

在深入了解 MongoDB 数据库的创建与管理之前,我们先来明晰一些基础概念。

MongoDB 是一个基于分布式文件存储的开源数据库系统,属于 NoSQL 数据库范畴。与传统的关系型数据库(如 MySQL、Oracle 等)不同,MongoDB 采用了文档型的数据存储方式。在关系型数据库中,数据以表格形式存储,每个表格由行和列组成,行代表记录,列代表字段。而在 MongoDB 中,数据以文档(document)的形式存储,文档类似 JSON 对象,由键值对组成。例如:

{
    "name": "John",
    "age": 30,
    "city": "New York"
}

这种文档结构使得 MongoDB 在处理复杂数据结构时更加灵活,无需像关系型数据库那样预先定义表结构。

数据库(Database)是 MongoDB 中数据的逻辑容器,一个 MongoDB 实例可以包含多个数据库。每个数据库都有自己的一组集合(Collection)。集合类似于关系型数据库中的表,是文档的分组。不过与表不同的是,集合不需要预先定义结构,集合中的文档可以有不同的字段。例如,在一个名为 users 的集合中,可能有这样两个文档:

{
    "name": "Alice",
    "email": "alice@example.com"
}
{
    "name": "Bob",
    "age": 25,
    "phone": "123 - 456 - 7890"
}

创建 MongoDB 数据库

在 MongoDB 中,数据库不需要显式创建。当你第一次向某个数据库插入数据时,该数据库就会被自动创建。下面我们通过 MongoDB 的 shell 来演示这一过程。

首先,确保 MongoDB 服务已经启动。打开终端,输入 mongo 命令进入 MongoDB shell。

假设我们要创建一个名为 myDB 的数据库,并在其中插入一些数据。我们可以这样操作:

// 使用 use 命令切换到 myDB 数据库,如果数据库不存在则会在后续插入数据时创建
use myDB;

// 创建一个集合(类似表),这里命名为 users
db.createCollection("users");

// 向 users 集合中插入一个文档
db.users.insertOne({
    "name": "Charlie",
    "age": 28,
    "email": "charlie@example.com"
});

在上述代码中,use myDB 命令用于切换到 myDB 数据库,如果 myDB 不存在,并不会报错,而是在后续插入数据时创建该数据库。db.createCollection("users") 创建了一个名为 users 的集合。db.users.insertOne 方法向 users 集合中插入了一个文档。

如果你使用的是编程语言连接 MongoDB 来创建数据库,以 Python 的 PyMongo 库为例:

from pymongo import MongoClient

# 连接到 MongoDB 实例
client = MongoClient('mongodb://localhost:27017/')

# 获取或创建数据库
db = client['myDB']

# 获取或创建集合
users_collection = db['users']

# 插入一个文档
users_collection.insert_one({
    "name": "David",
    "age": 32,
    "email": "david@example.com"
})

在这段 Python 代码中,首先通过 MongoClient 连接到本地运行的 MongoDB 实例。然后通过 client['myDB'] 获取或创建 myDB 数据库,通过 db['users'] 获取或创建 users 集合,最后使用 insert_one 方法插入文档。

管理 MongoDB 数据库

查看数据库

在 MongoDB shell 中,可以使用 show dbs 命令查看当前 MongoDB 实例中的所有数据库。例如:

show dbs;

这会列出所有数据库及其占用空间等信息。输出类似如下:

admin   0.000GB
config  0.000GB
local   0.000GB

如果要查看当前使用的数据库,可以使用 db 命令:

db;

该命令会输出当前所在的数据库名称。

删除数据库

在 MongoDB shell 中,删除数据库非常简单。首先切换到要删除的数据库,然后使用 dropDatabase() 方法。例如,要删除 myDB 数据库:

use myDB;
db.dropDatabase();

如果使用编程语言来删除数据库,以 Node.js 的 mongodb 包为例:

const { MongoClient } = require('mongodb');

const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);

async function deleteDatabase() {
    try {
        await client.connect();
        const database = client.db('myDB');
        await database.dropDatabase();
        console.log('Database deleted successfully');
    } catch (e) {
        console.error(e);
    } finally {
        await client.close();
    }
}

deleteDatabase();

在这段 Node.js 代码中,首先通过 MongoClient 连接到 MongoDB 实例。然后获取要删除的数据库 myDB,并使用 dropDatabase 方法删除该数据库。

备份与恢复数据库

MongoDB 提供了 mongodumpmongorestore 工具来进行数据库的备份和恢复。

备份数据库: 在终端中,使用 mongodump 命令备份数据库。例如,要备份 myDB 数据库到 /backup/myDB_backup 目录:

mongodump --uri="mongodb://localhost:27017/myDB" -o /backup/myDB_backup

上述命令中,--uri 指定了要备份的数据库连接字符串,-o 指定了备份文件的输出目录。备份完成后,/backup/myDB_backup 目录下会生成数据库相关的备份文件,这些文件以 BSON(Binary JSON)格式存储数据。

恢复数据库: 使用 mongorestore 命令恢复数据库。假设我们要将之前备份的 myDB 数据库恢复到 MongoDB 实例中:

mongorestore --uri="mongodb://localhost:27017" /backup/myDB_backup/myDB

这里 --uri 指定了要恢复到的 MongoDB 实例连接字符串,后面跟上备份文件的路径。注意路径要指定到具体数据库的备份目录。

MongoDB 数据库的高级管理

用户与权限管理

MongoDB 支持用户认证和权限管理,这对于保护数据库安全至关重要。

创建用户: 在 MongoDB shell 中,首先切换到 admin 数据库(因为用户管理通常在 admin 数据库中进行),然后使用 db.createUser() 方法创建用户。例如,创建一个具有管理员权限的用户 adminUser

use admin;
db.createUser({
    user: "adminUser",
    pwd: "adminPassword",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
});

在上述代码中,user 字段指定用户名,pwd 字段指定密码,roles 字段指定用户角色。这里的 userAdminAnyDatabase 角色表示该用户可以管理任何数据库的用户。

修改用户密码: 如果要修改用户密码,可以使用 db.changeUserPassword() 方法。例如,修改 adminUser 的密码:

use admin;
db.changeUserPassword("adminUser", "newAdminPassword");

权限管理: MongoDB 有多种内置角色,如 read(只读权限)、readWrite(读写权限)等。可以在创建用户时为用户分配不同的角色来控制其权限。例如,创建一个只对 myDB 数据库有读写权限的用户 myDBUser

use admin;
db.createUser({
    user: "myDBUser",
    pwd: "myDBPassword",
    roles: [ { role: "readWrite", db: "myDB" } ]
});

这样 myDBUser 用户只能对 myDB 数据库进行读写操作。

数据库性能优化

  1. 索引优化
    • MongoDB 的索引类似于关系型数据库的索引,用于提高查询性能。创建索引可以显著加快查询速度,尤其是在大数据量的情况下。
    • 例如,在 users 集合的 email 字段上创建索引:
      • 在 MongoDB shell 中:
use myDB;
db.users.createIndex({ email: 1 });

这里 { email: 1 } 表示按 email 字段升序创建索引。如果要创建降序索引,可以使用 { email: -1 }。 - 在 Python 的 PyMongo 中:

from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['myDB']
users_collection = db['users']
users_collection.create_index([('email', 1)])
  1. 查询优化
    • 合理设计查询语句对于性能提升也很关键。尽量避免全表扫描,利用索引进行查询。例如,对于上述创建了 email 索引的 users 集合,在查询时:
      • 在 MongoDB shell 中:
use myDB;
db.users.find({ email: "charlie@example.com" });

这样的查询会利用 email 索引,提高查询效率。 - 在 Python 的 PyMongo 中:

from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['myDB']
users_collection = db['users']
result = users_collection.find({ "email": "charlie@example.com" })
for user in result:
    print(user)
  1. 分片(Sharding)
    • 当数据量非常大时,单个服务器可能无法存储所有数据或提供足够的性能。分片是将数据分散存储在多个服务器(称为分片服务器)上的技术。
    • 要启用分片,首先需要配置一个或多个配置服务器(config server),用于存储分片元数据。然后配置路由服务器(mongos),客户端通过路由服务器与分片集群交互。最后将数据分布到各个分片服务器上。
    • 例如,假设我们有三个分片服务器 shard1shard2shard3,一个配置服务器 configsvr 和一个路由服务器 mongos
      • 启动配置服务器:
mongod --configsvr --replSet configReplSet --port 27019 --dbpath /data/configdb

这里 --configsvr 表示这是一个配置服务器,--replSet 用于配置副本集(配置服务器也推荐使用副本集模式),--port 指定端口,--dbpath 指定数据存储路径。 - 启动分片服务器:

mongod --shardsvr --replSet shard1 --port 27020 --dbpath /data/shard1
mongod --shardsvr --replSet shard2 --port 27021 --dbpath /data/shard2
mongod --shardsvr --replSet shard3 --port 27022 --dbpath /data/shard3

--shardsvr 表示这是一个分片服务器。 - 启动路由服务器:

mongos --configdb configReplSet/localhost:27019 --port 27017

这里 --configdb 指定配置服务器的副本集地址。

  • 配置好集群后,可以通过 MongoDB shell 启用分片并指定分片键。例如,在 myDB 数据库的 users 集合上按 user_id 字段进行分片:
use admin;
db.runCommand({ enableSharding: "myDB" });
db.runCommand({ shardCollection: "myDB.users", key: { user_id: 1 } });

这样 myDB.users 集合的数据就会根据 user_id 字段的值分散存储在各个分片服务器上。

副本集(Replica Set)管理

副本集是一组 MongoDB 服务器,其中一个为主节点(primary),其余为从节点(secondary)。主节点处理所有写操作,从节点复制主节点的数据。副本集提供了数据冗余和高可用性。

  1. 创建副本集
    • 假设我们有三个节点,分别运行在不同端口:270172701827019
    • 首先,为每个节点创建数据目录并启动 MongoDB 服务:
mkdir -p /data/replica1
mongod --port 27017 --dbpath /data/replica1 --replSet myReplSet
mkdir -p /data/replica2
mongod --port 27018 --dbpath /data/replica2 --replSet myReplSet
mkdir -p /data/replica3
mongod --port 27019 --dbpath /data/replica3 --replSet myReplSet

这里 --replSet 指定副本集名称为 myReplSet

  • 然后,进入 MongoDB shell 并初始化副本集:
mongo --port 27017
rs.initiate({
    _id: "myReplSet",
    members: [
        { _id: 0, host: "localhost:27017" },
        { _id: 1, host: "localhost:27018" },
        { _id: 2, host: "localhost:27019" }
    ]
});

rs.initiate 方法用于初始化副本集,_id 为副本集名称,members 数组中定义了副本集的各个成员节点。

  1. 副本集操作
    • 查看副本集状态:在 MongoDB shell 中,可以使用 rs.status() 命令查看副本集状态。例如:
rs.status();

这会输出副本集的详细信息,包括主节点、从节点状态,成员健康状况等。

  • 故障转移:如果主节点发生故障,副本集的选举机制会自动从从节点中选举出一个新的主节点,保证服务的可用性。例如,当主节点 localhost:27017 故障时,其他从节点会自动选举出新的主节点。

数据库的维护与监控

数据库统计信息

在 MongoDB shell 中,可以使用 db.stats() 方法获取当前数据库的统计信息。例如:

use myDB;
db.stats();

该命令会返回数据库的大小、集合数量、文档数量等信息。输出类似如下:

{
    "db": "myDB",
    "collections": 1,
    "objects": 2,
    "avgObjSize": 72,
    "dataSize": 144,
    "storageSize": 4096,
    "numExtents": 1,
    "indexes": 1,
    "indexSize": 8176,
    "ok": 1
}

这里 collections 表示集合数量,objects 表示文档数量,dataSize 表示数据占用空间大小,storageSize 表示实际存储占用空间大小等。

监控工具

  1. MongoDB Compass
    • MongoDB Compass 是官方提供的可视化工具,用于管理和监控 MongoDB 数据库。它可以直观地查看数据库结构、执行查询、管理索引等。
    • 下载并安装 MongoDB Compass 后,连接到本地或远程的 MongoDB 实例。在界面上可以看到数据库列表、集合列表,点击集合可以查看文档,还可以在查询界面执行复杂的查询语句,并实时查看查询结果。同时,Compass 也提供了性能监控功能,可以查看数据库的读写操作频率、响应时间等指标。
  2. mongotop
    • mongotop 是 MongoDB 自带的命令行工具,用于监控数据库的读写操作时间。在终端中运行 mongotop 命令,它会实时显示每个数据库的读写操作占用时间的百分比。例如:
mongotop

输出类似如下:

ns           total    read    write
myDB.users    0.000    0.000    0.000
local.oplog.rs 0.000    0.000    0.000

这里 ns 表示命名空间(数据库.集合),total 表示总操作时间,read 表示读操作时间,write 表示写操作时间。通过 mongotop 可以快速定位哪些数据库或集合的读写操作比较频繁,从而进行针对性的优化。

  1. mongostat
    • mongostat 也是 MongoDB 自带的命令行工具,用于监控 MongoDB 实例的各种状态指标,如连接数、插入、查询、更新、删除操作的频率等。在终端中运行 mongostat 命令:
mongostat

输出类似如下:

insert  query  update  delete  getmore  command  flushes  mapped  vsize  res  faults  locked db  idx miss  qr  qw  ar  aw  netIn  netOut  conn  set repl  time
    0      0       0       0        0       1       0    16m  1.1g 140m      0        0 admin:0.0%  0.0%     0   0   0   0   0    38b     42b    1  myReplSet PRIMARY 16:30:12

这里 insertqueryupdatedelete 分别表示插入、查询、更新、删除操作的频率,mapped 表示映射的内存大小,vsize 表示虚拟内存大小,res 表示常驻内存大小等。通过 mongostat 可以全面了解 MongoDB 实例的运行状态,及时发现性能问题。

通过以上对 MongoDB 数据库创建与管理的详细介绍,涵盖了从基础的数据库创建到高级的性能优化、用户权限管理、副本集与分片管理以及数据库的维护与监控等方面,希望能帮助你全面掌握 MongoDB 数据库的相关操作和管理技巧,在实际项目中更好地应用 MongoDB。