資料庫開發實戰
今天用Claude Code完成一個完整的資料庫開發專案——從Schema設計到效能最佳化,從資料遷移到生產部署。
這個案例會教你:
- Schema設計和建模
- 生成和執行遷移檔案
- 編寫複雜查詢
- 效能分析和最佳化
- 資料遷移和版本管理
專案概述
專案背景:部落格系統資料庫
為部落格平臺設計完整的資料庫架構,系統需要:
- 使用者管理: 使用者註冊、登入、許可權控制
- 文章管理: 文章釋出、編輯、分類、標籤
- 評論系統: 多級評論、點贊、回覆
- 社交功能: 關注、粉絲、動態
- 內容稽覈: 敏感詞過濾、舉報處理
- 統計分析: 閱讀量、點贊量、使用者活躍度
技術棧選擇
- 資料庫: PostgreSQL 15+ (關係型,支援複雜查詢)
- ORM: Prisma (型別安全,優秀的遷移系統)
- 快取: Redis (會話、熱點資料)
- 連線池: PgBouncer (生產環境連線管理)
- 開發工具: Claude Code (主要開發助手)
為什麼選擇PostgreSQL?
✓ 支持复杂查询和JOIN操作
✓ 原生JSON类型,灵活存储
✓ 全文搜索功能强大
✓ 事务处理可靠
✓ 拥有丰富的索引类型
✓ 开源免费,社区活跃
準備工作
環境搭建
# 检查PostgreSQL版本
psql --version
# 需要PostgreSQL 15或更高版本
# 检查Node.js版本
node --version
# 需要Node.js 18+
# 创建项目目录
mkdir blog-database-dev
cd blog-database-dev
# 初始化项目
npm init -y
# 初始化Git仓库
git init
git branch -M main
安裝依賴
# 安装Prisma CLI
npm install prisma @prisma/client --save-dev
# 安装PostgreSQL客户端
npm install pg --save
# 安装Redis客户端
npm install redis --save
# 安装其他工具库
npm install dotenv uuid bcryptjs --save
啟動Claude Code
# 在项目目录启动
claude
歡迎介面:
╔══════════════════════════════ ══════════════╗
║ ║
║ Welcome to Claude Code (Beta) ║
║ ║
╚════════════════════════════════════════════╝
Connected to: claude-sonnet-4.5
Working directory: /Users/username/blog-database-dev
How can I help you code today?
第一階段:Schema設計
第一輪對話
開始設計資料庫Schema:
我要为博客系统设计数据库Schema,系统需要:
1. User(用户表)
- id, username, email, password(哈希)
- avatar, bio, role(admin/author/user)
- createdAt, updatedAt, lastLoginAt
- 索引:email(unique), username(unique)
2. Post(文章表)
- id, title, slug, content(summary), body
- author(外键->User), status(draft/published/archived)
- views, likesCount, commentsCount
- publishedAt, createdAt, updatedAt
- 索引:slug(unique), author, status, publishedAt
3. Category(分类表)
- id, name, slug, description
- parentId(自关联), order
- 索引:slug(unique), parentId
4. Tag(标签表)
- id, name, slug, color
- 索引:name(unique), slug(unique)
5. Comment(评论表)
- id, content, author(外键->User)
- post(外键->Post), parentComment(自关联)
- likesCount, status(pending/approved/rejected)
- createdAt, updatedAt
- 索引:post, author, parentComment, status
6. Follow(关注关系表)
- follower(外键->User), following(外键->User)
- createdAt
- 唯一索引:follower+following
请使用Prisma设计这些模型,包含所有关系。
Claude Code會建立完整的Schema檔案:
Prisma Schema生成
prisma/schema.prisma:
// Prisma Schema for Blog System
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// 用户模型
model User {
id String @id @default(uuid())
username String @unique
email String @unique
password String
avatar String?
bio String? @db.Text
role UserRole @default(USER)
// 关系
posts Post[]
comments Comment[]
followers Follow[] @relation("UserFollowers")
following Follow[] @relation("UserFollowing")
likes Like[]
activities Activity[]
// 时间戳
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
lastLoginAt DateTime?
@@index([email])
@@index([username])
@@map("users")
}
enum UserRole {
ADMIN
AUTHOR
USER
}
// 文章模型
model Post {
id String @id @default(uuid())
title String
slug String @unique
content String? @db.Text
body String @db.Text
excerpt String? @db.VarChar(500)
// 关系
author User @relation(fields: [authorId], references: [id])
authorId String
category Category? @relation(fields: [categoryId], references: [id])
categoryId String?
tags PostTag[]
// 状态和统计
status PostStatus @default(DRAFT)
views Int @default(0)
likesCount Int @default(0)
commentsCount Int @default(0)
featured Boolean @default(false)
pinned Boolean @default(false)
// SEO
metaTitle String?
metaDescription String? @db.VarChar(160)
keywords String[]
// 时间戳
publishedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
@@index([categoryId])
@@index([status])
@@index([publishedAt(sort: Desc)])
@@index([slug])
@@map("posts")
}
enum PostStatus {
DRAFT
PUBLISHED
ARCHIVED
}
// 分类模型
model Category {
id String @id @default(uuid())
name String @unique
slug String @unique
description String? @db.Text
icon String?
color String?
order Int @default(0)
// 关系
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id])
parentId String?
children Category[] @relation("CategoryHierarchy")
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([parentId])
@@index([slug])
@@map("categories")
}
// 标签模型
model Tag {
id String @id @default(uuid())
name String @unique
slug String @unique
color String?
posts PostTag[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([name])
@@index([slug])
@@map("tags")
}
// 文章-标签关联表
model PostTag {
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
postId String
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
tagId String
@@id([postId, tagId])
@@map("post_tags")
}
// 评论模型
model Comment {
id String @id @default(uuid())
content String @db.Text
// 关系
author User @relation(fields: [authorId], references: [id])
authorId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
postId String
parent Comment? @relation("CommentReplies", fields: [parentId], references: [id])
parentId String?
replies Comment[] @relation("CommentReplies")
// 状态和统计
status CommentStatus @default(PENDING)
likesCount Int @default(0)
// 时间戳
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([postId])
@@index([authorId])
@@index([parentId])
@@index([status])
@@map("comments")
}
enum CommentStatus {
PENDING
APPROVED
REJECTED
SPAM
}
// 关注关系模型
model Follow {
id String @id @default(uuid())
follower User @relation("UserFollowing", fields: [followerId], references: [id], onDelete: Cascade)
followerId String
following User @relation("UserFollowers", fields: [followingId], references: [id], onDelete: Cascade)
followingId String
createdAt DateTime @default(now())
@@unique([followerId, followingId])
@@index([followerId])
@@index([followingId])
@@map("follows")
}
// 点赞模型
model Like {
id String @id @default(uuid())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
commentId String?
createdAt DateTime @default(now())
@@unique([userId, commentId])
@@index([userId])
@@index([commentId])
@@map("likes")
}
// 用户动态模型
model Activity {
id String @id @default(uuid())
type ActivityType
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
data Json?
createdAt DateTime @default(now())
@@index([userId])
@@index([createdAt(sort: Desc)])
@@map("activities")
}
enum ActivityType {
POST_CREATED
POST_PUBLISHED
COMMENT_CREATED
USER_FOLLOWED
USER_LIKED
}
Schema設計亮點
Claude Code在Schema設計中展示了這些專業能力:
- 關係對映: 正確使用了一對一、一對多、多對多關係
- 索引最佳化: 在常用查詢欄位上新增索引
- 列舉型別: 使用列舉限制欄位值,提高資料完整性
- 時間戳: 自動管理createdAt和updatedAt
- 級聯刪除: 正確配置onDelete行為
- 唯一約束: 防止資料重複
- JSON欄位: 靈活儲存動態資料