Skip to content

数据库集成课程计划

课程概述

本课程分为 8 节课,每节课 20-40 分钟,总时长约 120-150 分钟。通过理论讲解和实践操作,深入理解 MongoDB 和 PostgreSQL 的集成方法。

第 1 课:课程介绍与环境准备(5 分钟)

学习目标

  • 了解课程内容和目标
  • 搭建开发环境
  • 安装数据库和依赖

课程内容

  1. 课程介绍

    • MongoDB 和 PostgreSQL 的特点
    • 本课程的学习目标
    • 课程结构安排
  2. 环境准备

    • 安装 MongoDB
    • 安装 PostgreSQL
    • 安装 Node.js 依赖
  3. 项目初始化

    • 创建项目结构
    • 配置数据库连接
    • 测试连接

实践操作

bash
# 安装 MongoDB
# macOS
brew install mongodb-community

# Ubuntu
sudo apt-get install mongodb

# 启动 MongoDB
mongod

# 安装 PostgreSQL
# macOS
brew install postgresql

# Ubuntu
sudo apt-get install postgresql

# 启动 PostgreSQL
pg_ctl start

# 安装 Node.js 依赖
npm install mongoose pg

测试验证

bash
# 测试 MongoDB 连接
node -e "const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/test'); console.log('MongoDB connected');"

# 测试 PostgreSQL 连接
node -e "const { Client } = require('pg'); const client = new Client({ host: 'localhost', port: 5432 }); client.connect(); console.log('PostgreSQL connected');"

预期输出

MongoDB connected
PostgreSQL connected

第 2 课:MongoDB 连接与配置(15 分钟)

学习目标

  • 理解 MongoDB 连接机制
  • 掌握连接池配置
  • 学习错误处理

课程内容

  1. 连接机制

    • 连接字符串格式
    • 连接选项配置
    • 连接事件监听
  2. 连接池

    • 连接池原理
    • 连接池配置
    • 连接复用
  3. 错误处理

    • 连接错误处理
    • 查询错误处理
    • 重试机制

实践操作

javascript
const mongoose = require('mongoose');

// 连接配置
const options = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  maxPoolSize: 10,
  serverSelectionTimeoutMS: 5000,
  socketTimeoutMS: 45000,
};

// 建立连接
mongoose.connect('mongodb://localhost:27017/blog', options)
  .then(() => console.log('MongoDB connected'))
  .catch(err => console.error('Connection error:', err));

// 监听连接事件
mongoose.connection.on('connected', () => {
  console.log('Mongoose connected to MongoDB');
});

mongoose.connection.on('error', (err) => {
  console.error('Mongoose connection error:', err);
});

mongoose.connection.on('disconnected', () => {
  console.log('Mongoose disconnected');
});

测试验证

bash
node src/mongodb/connection.js

预期输出

Mongoose connected to MongoDB
MongoDB connected

第 3 课:PostgreSQL 连接与配置(15 分钟)

学习目标

  • 理解 PostgreSQL 连接机制
  • 掌握连接池配置
  • 学习连接管理

课程内容

  1. 连接机制

    • 连接字符串格式
    • 连接选项配置
    • 连接池管理
  2. 连接池

    • 连接池原理
    • 连接池配置
    • 连接释放
  3. 连接管理

    • 连接获取
    • 连接释放
    • 连接监控

实践操作

javascript
const { Pool } = require('pg');

// 连接池配置
const pool = new Pool({
  host: 'localhost',
  port: 5432,
  database: 'blog',
  user: 'postgres',
  password: 'password',
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

// 测试连接
pool.query('SELECT NOW()', (err, res) => {
  if (err) {
    console.error('Connection error:', err);
  } else {
    console.log('PostgreSQL connected:', res.rows[0]);
  }
});

// 监听连接池事件
pool.on('connect', () => {
  console.log('New client connected');
});

pool.on('remove', () => {
  console.log('Client removed');
});

// 优雅关闭
process.on('SIGINT', async () => {
  await pool.end();
  console.log('Pool has ended');
  process.exit(0);
});

测试验证

bash
node src/postgresql/connection.js

预期输出

PostgreSQL connected: { now: 2024-01-01T00:00:00.000Z }
New client connected

第 4 课:MongoDB 模型定义(15 分钟)

学习目标

  • 理解 Schema 概念
  • 掌握模型定义方法
  • 学习数据验证

课程内容

  1. Schema 定义

    • 基本字段类型
    • 字段验证规则
    • 默认值设置
  2. 模型方法

    • 实例方法
    • 静态方法
    • 虚拟字段
  3. 中间件

    • pre 中间件
    • post 中间件
    • 钩子函数

实践操作

javascript
const mongoose = require('mongoose');

// 用户 Schema
const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    trim: true,
    maxlength: 100
  },
  email: {
    type: String,
    required: true,
    unique: true,
    lowercase: true,
    trim: true
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
});

// 文章 Schema
const articleSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
    trim: true,
    maxlength: 200
  },
  content: {
    type: String,
    required: true
  },
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  tags: [{
    type: String,
    trim: true
  }],
  createdAt: {
    type: Date,
    default: Date.now
  },
  updatedAt: {
    type: Date,
    default: Date.now
  }
});

// 评论 Schema
const commentSchema = new mongoose.Schema({
  content: {
    type: String,
    required: true,
    trim: true,
    maxlength: 500
  },
  article: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Article',
    required: true
  },
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
});

// 创建模型
const User = mongoose.model('User', userSchema);
const Article = mongoose.model('Article', articleSchema);
const Comment = mongoose.model('Comment', commentSchema);

module.exports = { User, Article, Comment };

测试验证

bash
node test/mongodb/models.test.js

预期输出

✅ User model created
✅ Article model created
✅ Comment model created

第 5 课:PostgreSQL 模型定义(15 分钟)

学习目标

  • 理解表结构设计
  • 掌握 SQL 建表语句
  • 学习关系定义

课程内容

  1. 表结构

    • 基本数据类型
    • 约束定义
    • 索引创建
  2. 关系定义

    • 一对一关系
    • 一对多关系
    • 多对多关系
  3. 数据验证

    • CHECK 约束
    • NOT NULL 约束
    • UNIQUE 约束

实践操作

javascript
const { Pool } = require('pg');

const pool = new Pool({
  host: 'localhost',
  port: 5432,
  database: 'blog',
  user: 'postgres',
  password: 'password',
});

// 创建用户表
async function createUsersTable() {
  const query = `
    CREATE TABLE IF NOT EXISTS users (
      id SERIAL PRIMARY KEY,
      name VARCHAR(100) NOT NULL,
      email VARCHAR(255) UNIQUE NOT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
  `;
  await pool.query(query);
  console.log('Users table created');
}

// 创建文章表
async function createArticlesTable() {
  const query = `
    CREATE TABLE IF NOT EXISTS articles (
      id SERIAL PRIMARY KEY,
      title VARCHAR(200) NOT NULL,
      content TEXT NOT NULL,
      author_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
  `;
  await pool.query(query);
  console.log('Articles table created');
}

// 创建评论表
async function createCommentsTable() {
  const query = `
    CREATE TABLE IF NOT EXISTS comments (
      id SERIAL PRIMARY KEY,
      content VARCHAR(500) NOT NULL,
      article_id INTEGER REFERENCES articles(id) ON DELETE CASCADE,
      author_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
  `;
  await pool.query(query);
  console.log('Comments table created');
}

// 创建标签表
async function createTagsTable() {
  const query = `
    CREATE TABLE IF NOT EXISTS tags (
      id SERIAL PRIMARY KEY,
      name VARCHAR(50) UNIQUE NOT NULL
    )
  `;
  await pool.query(query);
  console.log('Tags table created');
}

// 创建文章标签关联表
async function createArticleTagsTable() {
  const query = `
    CREATE TABLE IF NOT EXISTS article_tags (
      article_id INTEGER REFERENCES articles(id) ON DELETE CASCADE,
      tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE,
      PRIMARY KEY (article_id, tag_id)
    )
  `;
  await pool.query(query);
  console.log('Article tags table created');
}

// 创建索引
async function createIndexes() {
  const queries = [
    'CREATE INDEX IF NOT EXISTS idx_articles_author ON articles(author_id)',
    'CREATE INDEX IF NOT EXISTS idx_comments_article ON comments(article_id)',
    'CREATE INDEX IF NOT EXISTS idx_comments_author ON comments(author_id)',
  ];
  
  for (const query of queries) {
    await pool.query(query);
  }
  
  console.log('Indexes created');
}

// 执行初始化
async function init() {
  await createUsersTable();
  await createArticlesTable();
  await createCommentsTable();
  await createTagsTable();
  await createArticleTagsTable();
  await createIndexes();
  
  await pool.end();
  console.log('Database initialized');
}

init().catch(console.error);

测试验证

bash
node src/postgresql/init.js

预期输出

Users table created
Articles table created
Comments table created
Tags table created
Article tags table created
Indexes created
Database initialized

第 6 课:CRUD 操作实现(20 分钟)

学习目标

  • 掌握 MongoDB CRUD 操作
  • 掌握 PostgreSQL CRUD 操作
  • 学习数据验证

课程内容

  1. MongoDB CRUD

    • 创建文档
    • 读取文档
    • 更新文档
    • 删除文档
  2. PostgreSQL CRUD

    • 插入数据
    • 查询数据
    • 更新数据
    • 删除数据
  3. 数据验证

    • Schema 验证
    • 约束验证
    • 错误处理

实践操作

javascript
// MongoDB CRUD 示例
const mongoose = require('mongoose');
const { User, Article, Comment } = require('./models');

// 创建用户
async function createUser(userData) {
  const user = new User(userData);
  await user.save();
  return user;
}

// 查询用户
async function findUser(conditions) {
  return await User.findOne(conditions);
}

// 更新用户
async function updateUser(userId, updates) {
  return await User.findByIdAndUpdate(userId, updates, { new: true });
}

// 删除用户
async function deleteUser(userId) {
  return await User.findByIdAndDelete(userId);
}

// PostgreSQL CRUD 示例
const { Pool } = require('pg');
const pool = new Pool({ /* config */ });

// 创建用户
async function createUser(userData) {
  const query = 'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *';
  const result = await pool.query(query, [userData.name, userData.email]);
  return result.rows[0];
}

// 查询用户
async function findUser(userId) {
  const query = 'SELECT * FROM users WHERE id = $1';
  const result = await pool.query(query, [userId]);
  return result.rows[0];
}

// 更新用户
async function updateUser(userId, updates) {
  const query = 'UPDATE users SET name = $1, email = $2 WHERE id = $3 RETURNING *';
  const result = await pool.query(query, [updates.name, updates.email, userId]);
  return result.rows[0];
}

// 删除用户
async function deleteUser(userId) {
  const query = 'DELETE FROM users WHERE id = $1 RETURNING *';
  const result = await pool.query(query, [userId]);
  return result.rows[0];
}

测试验证

bash
npm test

预期输出

✅ MongoDB CRUD tests passed
✅ PostgreSQL CRUD tests passed

第 7 课:博客系统实战(20 分钟)

学习目标

  • 整合所有功能
  • 构建完整博客系统
  • 学习业务逻辑实现

课程内容

  1. 系统设计

    • 功能模块划分
    • 数据模型设计
    • API 接口设计
  2. 业务实现

    • 用户管理
    • 文章管理
    • 评论管理
  3. 测试验证

    • 功能测试
    • 集成测试
    • 性能测试

实践操作

javascript
const { BlogService } = require('./src/services');

async function main() {
  const service = new BlogService('mongodb');

  // 创建用户
  const user = await service.createUser({
    name: '张三',
    email: 'zhangsan@example.com'
  });
  console.log('User created:', user);

  // 创建文章
  const article = await service.createArticle({
    title: '我的第一篇文章',
    content: '这是文章内容',
    authorId: user.id,
    tags: ['Node.js', 'MongoDB']
  });
  console.log('Article created:', article);

  // 添加评论
  const comment = await service.createComment({
    content: '很好的文章',
    articleId: article.id,
    userId: user.id
  });
  console.log('Comment created:', comment);

  // 查询文章列表
  const articles = await service.findArticlesByAuthor(user.id);
  console.log('Articles:', articles);

  // 查询文章详情
  const articleDetail = await service.findArticleById(article.id);
  console.log('Article detail:', articleDetail);
}

main().catch(console.error);

测试验证

bash
node examples/blog.js

预期输出

User created: { id: ..., name: '张三', email: 'zhangsan@example.com' }
Article created: { id: ..., title: '我的第一篇文章', ... }
Comment created: { id: ..., content: '很好的文章', ... }
Articles: [...]
Article detail: { id: ..., title: '我的第一篇文章', ... }

第 8 课:总结与扩展(15 分钟)

学习目标

  • 回顾课程内容
  • 总结核心概念
  • 探索扩展方向

课程内容

  1. 课程回顾

    • MongoDB 连接和配置
    • PostgreSQL 连接和配置
    • 模型定义和验证
    • CRUD 操作实现
    • 博客系统实战
  2. 核心概念总结

    • 连接池管理
    • 数据验证
    • 错误处理
    • 性能优化
  3. 扩展方向

    • 分页功能实现
    • 搜索功能集成
    • 缓存层添加
    • 数据迁移实现
    • 连接池优化

实践操作

bash
# 运行所有测试
npm test

# 思考如何扩展功能
# 实现分页、搜索、缓存等功能

预期输出

✅ 所有测试通过

学习成果

完成本课程后,你将能够:

  1. ✅ 理解 MongoDB 和 PostgreSQL 的核心概念
  2. ✅ 掌握数据库连接和配置
  3. ✅ 实现完整的 CRUD 操作
  4. ✅ 构建可扩展的数据访问层
  5. ✅ 实现博客系统实战案例

参考资源

下一步

完成本课程后,你可以继续学习:

  • 认证和授权(JWT、OAuth)
  • WebSocket 实时通信
  • 微服务架构
  • 容器化部署(Docker)
  • CI/CD 持续集成

所有教学材料已保存。准备录制。


架构师AI杜公众号二维码

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态