Back to archive
|5 min read

SmartNote 数据库设计:从 user、note 到 note_tag

梳理 SmartNote 项目的核心表结构设计,并说明这些表之间的关系以及为什么这样设计。

MySQL项目实战数据库设计

在 SmartNote 项目中,我先从数据库设计入手,因为后端项目很多业务边界其实都体现在表结构里。

项目核心表#

当前版本我设计了 5 张核心表:

  • user
  • note
  • tag
  • note_tag
  • favorite

这 5 张表基本能支撑当前阶段的主要业务。

user 表#

用户表主要负责保存注册用户信息。

CREATE TABLE user (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(100) NOT NULL,
  email VARCHAR(100),
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
  update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
设计思路
id 作为主键,方便后续和其他表做关联
username、password、email 支撑注册登录场景
create_time、update_time 是常规审计字段,后续很多业务表都应该保留
note 表
笔记表是整个项目里最核心的一张表。

CREATE TABLE note (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  title VARCHAR(200) NOT NULL,
  content TEXT,
  is_deleted TINYINT DEFAULT 0,
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
  update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
设计思路
user_id 表示这篇笔记属于哪个用户
title 和 content 是核心内容字段
is_deleted 用于逻辑删除,避免直接物理删除数据
时间字段方便做排序、统计和后续数据追踪
表关系
一个用户可以有多篇笔记,所以这里是:

user 和 note:一对多
tag 表
标签表负责存放标签信息。

CREATE TABLE tag (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
设计思路
标签本身结构很简单,重点不是字段多,而是后面和笔记之间的关系设计。

note_tag 表
笔记和标签之间是多对多关系,所以需要中间表。

CREATE TABLE note_tag (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  note_id BIGINT NOT NULL,
  tag_id BIGINT NOT NULL
);
为什么必须用中间表
因为一篇笔记可以绑定多个标签,一个标签也可以对应多篇笔记。

比如:

一篇笔记可以同时属于 Java、Spring Boot、项目实战
一个 Redis 标签也可能被很多笔记复用
因此:

note 和 tag:多对多
通过 note_tag 建立关联
这也是面试里经常会问到的一个设计点。

favorite 表
收藏表用来表示用户和笔记之间的收藏关系。

CREATE TABLE favorite (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  note_id BIGINT NOT NULL,
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
设计思路
收藏本质上也是一种关联关系:

一个用户可以收藏多篇笔记
一篇笔记也可以被多个用户收藏
所以这里实际上也是一种多对多场景,只不过我单独抽成了业务表。

当前设计的几个特点
1. 先满足核心功能
这个阶段的设计重点不是追求复杂,而是先把项目主流程跑通:

注册登录
笔记管理
标签分类
搜索
收藏
2. 保留后续扩展空间
虽然现在表结构不复杂,但已经为后续功能留出了空间,比如:

浏览量字段
热门笔记排序
搜索历史记录
逻辑删除扩展
用户信息补充
3. 适合单体和微服务两个版本
当前这些表结构既适合单体版,也方便后面拆微服务。

例如:

user 表可以归到 user-service
note、tag、note_tag、favorite 可以归到 note-service
所以前期表结构设计如果比较清晰,后期做服务拆分也会更顺。

我在设计时最注意的点
现阶段我特别注意三件事:

关系是否清晰
字段是否足够支撑业务
后面做接口时是否方便
因为数据库设计不是为了“看起来专业”,而是为了让后面的 Controller、Service、Mapper 都能顺着这个结构自然写下去。

结语
对 SmartNote 来说,这套数据库设计不是终点,而是后续所有接口开发的基础。下一步我会继续把这些表映射到实体类,并逐步完成注册登录、笔记 CRUD、标签绑定和搜索功能。