[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10853":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":36,"readmeContent":37,"aiSummary":38,"trendingCount":16,"starSnapshotCount":16,"syncStatus":39,"lastSyncTime":40,"discoverSource":41},10853,"sql-mother","liyupi\u002Fsql-mother","liyupi","程序员鱼皮原创项目，免费的闯关交互式 SQL 自学教程网站，从零基础到进阶，带你掌握常用 SQL 语法（MySQL、SQLite、PostgreSQL）、快速学习 SQL 和数据库。支持在线SQL编辑器、实时查询结果、语法高亮、SQL运行广场等功能。纯前端实现，简单易学~","http:\u002F\u002Fsqlmother.yupi.icu",null,"TypeScript",4200,428,11,12,0,4,14,58,15,77.7,false,"master",true,[26,27,28,29,30,31,32,33,34,35],"css","database","frontend","html","javascript","mysql","sql","typescript","vue3","web","2026-06-12 04:00:52","# SQL 之母 - 闯关式 SQL 自学网\n\n> 纯前端实现的闯关式 SQL 自学网\n>\n> By [程序员鱼皮](https:\u002F\u002Fdocs.qq.com\u002Fdoc\u002FDUFFRVWladXVjeUxW) ，一人全役\n\n\n\n在线体验：http:\u002F\u002Fsqlmother.yupi.icu\n\n视频演示：https:\u002F\u002Fwww.bilibili.com\u002Fvideo\u002FBV1pV4y1i7LW\n\n\n\n## 项目介绍\n\n一个完全免费的闯关式 SQL 自学教程网站，结合鱼皮自己的 SQL 学习实践经验，编写了 30 多个关卡，用户可以在线提交 SQL 代码做题闯关，目标是从 0 到 1 地带大家掌握常用的 SQL 语法。\n\n此外，网站支持自由选择关卡、自定义关卡、SQL 在线练习广场等功能。\n\n![](.\u002Fdoc\u002Findex.png)\n\n\n\n### 为什么做这样一个网站？\n\n首先，SQL 知识极为重要，几乎是程序员、产品经理、数据分析同学的必备技能。\n\n对于 SQL 的学习，比起看教程，更适合通过实战来入门。网上虽然也有类似的 SQL 自学网，但是要么收费、要么不够体系化。\n\n所以鱼皮决定自己动手，搞一个开源的 SQL 学习网，一方面希望能够帮助大家更轻松地入门 SQL；另一方面，也希望项目代码也能给大家一些启发，让更多同学有机会参与进来成为贡献者，一起做好一个项目！\n\n\n\n## 20 秒学会使用\n\n1）直接进入主页，左侧是教程和题目区域，请先完整阅读\n\n2）在右上区域编写 SQL 代码做题，点击运行提交结果\n\n3）可以通过右下的题目助手区域帮助自己做题\n\n4）执行结果正确后，可以进入下一关\n\n![SQL 之母使用教程](.\u002Fdoc\u002Ftutorial.png)\n\n你也可以自由选择关卡来挑战，所有关卡都没有任何限制，不一定非要按顺序做题：\n\n![选择关卡](.\u002Fdoc\u002Flevels.png)\n\n\n\n\n## 1 分钟本地启动\n\n由于项目采用纯前端实现，本地启动项目非常简单！\n\n> 在线访问人数较多，可能会卡顿，所以更推荐大家自己在本地使用~\n\n1）下载本项目代码\n\n2）进入项目根目录，执行 `npm install` 安装项目依赖\n\n3）执行 `npm run dev` 本地启动即可\n\n\n\n## 功能和特性\n\n- 展示教程题目文档（Markdown 格式）\n- 在线做题\n  - 比对结果\n  - 题目助手\n    - 展示执行结果\n    - 查看提示\n    - 查看建表语句\n    - 查看答案\n- 关卡设置\n  - 自由选择关卡\n  - 主线关卡 - 支持上一关 \u002F 下一关\n  - 自定义关卡\n- SQL 广场（自由输入 SQL）\n\n\n\n![SQL 广场](.\u002Fdoc\u002Fsql-playground.png)\n\n\n\n## 技术选型\n\n本项目采用纯前端实现，不需要任何后端的前置知识~\n\n> Q：为什么采用纯前端实现？\n>\n> A：减少攻击风险 + 省钱 + 新的学习尝试\n\n\n\n- 主框架：Vue 3\n- 组件库：ant-design-vue\n- Markdown 展示组件：bytemd + github-markdown-css 主题\n- 代码编辑器：monaco-editor\n- SQL 执行：sql.js\n- SQL 代码格式化：sql-formatter\n- 全局状态管理：pinia + pinia-plugin-persistedstate\n- 前端工程化：typescript + eslint + prettier\n- 工具库：lodash\n\n\n\n## 核心设计\n\n### 1、界面模块化\n\n采用模块化的开发思想，把做题页面（主页）拆分为题目浏览区、SQL 编码区、题目结果区，每个区都是一个独立的 Vue 组件文件，实现了逻辑的隔离和组件的复用（比如 SQL 编码区同样可以复用到 SQL 练习广场页面）。\n\n- 题目浏览区（QuestionBoard）：展示题目 Markdown 文档\n- SQL 编码区（SqlEditor）：封装了代码编辑器、运行 \u002F 格式化 \u002F 重置按钮\n- 题目结果区（SqlResult）：封装了题目执行结果的展示\n\n然后在 `IndexPage.vue` 中就可以引入这些组件，并且传递关卡信息、运行结果等数据给组件，组装成一个完整的页面。\n\n\n\n### 2、关卡设计\n\n虽然没有后端数据库，但是仍应该把所有关卡的数据统一进行管理，所以定义了 `levels` 目录，统一存放关卡相关数据。\n\n首先将关卡分为了两类，主线关卡（教程）和自定义关卡（便于扩展），分别在 `mainLevels.ts` 和 `customLevels.ts` 文件中进行管理。\n\n每个关卡都是一个单独的目录，实现了关卡之间的隔离。\n\n![每个关卡独立目录](.\u002Fdoc\u002FcustomLevel.png)\n\n由于每个关卡的题目教程文章可能非常长，直接写在 ts 文件中不利于阅读和管理，所以这里的策略是把所有文章写在 `.md` Markdown 文件中，在关卡定义文件 `index.ts` 中读取 `.md` 文件。\n\n示例代码如下，每个关卡的信息独立定义、相互隔离：\n\n```ts\nimport md from \".\u002FREADME.md?raw\";\nimport sql from \".\u002FcreateTable.sql?raw\";\n\nexport default {\n  key: \"level1\",\n  title: \"基础语法 - 查询 - 全表查询\",\n  initSQL: sql,\n  content: md,\n  defaultSQL: \"select * from student\",\n  answer: \"select * from student\",\n  hint: \"请仔细查看本关给出的示例\",\n  type: \"main\",\n} as LevelType;\n```\n\n\n\n### 3、纯前端 SQL 执行\n\n纯前端是怎么操作数据库、执行 SQL 的呢？有前端经验的同学会本能地想到 `webassembly` 技术。\n\n没错，通过 `webassembly` 技术，我们可以在浏览器中执行 JS 之外的语言（比如 C++）。但是没必要自己去实现 SQL 执行逻辑了，站在巨人的肩膀上，直接使用开源的 `sql.js` 库，就可以在前端执行自己的 SQL 操作了。\n\n核心代码在 `src\u002Fcore\u002FsqlExecutor.ts` 中，定义了初始化 DB 和执行 SQL 两个函数，很简单：\n\n```ts\nimport initSqlJs, { Database, SqlJsStatic } from \"sql.js\";\n\n\u002F**\n * SQL 执行器\n *\n * @author coder_yupi https:\u002F\u002Fgithub.com\u002Fliyupi\n *\u002F\nlet SQL: SqlJsStatic;\n\n\u002F**\n * 获取初始化 DB\n * @param initSql\n *\u002F\nexport const initDB = async (initSql?: string) => {\n  if (!SQL) {\n    SQL = await initSqlJs({\n      \u002F\u002F Required to load the wasm binary asynchronously\n      locateFile: () =>\n        \"https:\u002F\u002Fcdn.bootcdn.net\u002Fajax\u002Flibs\u002Fsql.js\u002F1.7.0\u002Fsql-wasm.wasm\",\n    });\n  }\n  \u002F\u002F Create a database\n  const db = new SQL.Database();\n  if (initSql) {\n    \u002F\u002F Execute a single SQL string that contains multiple statements\n    db.run(initSql); \u002F\u002F Run the query without returning anything\n  }\n  return db;\n};\n\n\u002F**\n * 执行 SQL\n * @param db\n * @param sql\n *\u002F\nexport const runSQL = (db: Database, sql: string) => {\n  return db.exec(sql);\n};\n\n```\n\n在关卡加载时，会先执行关卡对应的初始化 SQL 语句完成建表和导入示例数据，然后用户就可以编写 SQL 查询表中的数据了。\n\n\n\n### 4、判题机制\n\n和判题相关的代码全部集中定义在 `src\u002Fcore\u002Fresult.ts` 文件中，包括定义了几种执行状态，以及判断结果是否正确的函数。\n\n如何判断用户的 SQL 语句是否正确呢？\n\n不是直接去对比用户的输入语句和我们预设的答案是否一致（那样太死板了），而是依次执行以下 3 个操作：\n\n1. 分别提交用户的输入语句和答案语句，得到两份结果表\n2. 判断两个结果表输出的列名是否一致（名称和顺序都要一致）\n3. 判断两个结果表输出的数据是否一致\n\n这里作者用了个 trick 方式来对比数据，直接把两份结果集转为 JSON 格式，对比 JSON 字符串是否一致即可，而不是多重 for 循环。\n\n\n\n## 目录结构\n\n- public：公共静态资源\n- doc：文档相关资源\n- src\n  - assets：静态资源\n  - components：组件\n    - CodeEditor.vue：代码编辑器\n    - MdViewer.vue：Markdown 浏览\n    - QuestionBoard.vue：题目面板（教程区）\n    - SqlEditor.vue：SQL 编辑器（练习区）\n    - SqlResult.vue：SQL 执行结果（结果区）\n    - SqlResultTable.vue：SQL 结果表格\n  - configs：配置\n    - routes：路由\n  - core：核心\n    - sqlExecutor.ts：SQL 执行引擎\n    - result.ts：执行结果相关变量和函数\n    - globalStore.ts：全局状态管理\n  - levels：关卡\n    - custom：自定义关卡\n    - main：主线关卡\n      - level1：每个关卡都是一个单独的目录\n        - createTable.sql：关卡依赖的建表语句\n        - index.ts：关卡的定义\n        - README.md：关卡教程\n    - index.ts：定义了关卡相关变量和函数\n    - level.d.ts：关卡类型定义\n    - mainLevels：主线关卡列表\n    - customLevels：自定义关卡列表\n  - pages：页面\n    - IndexPage.vue：主页\n    - LevelsPage.vue：关卡页面\n    - PlaygroundPage.vue：广场页面\n  - App.vue：主页\n  - main.ts：Vue 主文件\n  - style.css：全局样式文件\n  - vite-env.d.ts：环境定义\n- .eslintrc.js：代码规范\n- .gitignore：提交忽略文件\n- index.html：静态主页\n- package.json：项目管理\n- tsconfig.json：TS 配置\n- vite.config.ts：打包工具配置\n\n\n\n## 贡献指南\n\n欢迎各路好汉参与贡献，利人利己~\n\n目前有几种推荐的贡献方式：\n\n\n\n### 1、贡献关卡\n\n在贡献关卡前，请确保你已经理解了本项目加载关卡的方式。\n\n为保证教程的连贯性，更推荐贡献 `自定义关卡` 而不是主线关卡，更容易被合并。\n\n贡献自定义关卡的步骤：\n\n1）复制 `src\u002Flevels\u002Fcustom\u002F自定义关卡模板` ，将目录名改为自己的关卡中文名\n\n2）修改模板中的 `createTable.sql` 建表语句，导入默认数据\n\n3）修改模板中的 `index.ts` 文件，设置关卡的中英文名、默认 SQL、答案 SQL、提示等\n\n4）修改模板中的 `README.md` 文件，更改标题和题目内容，需要给出表结构信息、并且尽量把题目表达清楚（比如必须按照某个顺序输出）\n\n5）在 `customLevels.ts` 文件中引入自定义的关卡。\n\n> 注意，本项目仅支持 SQLite 语法（基本上是通用的 SQL）！不要使用太花里胡哨的函数！\n\n\n\n![自定义关卡](.\u002Fdoc\u002FcustomLevel.png)\n\n\n\n### 2、完善关卡\n\n比如修复关卡的错误、优化关卡的文案使其更易于理解或增加更多干货、调整关卡的难度等。\n\n\n\n### 3、项目扩展\n\n本项目仅为鱼皮一人开发，时间和精力有限，很多地方没有做到完善，欢迎大家给项目进行扩展，打造属于自己的 SQL 之子、SQL 之孙、SQL 之曾孙系列产品。。。\n\n一些可能的扩展思路：\n\n1. 点击 “提交” 题目后，自动展开执行结果区域\n2. 过关后，给出更友好的过关提示，可以更方便地到达下一关\n3. 支持 SQL 一键格式化\n4. 优化关卡加载机制，按需加载\n5. 给项目增加一个后端，用数据库来存放关卡数据，并且支持在线提交 \u002F 审核关卡\n6. 增加过关排行榜\n\n感谢阅读，也欢迎加入 [作者的编程学习圈](https:\u002F\u002Fyupi.icu)，学习更多原创项目~\n\n## 感谢赞助\n\n本项目 CDN 加速及安全防护由 Tencent EdgeOne 赞助\n\n[亚洲最佳CDN、边缘和安全解决方案 - Tencent EdgeOne](https:\u002F\u002Fedgeone.ai\u002Fzh?from=github)\n\n![image](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Feeb52237-4520-4a97-8f3d-6cb901e2106a)\n\n","SQL 之母是一个免费的闯关交互式 SQL 自学教程网站，旨在帮助用户从零基础到进阶掌握常用 SQL 语法（如 MySQL、SQLite 和 PostgreSQL）。该项目的核心功能包括在线 SQL 编辑器、实时查询结果展示、语法高亮以及一个 SQL 运行广场等。它采用纯前端技术实现，使用 Vue 3 作为主框架，并结合了 monaco-editor 作为代码编辑器和 sql.js 来执行 SQL 语句，使得整个学习过程既直观又高效。适合任何希望以实践方式学习 SQL 的个人或团队，特别是对于初学者而言，能够提供一个友好且互动的学习环境。",2,"2026-06-11 03:30:29","top_topic"]