Database Design
Clear Notes 博客系统数据库表结构
根据当前前端页面的文章列表、精选内容、专题集合、订阅表单和未来博客后台需求,设计以下关系型数据库结构。
Overview
模块划分
内容管理
文章、分类、标签、专题、媒体资源,支撑首页文章列表、精选卡片和专题展示。
用户与权限
作者、管理员和登录身份管理,方便后续扩展后台发布、编辑、审核能力。
互动与订阅
评论、浏览量、点赞、邮件订阅,承接当前订阅表单和未来文章互动。
站点配置
导航、首页区块、SEO 配置等可运营内容,减少硬编码。
Tables
全部表结构
用户与作者
users
保存后台用户、作者资料和登录身份。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 用户 ID |
| username | VARCHAR(50) | UNIQUE, NOT NULL | 登录账号 |
| display_name | VARCHAR(80) | NOT NULL | 页面展示名称 |
| VARCHAR(120) | UNIQUE, NOT NULL | 邮箱 | |
| password_hash | VARCHAR(255) | NOT NULL | 加密后的密码 |
| avatar_url | VARCHAR(255) | NULL | 头像地址 |
| bio | VARCHAR(500) | NULL | 作者简介 |
| role | ENUM('admin','editor','author') | DEFAULT 'author' | 用户角色 |
| status | ENUM('active','disabled') | DEFAULT 'active' | 账号状态 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
文章主体
posts
保存博客文章正文、摘要、发布状态和首页展示所需信息。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 文章 ID |
| author_id | BIGINT UNSIGNED | FK users(id), NOT NULL | 作者 ID |
| category_id | BIGINT UNSIGNED | FK categories(id) | 主分类 ID |
| cover_media_id | BIGINT UNSIGNED | FK media_assets(id), NULL | 封面资源 |
| title | VARCHAR(180) | NOT NULL | 文章标题 |
| slug | VARCHAR(200) | UNIQUE, NOT NULL | 文章 URL 标识 |
| excerpt | VARCHAR(500) | NULL | 文章摘要 |
| content | LONGTEXT | NOT NULL | 文章正文 |
| content_format | ENUM('html','markdown') | DEFAULT 'markdown' | 正文格式 |
| status | ENUM('draft','published','archived') | DEFAULT 'draft' | 发布状态 |
| is_featured | BOOLEAN | DEFAULT FALSE | 是否精选 |
| featured_label | VARCHAR(40) | NULL | 精选卡片标签 |
| reading_minutes | SMALLINT UNSIGNED | DEFAULT 1 | 预计阅读分钟 |
| published_at | DATETIME | NULL, INDEX | 发布时间 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
分类
categories
对应前端文章元信息中的 CSS、JavaScript、复盘等分类。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 分类 ID |
| name | VARCHAR(60) | UNIQUE, NOT NULL | 分类名称 |
| slug | VARCHAR(80) | UNIQUE, NOT NULL | URL 标识 |
| description | VARCHAR(255) | NULL | 分类描述 |
| sort_order | INT | DEFAULT 0 | 排序值 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
标签
tags
用于为文章增加更细粒度的检索维度。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 标签 ID |
| name | VARCHAR(60) | UNIQUE, NOT NULL | 标签名称 |
| slug | VARCHAR(80) | UNIQUE, NOT NULL | URL 标识 |
| color | CHAR(7) | NULL | 标签颜色,如 #2f6fbb |
| created_at | DATETIME | NOT NULL | 创建时间 |
文章标签关系
post_tags
文章与标签的多对多关系表。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| post_id | BIGINT UNSIGNED | PK, FK posts(id) | 文章 ID |
| tag_id | BIGINT UNSIGNED | PK, FK tags(id) | 标签 ID |
| created_at | DATETIME | NOT NULL | 关联时间 |
专题集合
collections
对应首页“前端基础、页面练习、学习复盘”等专题卡片。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 专题 ID |
| title | VARCHAR(100) | NOT NULL | 专题标题 |
| slug | VARCHAR(120) | UNIQUE, NOT NULL | URL 标识 |
| summary | VARCHAR(300) | NULL | 专题简介 |
| display_no | VARCHAR(8) | NULL | 前端显示编号,如 01 |
| cover_media_id | BIGINT UNSIGNED | FK media_assets(id), NULL | 封面资源 |
| sort_order | INT | DEFAULT 0 | 排序值 |
| is_visible | BOOLEAN | DEFAULT TRUE | 是否展示 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
专题文章关系
collection_posts
管理专题中包含哪些文章以及文章在专题内的顺序。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| collection_id | BIGINT UNSIGNED | PK, FK collections(id) | 专题 ID |
| post_id | BIGINT UNSIGNED | PK, FK posts(id) | 文章 ID |
| sort_order | INT | DEFAULT 0 | 专题内排序 |
| created_at | DATETIME | NOT NULL | 加入时间 |
媒体资源
media_assets
保存文章封面、头像、专题图等文件资源。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 资源 ID |
| uploader_id | BIGINT UNSIGNED | FK users(id), NULL | 上传者 |
| file_url | VARCHAR(255) | NOT NULL | 文件地址 |
| file_name | VARCHAR(160) | NOT NULL | 文件名 |
| mime_type | VARCHAR(80) | NOT NULL | 文件 MIME 类型 |
| file_size | INT UNSIGNED | NULL | 文件大小,单位 byte |
| alt_text | VARCHAR(180) | NULL | 图片替代文本 |
| created_at | DATETIME | NOT NULL | 上传时间 |
评论
comments
为后续文章详情页增加评论与回复能力。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 评论 ID |
| post_id | BIGINT UNSIGNED | FK posts(id), NOT NULL | 文章 ID |
| parent_id | BIGINT UNSIGNED | FK comments(id), NULL | 父评论 ID |
| user_id | BIGINT UNSIGNED | FK users(id), NULL | 登录用户 ID |
| guest_name | VARCHAR(80) | NULL | 访客昵称 |
| guest_email | VARCHAR(120) | NULL | 访客邮箱 |
| content | TEXT | NOT NULL | 评论内容 |
| status | ENUM('pending','approved','spam') | DEFAULT 'pending' | 审核状态 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
订阅
newsletter_subscribers
承接当前页面底部邮箱订阅表单。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 订阅 ID |
| VARCHAR(120) | UNIQUE, NOT NULL | 订阅邮箱 | |
| status | ENUM('subscribed','unsubscribed') | DEFAULT 'subscribed' | 订阅状态 |
| source | VARCHAR(80) | DEFAULT 'home_newsletter' | 订阅来源 |
| confirmed_at | DATETIME | NULL | 确认订阅时间 |
| created_at | DATETIME | NOT NULL | 提交时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
文章统计
post_stats
独立保存浏览、点赞、评论数,避免高频统计直接写文章主表。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| post_id | BIGINT UNSIGNED | PK, FK posts(id) | 文章 ID |
| view_count | INT UNSIGNED | DEFAULT 0 | 浏览数 |
| like_count | INT UNSIGNED | DEFAULT 0 | 点赞数 |
| comment_count | INT UNSIGNED | DEFAULT 0 | 评论数 |
| last_viewed_at | DATETIME | NULL | 最近浏览时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
站点配置
site_settings
保存站点标题、SEO、首页文案和其他可运营配置。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT UNSIGNED | PK, AUTO_INCREMENT | 配置 ID |
| setting_key | VARCHAR(100) | UNIQUE, NOT NULL | 配置键 |
| setting_value | JSON | NOT NULL | 配置值 |
| description | VARCHAR(255) | NULL | 配置说明 |
| updated_by | BIGINT UNSIGNED | FK users(id), NULL | 最后修改人 |
| created_at | DATETIME | NOT NULL | 创建时间 |
| updated_at | DATETIME | NOT NULL | 更新时间 |
Relations
主要关系
- users 1 - N posts:一个作者可以发布多篇文章。
- categories 1 - N posts:一个分类下可以有多篇文章。
- posts N - N tags:通过 post_tags 关联。
- collections N - N posts:通过 collection_posts 关联。
- posts 1 - N comments:一篇文章可以有多条评论。
- posts 1 - 1 post_stats:每篇文章对应一条统计记录。