用Flutter做背单词APP-02我画了设计稿,然后让AI帮我设计了数据库(顺便聊了会天)

作者:雪隐_上班了

本文欢迎分享、聚合讨论,但不接受整篇搬运。圈子不大,写文不易,急用可联系授权。


上集回顾

上回说到,我搞定了服务器方案------用树莓派给自己搭了个"丐中丐私有云",电费一个月6毛钱,比云厂商便宜到姥姥家了。

但服务器只是地基,房子长啥样还没谱呢。

于是这一篇,咱们聊设计稿和数据库。


设计稿:我真的画了,虽然丑

你可能会问:上回你不是说AI帮你生成了设计稿吗?直接用不就完了?

我的回答是:AI生成的那玩意儿,叫"灵感草图",不叫"设计稿"。

它给了我一个方向,但真要照着做,那App长出来估计跟"买家秀"似的------不能说丑,只能说"AI尽力了"。

所以我还是老老实实拿起了笔。

对,就是那种写在纸上会留下痕迹的笔,

不是Apple Pencil,就是2块钱一支的晨光中性笔。

我按照《Refactoring UI》这本书的思路,先在纸上画草稿。

这本书AI帮我浓缩成了500字,我喝杯咖啡的功夫就"读完"了。

(AI:你这叫读?你这叫瞟。)

但不得不说,纸上画草稿这事儿,真有用

你在脑子里构思的时候,觉得"嗯,这个功能得有,那个也得有,全都安排上"。

一旦落到纸面上,你会发现:

  • 这个按钮放哪儿都不对劲
  • 那个页面根本不需要
  • 这个功能跟那个功能打架了
  • 我到底是想做背单词App还是想做社交软件?

草稿的作用,就是把脑子里的"我觉得挺好"变成纸上的"这什么玩意儿"。

这个过程很痛苦,但很值得。

然后我打开Figma,一个画面一个画面地画。

不能说多好看,但至少比AI生成的那个"赛博坦拼贴画"强了那么一点点。


有了设计稿,下一步:数据库怎么搞?

这时候就得请出我们的老朋友------AI

我把设计稿截图发给AI,说:

"帮我设计数据库,这是画面,你看着办。"

AI吐出了一堆表结构。

然后我又问:

"这个数据你为什么这么放?那个字段为什么在那个表里?"

就这样聊了几个来回。

这感觉就像你在跟一个话多但靠谱的同事讨论需求,

他给你提方案,你质疑他,他解释,你再质疑,他再解释......

聊着聊着,你俩就把事儿给定下来了。

聊的过程中,你会发现很多"当时没想到"的问题。

比如:

  • 某个字段放在A表还是B表?
  • 用户背完的单词怎么记录?
  • 复习计划怎么安排?

这些问题如果等到写代码的时候再想,那就等着"返工三连"吧。

所以这一步,尽量多花点功夫。

后面改也不是不行,但改起来就像在行驶的车上换轮胎------能换,但容易翻车。


数据库设计:7张表,一个背单词宇宙

聊完之后,AI给我生成了这套数据库设计。

一共7张表,基本覆盖了一个背单词App的核心功能。

咱一张一张来看(不感兴趣的可以跳过,但最好别跳,万一你以后也要做呢):


1. users --- 用户表

sql 复制代码
CREATE TABLE users (
  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nickname    VARCHAR(50)  NOT NULL DEFAULT '' COMMENT '昵称',
  avatar      VARCHAR(500) NULL COMMENT '头像 URL',
  created_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '用户表';

极简风,没密码没邮箱------因为我是用手机号一键登录的,后面再加。

头像URL留了500个字符,够你存个高清无码大头照了。


2. words --- 单词库

sql 复制代码
CREATE TABLE words (
  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  word        VARCHAR(200)  NOT NULL COMMENT '单词/词组/句型',
  phonetic    VARCHAR(200)  NULL COMMENT '音标',
  pos         VARCHAR(20)   NULL COMMENT '词性/phrase/pattern',
  definition  TEXT          NOT NULL COMMENT '释义',
  example     TEXT          NULL COMMENT '例句',
  audio_url   VARCHAR(500)  NULL COMMENT '音频 URL',
  type        VARCHAR(20)   NOT NULL DEFAULT 'word' COMMENT '类型: word/phrase/pattern',
  is_custom   TINYINT(1)   NOT NULL DEFAULT 0 COMMENT '是否用户自定义',
  created_at  DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_word_pos (word, pos),
  INDEX idx_word (word)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '单词库';

核心中的核心。

注意type字段------我不光要背单词,还要背词组和句型。

这就是我当初吐槽"市面上App没这功能"的原因,

现在我自己设计,想加什么加什么。

百词斩:我们没有词组功能哦~

我:好的,那我自己做一个。

百词斩:???

is_custom表示"这个单词是不是用户自己加的",

系统词库导入的是0,用户手搓的是1。


3. wordbooks --- 单词本

sql 复制代码
CREATE TABLE wordbooks (
  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id     BIGINT UNSIGNED NOT NULL COMMENT '所属用户',
  name        VARCHAR(100)  NOT NULL COMMENT '单词本名称',
  description VARCHAR(500)  NULL COMMENT '描述',
  created_at  DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  INDEX idx_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '单词本';

每个用户可以建N个单词本,

比如"四级高频"、"考研核心"、"工作中遇到的奇葩词"......


4. wordbook_words --- 单词本与单词的关联表

sql 复制代码
CREATE TABLE wordbook_words (
  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  wordbook_id BIGINT UNSIGNED NOT NULL COMMENT '单词本 ID',
  word_id     BIGINT UNSIGNED NOT NULL COMMENT '单词 ID',
  added_at    DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (wordbook_id) REFERENCES wordbooks(id) ON DELETE CASCADE,
  FOREIGN KEY (word_id)     REFERENCES words(id)     ON DELETE CASCADE,
  UNIQUE KEY uk_wordbook_word (wordbook_id, word_id),
  INDEX idx_wordbook_id (wordbook_id),
  INDEX idx_word_id (word_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '单词本单词关联';

多对多关系,一个单词本能装N个单词,一个单词也能属于N个单词本。

中间表,老套路了。


5. user_word_progress --- 用户单词学习进度

这张表是最复杂的,也是整个App的灵魂所在

sql 复制代码
CREATE TABLE user_word_progress (
  id              BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id         BIGINT UNSIGNED NOT NULL COMMENT '用户 ID',
  word_id         BIGINT UNSIGNED NOT NULL COMMENT '单词 ID',
  status          TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态: 0未学/1学习中/2已掌握',
  is_simple       TINYINT(1)      NOT NULL DEFAULT 0 COMMENT '是否标记为简单词',
  correct_streak     INT UNSIGNED    NOT NULL DEFAULT 0 COMMENT '连续答对次数',
  easiness_factor    DECIMAL(3,2)  NOT NULL DEFAULT 2.50 COMMENT 'SM-2 容易度系数,最小1.3',
  review_times       INT UNSIGNED  NOT NULL DEFAULT 0 COMMENT 'SM-2 成功复习次数(答错重置)',
  last_interval_days INT UNSIGNED  NOT NULL DEFAULT 0 COMMENT 'SM-2 上次复习间隔天数',
  next_review_at     DATETIME      NULL COMMENT '下次复习时间',
  source             VARCHAR(20)  NOT NULL DEFAULT 'new' COMMENT '来源: new/review/simple',
  mastered_at        DATETIME      NULL COMMENT '掌握时间',
  review_count       INT UNSIGNED  NOT NULL DEFAULT 0 COMMENT '复习次数(含答错)',
  last_reviewed_at DATETIME       NULL COMMENT '上次复习时间',
  created_at      DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at      DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE,
  UNIQUE KEY uk_user_word (user_id, word_id),
  INDEX idx_user_id (user_id),
  INDEX idx_word_id (word_id),
  INDEX idx_status (status),
  INDEX idx_next_review (next_review_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '用户单词学习进度';

看到easiness_factorcorrect_streakreview_times这些字段没?

这是 SM-2算法 的标配。

SM-2算法是什么?

简单说,就是一种"根据你答对答错动态调整复习间隔"的算法。

你答对了,下次复习间隔变长;答错了,间隔缩短。

所有牛逼的背单词App背后都有它。

你要问我为什么不用更高级的SM-4、SM-5?

因为SM-2我勉强能看懂,

SM-4的论文我看了三遍,然后决定:还是SM-2吧,人要对自己诚实。


6. daily_records --- 每日学习记录

sql 复制代码
CREATE TABLE daily_records (
  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id     BIGINT UNSIGNED NOT NULL COMMENT '用户 ID',
  record_date DATE            NOT NULL COMMENT '记录日期',
  learned_count INT UNSIGNED  NOT NULL DEFAULT 0 COMMENT '今日已学单词数',
  created_at  DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  UNIQUE KEY uk_user_date (user_id, record_date),
  INDEX idx_user_id (user_id),
  INDEX idx_record_date (record_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '每日学习记录';

用来统计"今天背了多少个",

方便做打卡、热力图、以及"你今天又没背单词"的推送提醒。


7. user_settings --- 用户设置

sql 复制代码
CREATE TABLE user_settings (
  id                    BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id               BIGINT UNSIGNED NOT NULL COMMENT '用户 ID',
  wordbook_id           BIGINT UNSIGNED NULL COMMENT '指定的默写单词本',
  daily_goal            INT UNSIGNED NOT NULL DEFAULT 20  COMMENT '每日目标单词数',
  wrong_review_times    INT UNSIGNED NOT NULL DEFAULT 5    COMMENT '错词复习次数',
  new_words_per_day     INT UNSIGNED NOT NULL DEFAULT 10  COMMENT '每日新词数量',
  review_interval       INT UNSIGNED NOT NULL DEFAULT 1    COMMENT '复习间隔(天)',
  theme                 VARCHAR(20)  NOT NULL DEFAULT 'light' COMMENT '主题: light / dark / auto',
  notification_enabled  TINYINT(1)  NOT NULL DEFAULT 1    COMMENT '是否开启推送提醒',
  notification_time     TIME        NOT NULL DEFAULT '09:00:00' COMMENT '每日提醒时间',
  makeup_chances       INT UNSIGNED NOT NULL DEFAULT 0  COMMENT '补签机会次数',
  created_at            DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at            DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (wordbook_id) REFERENCES wordbooks(id) ON DELETE SET NULL,
  UNIQUE KEY uk_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '用户设置表';

注意makeup_chances------补签机会

这玩意儿是干嘛的?

你懂的,总有些日子你忘了背单词,

然后看着日历上的"漏打卡"心痛不已。

有补签卡,就能挽回一点尊严。

说白了就是:

我给自己留了条后路,

毕竟我知道自己有多懒。


写在最后

设计稿画完了,数据库也设计好了。

这一篇没什么代码,全是规划和设计,

可能看起来没那么"硬核",

但我想说的是------

再牛逼的代码,也得从一张草稿纸开始。

你看到的这7张表,

背后是我和AI聊了N个来回,

推翻重来了好几次,

才定下来的。

虽然现在看起来挺像那么回事,

但等到真正写代码的时候,

说不定又得改。

软件开发的真相:

设计的时候觉得"完美",

写代码的时候觉得"这里得改",

上线之后觉得"当初我怎么想的"。

没事,改就改呗。

反正又不是给别人打工,

我自己的项目,想怎么改就怎么改。


喜欢就点个

觉得有用就评论 两句,

觉得我在吹牛......那就看到最后,看我到底能不能做出来。

相关推荐
lichenyang4531 小时前
不要把 JSBridge 写成 if else:Dispatcher、Registry 和 Biz/Imp 分层
前端
前端甜糖1 小时前
前端如何实现在线预览office常见文件功能?
前端·vue.js
love530love1 小时前
CodexPro + MCP + Cloudflare 配置详解:HTTP2、QUIC 与连接排障
ide·人工智能·windows·ai agent
北鸟南游1 小时前
学习-claude code 工程化实战的笔记
前端·ai编程·claude
Kyrie6781 小时前
TypeScript 7.0 正式发布
前端
lichenyang4531 小时前
JSBridge 不是发消息就完了:runJavaScript、Timeout 和 Callback Lost
前端
Listen·Rain1 小时前
向量化详解
java·人工智能·spring·机器学习·ai
xiaofeichaichai1 小时前
Vite配置实战
前端
zhanghaofaowhrql1 小时前
为CSDN博客编辑器安装自定义CSS主题,打造个性化写作界面
前端·css·编辑器