用 Redis 当数据库?Next.js 笔记系统的数据层设计

用 Redis 当数据库?Next.js 笔记系统的数据层设计

别人都用 MySQL,这个项目却拿 Redis 存笔记。聊聊 NOSQL 的取舍、hash 类型的妙用,以及 Redis + MySQL 的经典缓存思路。

一、为什么敢用 Redis 存数据

传统认知里,Redis 只是「缓存」,真正的数据要落 MySQL。但这个笔记系统,直接让 Redis 顶上了「数据库」的位置。

先搞清楚 Redis 是什么:

  • NOSQL:没有数据表,不是关系型,不用写 SQL,也不用 ORM 驱动
  • key:value :内存数据库,像 localStorage 一样直接 key:value 开搞
  • 跑在内存:默认端口 6379,读写速度极快

对于「个人笔记」这种量级不大、结构简单、又不强依赖关系查询的场景,Redis 完全够用,还省去了建表、写 SQL、配连接池的一大堆心智负担。

二、hash 类型:天然适合存「对象」

Redis 厉害的地方在于,它对不同类型的数据有优化的存储方式 。除了最基础的字符串 get/set,还有 hash 类型 hget/hset,正好用来存笔记对象。

一条笔记长这样:

JSON

json 复制代码
{
  "title": "sunt aut",
  "content": "quia et suscipit suscipit recusandae",
  "updateTime": "2023-12-13T09:19:48.837Z"
}

结构是「一个 id 对应一个对象」,用 Redis hash 存再合适不过:

  • key = notes(所有笔记的集合)
  • field = 笔记的 id(如 1702459181837
  • value = 序列化后的笔记 JSON 字符串

对应关系一目了然:

概念 Redis hash
整个笔记集合 notes 这个 key
单条笔记 id field
笔记内容 value(JSON 字符串)

三、数据服务层:lib 目录

Next.js 约定,数据业务逻辑统一放在 lib 目录 。这里我们写了一个 lib/redis.js

js

javascript 复制代码
import Redis from 'ioredis';

const redis = new Redis(); // 默认连本地 6379

// 初始数据(首次运行时 seed 进去)
const initialData = {
  "1702459181837": '{"title":"sunt aut",...}',
  "1702459182837": '{"title":"qui est",...}',
  "1702459188837": '{"title":"ea molestias",...}'
}

export async function getAllNotes() {
  // hash 数据类型:一次性取出所有笔记
  const data = await redis.hgetall('notes');
  // 首次为空,写入 seed 数据
  if (Object.keys(data).length == 0) {
    await redis.hset("notes", initialData);
  }
  return await redis.hgetall("notes");
}

几个细节:

  1. ioredis 是 Node 的 Redis 客户端,相当于「驱动」,帮我们跟 Redis 通信
  2. hgetall('notes') 直接拿到整个 hash,返回一个 { field: value } 的对象
  3. 空数据时自动 seed,保证首次运行就有内容可看

getAllNotes 这个函数,被 Sidebar 组件在服务端 await 调用(还记得第一篇的 RSC 吗),数据就从 Redis 一路流到了页面。

四、Redis + MySQL:经典缓存套路

虽然本项目「只用 Redis」,但 Redis 更常见的定位是站在 MySQL 前面做缓存,解决数据库读写的 I/O 瓶颈。

想象掘金首页的文章列表:

  • 文章列表几分钟内基本不变
  • 如果每个用户访问都去查 MySQL,数据库压力巨大
  • 而 Redis 是内存操作,速度快几个数量级

于是有了经典流程:

vbnet 复制代码
第一个用户访问
  → 查 MySQL 拿到 posts 列表
  → 序列化成 key:value 存进 Redis
  → 返回数据

后续用户访问
  → 直接读 Redis
  → 命中缓存,返回数据(不再碰 MySQL)

这就是「缓存穿透前先缓存」的思路------热点数据放 Redis,冷数据/持久化靠 MySQL。理解了这套逻辑,也就理解了 Redis 在企业级架构里的真正价值。

五、这个设计还能怎么扩展

当前 lib/redis.js 只实现了「查全部」,但基于 hash 类型,CRUD 顺手就能补齐:

js

javascript 复制代码
// 新增/更新一条
await redis.hset('notes', id, JSON.stringify(note));

// 删除一条
await redis.hdel('notes', id);

// 查单条
const note = await redis.hget('notes', id);

配合第一篇的路由设计:

  • 新增 → POST /note/edithset
  • 编辑 → POST /note/edit/[id]hset
  • 删除 → hdel
  • 详情 → GET /note/[id]hget

搜索功能则可以在服务端 hgetall 后,对标题/内容做关键字过滤,逻辑简单直接。

总结

这篇文章我们看清了数据层的取舍:

  1. NOSQL 的定位:结构简单、量级可控的场景,Redis 完全能独当一面
  2. hash 类型:天生适合「id → 对象」这种存储结构
  3. 数据服务层 :集中在 lib,被服务端组件直接调用
  4. 缓存思想:Redis + MySQL 是处理高并发读的黄金搭档

技术选型从来不是「越重越好」,而是「刚好够用」。一个个人笔记系统,用 Redis 既轻量又优雅,还能顺手把缓存思想吃透------这就是小而美项目的价值。

相关推荐
名字还没想好☜3 天前
React 文件上传实战:预览 URL 回收、多文件逐个进度与拖拽放置区踩坑
前端·react·next.js
moMo13 天前
NestJS 入门:用"模块化 + 装饰器"读懂大型后端框架
next.js
天道kabuto14 天前
前端每日知识点:Next.js 渲染与缓存:从 Pages Router 到 Cache Components 的范式迁移
next.js
名字还没想好☜16 天前
React 实现暗黑模式切换:localStorage 持久化、SSR 首屏闪烁与跟随系统主题
前端·javascript·react.js·ecmascript·react·next.js
Linguwen17 天前
AI外贸建站04|三个账号第一次联动:让Codex写一个网页,从生成到上线走完整条流水线
next.js·外贸独立站·企业官网·外贸建站·ai建站
Linguwen17 天前
AI外贸建站03|建站三件套:GitHub、Next.js、Codex各干什么,为什么别再用模板建站
next.js·外贸独立站·企业官网·外贸建站·ai建站
古夕19 天前
my-first-ai-web_学习记录05——NextAuth Adapter 存储用户信息
typescript·全栈·next.js
10年前端老司机19 天前
别卷CRUD了!前端用Next.js+LangChain.js,低成本冲进AI高薪赛道
前端·langchain·next.js
为你学会写情书21 天前
Next.js 16 全栈实战:从零搭一个 Markdown 笔记系统
next.js