用 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 既轻量又优雅,还能顺手把缓存思想吃透------这就是小而美项目的价值。

相关推荐
为你学会写情书34 分钟前
Next.js 16 全栈实战:从零搭一个 Markdown 笔记系统
next.js
Asize2 天前
框架的说明书是写给 AI 看的:我用 Next.js 搭了个博客
人工智能·代码规范·next.js
触底反弹5 天前
🚀 Next.js 全栈项目数据库连接实战:Drizzle ORM + Supabase 从零到跑通
postgresql·orm·next.js
YIAN6 天前
Next.js App Router 全栈实战:从 0 到 1 写一个 Todo 应用,前端后端一个项目搞定
前端·全栈·next.js
进哥AI研习社6 天前
图片优化全链路——AVIF/WebP 自适应与懒加载策略
next.js·图片优化·懒加载·avif·lcp·模糊占位·cdn 加速
Darling噜啦啦6 天前
从零搭建单词管理系统:Next.js + Supabase + Drizzle ORM 全栈实战
数据库·orm·next.js
阿黎梨梨6 天前
搭建一个单词管理后台:Next.js + Supabase + Drizzle
数据库·next.js
柒和远方6 天前
V077:Next.js 后台的认证与权限防线:首个超级管理员的事务锁初始化、会话令牌哈希,与四道管理员保护规则
orm·next.js
半个落月6 天前
Next.js 16 笔记应用实战:Redis 数据链路与组件两版拆分详解
前端·redis·next.js