AI Agent Python 学习路线
首页
  • Month 1 概览
  • Week 1 · Python 语法速成
  • Week 2-3 · FastAPI 实战
  • 进阶 · FastAPI 业务架构详解
  • 实战 · 会员管理系统(商业级标准)
  • Week 4 · AI / LLM 基础
  • Month 2 概览
  • Week 5-6 · LangChain / LangGraph
  • Week 7-8 · RAG 检索增强生成
  • Month 3 概览
  • Week 9-10 · 架构设计
  • Week 11 · 实现 + 调试
  • Week 12 · 部署 + 复盘
  • 基建 · 选型指南(SQLite/PG/MySQL/Redis/Nginx)
📚 资源 & 避坑
首页
  • Month 1 概览
  • Week 1 · Python 语法速成
  • Week 2-3 · FastAPI 实战
  • 进阶 · FastAPI 业务架构详解
  • 实战 · 会员管理系统(商业级标准)
  • Week 4 · AI / LLM 基础
  • Month 2 概览
  • Week 5-6 · LangChain / LangGraph
  • Week 7-8 · RAG 检索增强生成
  • Month 3 概览
  • Week 9-10 · 架构设计
  • Week 11 · 实现 + 调试
  • Week 12 · 部署 + 复盘
  • 基建 · 选型指南(SQLite/PG/MySQL/Redis/Nginx)
📚 资源 & 避坑

基础设施选型指南:SQLite / MySQL / PostgreSQL / Redis / Tengine(Nginx)

🎯 本篇目标:回答一个新手最常见的困惑——"我的项目什么时候需要引入这些组件?"

原则先行:不为简历堆技术,只为解决实际问题。每个组件都从"没有它会出什么问题"讲起,并标注它在 会员管理系统 演进路线中的位置。


1. 全景图:各组件的职责边界

用户请求
   │
   ▼
┌─────────────┐     ┌──────────────────────────────────┐
│ Tengine     │     │ FastAPI 应用                      │
│ (Nginx 系)  │────▶│  ├─ 业务逻辑                      │
│ 反向代理     │     │  ├─ 需要缓存/计数? ──────▶ Redis │
│ TLS/静态/限流│     │  └─ 需要持久化数据? ──▶ PostgreSQL│
└─────────────┘     └──────────────────────────────────┘
                     (MySQL 和 PostgreSQL 二选一)
组件一句话定位你不引入它的默认状态
SQLite零配置单文件数据库uvicorn + 一个 .db 文件就能跑(会员系统现状)
PostgreSQL功能最强的开源关系库,默认首选数据还在 SQLite 里
MySQL流行的开源关系库,生态成熟同上
Redis内存数据库:缓存/计数/分布式锁每次都查库,全靠数据库扛
Tengine(Nginx)反向代理服务器:TLS/静态/负载均衡uvicorn 裸奔对外,自己管 HTTPS

💡 TS 对照

Node 世界的对应关系:SQLite ≈ 低配版 Prisma+SQLite;PostgreSQL/MySQL ≈ 你连过的各种云数据库;Redis ≈ Express 里的 ioredis(session/缓存);Nginx ≈ 你部署 Node 应用时前面挡的那层(如果你用过宝塔,网站"反代"功能就是 Nginx)。


2. SQLite:起点,也是被低估的狠角色

什么时候用

  • ✅ 开发/测试环境(会员系统 P1-P5 全程)
  • ✅ 单机部署、写入 QPS < 100 的小系统(内部工具、个人项目、博客后台)
  • ✅ 嵌入式/本地应用(手机 App、桌面软件)
  • ✅ 大量读多写少的边缘场景(甚至一些生产站点就用 SQLite)

什么时候必须离开

信号原因
多实例部署SQLite 是单文件,多台机器不能共享同一文件
并发写入频繁整库一把写锁,database is locked 会反复出现
需要 SELECT FOR UPDATE 语义验证它的行锁语义和 PG/MySQL 不完全一致,测了也白测

💡 一个常见误区

"SQLite 不能生产使用"是过时结论。单机小系统它完全够格——真正让你换库的信号是多实例部署和并发写,而不是"上线"本身。


3. PostgreSQL vs MySQL:怎么选?

结论先行

没有明确理由时,选 PostgreSQL。 新项目 2024 年后的社区默认答案。

对比表

维度PostgreSQLMySQL
定位"功能的完全体",学术严谨"够用且快",互联网公司存量霸主
JSON 支持jsonb 类型可索引可查询(强项)JSON 类型存在但查询能力弱
复杂查询窗口函数/CTE/全文检索/数组类型都强简单查询性能优秀,复杂查询较弱
并发控制MVCC 实现更完善,FOR UPDATE SKIP LOCKED 等高级特性常用特性都有
生态现状PostGIS(地理)、pgvector(AI 向量检索)等扩展是杀手锏国内云厂商支持最广,DBA 好招
公司存量新创公司/外企主流国内大厂存量系统多

什么时候选 MySQL(真实理由,不是玄学)

  1. 团队/公司已有 MySQL 运维经验和监控体系
  2. 目标公司技术栈是 MySQL,为求职对齐
  3. 用阿里云 RDS 等,两个都支持 → 回到默认:选 PG

💡 和你 AI 学习路线的强关联

pgvector 是 Month 2 RAG 的隐藏考点:向量数据直接存 PostgreSQL 就能做小规模语义检索,不用单独部署 Milvus/Chroma。选 PG 等于给 AI 铺路。

引入时机(会员系统)

  • P1-P5:SQLite 够用
  • 演进步骤 ⑤(SaaS 化):换 PostgreSQL——因为多租户后需要真行锁 + pgvector + 更强的并发

4. Redis:什么时候才真的需要它?

判断标准:先问"数据库扛不住了吗?",再问"这个数据适合放内存吗?"

场景用 Redis 吗说明
缓存热点查询(套餐列表、行情价格)✅ 经典场景读多写少 + 能容忍短暂不一致
登录限流(同 IP 5 次/分钟)✅ 计数器 INCR + EXPIRE会员系统 P2 的限流,单机可以用内存 dict,多实例必须 Redis
JWT 注销黑名单✅ 带 TTL 的 keytoken 剩余有效期 = TTL,自动过期清理
幂等键存储✅ 天然适合SET idem:key value NX EX 86400
分布式锁(防并发下单)⚠️ 可以但慎重优先用数据库行锁(P4 教的 FOR UPDATE),锁的语义更可靠
Session 存储⚠️ 有 JWT 就不需要双 token 方案下无服务端 session
消息队列⚠️ 轻量场景用 Stream重度任务队列以后学 RabbitMQ/Kafka

引入信号(满足任一)

  1. 多实例部署:限流/黑名单/幂等键存在"进程内存"里时,实例之间不共享 → 必须 Redis
  2. 数据库出现可观测的读压力:慢查询日志出现高频重复 SELECT
  3. 需要 TTL 语义的数据(验证码、防重放 nonce)

反模式(新手最容易犯)

# ❌ 反例:什么都往 Redis 塞,数据库成了"归档库"
# 会员档案、订单流水这种强一致、要关联查询的数据 → 永远在关系库
# Redis 只放"丢了也不心疼/能重建"的数据
cache.set(f"plan:{plan_id}", plan, ex=300)   # ✅ 5 分钟缓存,过期回源

💡 会员系统里的 Redis 位置

文档 §5 安全清单里的"注销黑名单"和 §4.3 的幂等键,单机版用 SQLite 表实现即可;演进步骤④(多实例)时迁到 Redis,接口不用变——这就是 service 层封装的价值。


5. Tengine(Nginx):uvicorn 前面为什么必须挡一层?

先说清楚关系:Tengine 是阿里巴巴基于 Nginx 的分支,用法心智完全一致。uvicorn 是应用服务器,不是为直接暴露公网设计的。

Nginx/Tengine 承担的四件事

职责没有它会怎样
TLS 终结(HTTPS 证书)uvicorn 自己配证书很别扭,且证书续期要重启应用
静态文件(Swagger、未来前端 dist)让 Python 进程送静态文件 = 浪费(Node 圈同理:不用 express 送 build 产物)
反向代理 + 负载均衡proxy_pass http://127.0.0.1:8000;未来多实例 upstream 轮询
安全缓冲隐藏后端细节、限速、大请求体拦截、超时控制

最小可用配置(会员系统部署用)

server {
    listen 443 ssl;
    server_name api.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/xxx/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;

    # 限流:商业标准的登录保护(配合应用内 slowapi)
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

    location /api/ {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header X-Real-IP $remote_addr;          # ★ 审计日志记录真实 IP
        proxy_set_header X-Request-ID $request_id;        # ★ 链路追踪贯穿全链路
        proxy_read_timeout 60s;
    }

    location /docs { deny all; }                          # prod 禁 Swagger
}

💡 引入信号

第一个公网用户出现的那天。开发期 localhost 直连 uvicorn 没问题;上线 = uvicorn 只绑 127.0.0.1,Nginx 对外。这是商业部署的铁律(对照部署篇 Dockerfile 里 --host 0.0.0.0 是容器内、Nginx 在容器外的拓扑)。


6. "等"字辈:提前认识的其它成员

组件解决什么问题什么时候轮到它
Elasticsearch全文搜索、复杂多条件检索会员搜索从"LIKE 模糊查"进化到"分词/拼音/多字段权重"时。小规模 PG 全文检索可顶很久
MongoDB文档模型、schema 灵活数据结构真的不定型时(如 Agent 的对话轨迹快照)。别拿"不想建表"当理由
RabbitMQ / Kafka异步任务、削峰、事件广播发短信/生成报表不想阻塞接口时;Kafka 面向高吞吐日志流。起步用 FastAPI BackgroundTasks + Redis Stream
MinIO / OSS对象存储(文件)会员头像/合同扫描件。云上直接用 OSS/COS
Cron / Celery定时任务到期提醒从"接口查"变成"每天 9 点主动推"时。轻量先 APScheduler

💡 每个都遵循同一条铁律:先有痛,再引入。简历上写"用过"很容易被追问穿透,写"因为 X 问题引入 Y,解决了 Z"才立得住。


7. 决策速查卡(贴显示器系列)

需要存"必须不丢"的业务数据吗?
 ├─ 是 → 关系型数据库
 │    ├─ 单机小系统起步 → SQLite
 │    └─ 多实例/AI向量/复杂查询 → PostgreSQL(默认)
 │                                    └─ 公司存量是 MySQL → MySQL
 ├─ 数据丢了能重建 + 读多写少/带过期时间?
 │    └─ 是 → Redis
 └─ 全文搜索/文件/异步任务?
      → 先用 PG/MinIO/BackgroundTasks 顶着,痛了再上专门组件

要暴露到公网吗?
 └─ 是 → Nginx/Tengine 挡在 uvicorn 前面(TLS + 反代 + 限流)

8. 会员系统全演进路线(组件视角汇总)

阶段组件变化触发信号
P1-P5(现在)SQLite + uvicorn 裸跑—
上线 v1+ Tengine(Nginx) TLS/反代第一个公网用户
SaaS ①②③SQLite → PostgreSQL多实例部署 + pgvector 需求
SaaS ④+ Redis(黑名单/幂等键/限流迁过去)多实例内存不共享
成长期+ Celery 定时任务、ES 搜索(视痛感)到期提醒要主动推送;搜索要分词

🔗 本篇与 Month 3 部署篇 的关系:部署篇教"怎么把容器跑起来",本篇教"跑起来之前每个组件该不该存在"。