📄 一句话概括
缓存=把常用的查询结果抄在「近处的小本本」上:下次同样的请求不再打扰数据库——代价是小本本会过期。
📝 本节和前面几节的关系
索引(7-7)让查询快了一个量级,但当访问量大到「每次都查数据库也嫌多」时,下一招是把结果本身存到更快的存储(内存)里。本节也是全章「应用程序视角」的性能压轴:数据库已经很快,但不查才是最快。
一、缓存怎么工作
请求来了 → 先查缓存(内存,微秒级)
├─ 命中(有)→ 直接返回,数据库毫发无损
└─ 未命中(没有)→ 查数据库 → 结果写入缓存 → 返回
(并设过期时间 TTL)
- 代表工具:Redis、Memcached(内存键值库——2-6 键值模型的明星应用)
- 典型缓存对象:首页热榜、商品详情、站点设置——读多写少的数据
二、缓存的三个麻烦
- 一致性:数据库改了,缓存还是旧值——策略:更新时同时删缓存(下次未命中自动回源刷新)
- 过期时间(TTL):给每条缓存定寿命,到期自动作废
- 缓存穿透/雪崩:查不存在的 key 每次都打到数据库;大量 key 同时过期瞬间压垮库——设空值缓存、过期时间加随机
三、动手 Demo:手工缓存一笔查询
# 在线 Python 运行器:用字典当「迷你 Redis」
cache = {} # 内存小本本
TTL = 60 # 缓存 60 秒
def get_hot_books(db):
key = "hot_books"
if key in cache: # 命中:不打扰数据库
return cache[key]
result = db.query("SELECT * FROM books ORDER BY score DESC LIMIT 10")
cache[key] = result # 回源后写入缓存
return result
# 第一次调用:查库(慢) → 第二次:直接命中(快)
# 数据库里的 score 更新时 → cache.pop(key) 删缓存,保持一致
【准备块】在线 Python 运行器;db.query 用假函数示意即可。
四、30 秒实验
数一数你一天查了多少次「天气」——如果天气 App 每次都问气象台,气象台早被挤爆了。App 缓存 10 分钟的预报,就是 8-6 的全部思想:10 分钟内,所有人共享一个答案。
五、常见误区
- 「缓存了就不用管数据库」:缓存只是挡住「重复的读」;写操作永远走数据库,且要记得同步失效缓存
- 「缓存越久越好」:TTL 越长,用户看到旧数据的窗口越大——缓存的本质是「用一点旧换很多快」
- 「什么都能缓存」:余额、库存这类实时性敏感的数据慎缓存——显示错误比慢更糟
自测三问
1. 缓存的读写路径?(先查缓存,命中直接返回;未命中查库并回填+设 TTL) 2. 数据更新后如何保持缓存一致?(更新时同时删除对应缓存,下次读自动回源刷新) 3. 哪类数据不适合长 TTL 缓存?(余额、库存等实时敏感数据——旧值的代价大于慢)- ☐ 下一节(8-7 大数据-收集和分析大量数据)
相关笔记
- 索引-缩短获取数据的时间 — 性能第一招;缓存是索引之后的第二招
- 键值类型、面向列型-NoSQL数据库的种类1-键与值的组合模型 — Redis 正是键值模型的明星
- 大数据-收集和分析大量数据 — 下一节:数据不只是「存」,还要「用」
- 🗄️ 数据库基础 · 索引 — 全课路线图