跳转至

后端与数据库

主要内容

本篇整理数据库和后端学习:关系型数据库、SQL CRUD、约束、JOIN、聚合、事务、PostgreSQL、Go 后端、Node.js 后端、GORM、Sequelize、API 文档驱动开发,以及飞书中的 SQL、Go、CORS、JSON tag 思考题。

参考文档

  • 数据库.md数据库扩展.mdPostgreSQL 环境配置.md
  • Golang.mdGo 环境配置.mdGo 进阶阅读.md
  • GORM.mdNode.js基础.mdNode.js.mdSequelize.md
  • API 的制定.md

后端的职责

后端连接前端、数据库和外部服务。它处理请求、鉴权、业务逻辑、数据读写和错误返回。

前端请求 -> 路由 -> 参数校验 -> 业务逻辑 -> 数据库/外部服务 -> JSON 响应

为什么需要数据库

文件可以保存数据,但复杂业务需要并发控制、完整性约束、多表关系、事务和高效查询。关系型数据库用表组织数据,用 SQL 操作数据。

SQL 基础

INSERT INTO users (name) VALUES ('Alice');
SELECT * FROM users WHERE name = 'Alice';
UPDATE users SET name = 'Bob' WHERE id = 1;
DELETE FROM users WHERE id = 1;

约束:主键、外键、非空、唯一、默认值。

外键保证引用完整性。例如 student 的 dept_name 必须在 department 表中存在。

JOIN 与聚合

JOIN 用于跨表查询。比如查学生所在院系楼,需要 student 和 department 连接。

聚合函数:countavgsummaxmin

SELECT dept_name, avg(salary)
FROM instructor
GROUP BY dept_name;

事务

事务保证一组操作要么全部成功,要么全部失败。

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

ACID:原子性、一致性、隔离性、持久性。

Go 后端

Go 学习点:

  • packageimportfunc
  • struct 和 interface。
  • 大写导出、小写包内可见。
  • go mod init
  • 配置文件读取。
  • GORM 连接数据库。
  • net/http 处理请求。
  • CORS。

Go module path 常写成 github.com/user/project,因为它是全局依赖标识。

Node.js 后端

Node.js 是让 JavaScript 脱离浏览器运行的环境。它适合 I/O 密集型后端和全栈 TypeScript。

要理解:事件循环、异步、npm、package-lock、模块化、HTTP server。

部署时用 npm ci 保证依赖和 lockfile 一致。

ORM

ORM 把数据库表映射为语言对象。GORM 用 struct,Sequelize 用 JS/TS 模型。

优点:写 CRUD 更快,减少重复 SQL。

风险:不懂 SQL 会看不懂性能问题,自动迁移也可能误伤表结构。

API 文档驱动

API 文档决定:URL、method、request、response、错误码。后端写接口时要同时考虑前端怎么调、数据库怎么查。

实践项目

评论系统:users、posts、comments 三张表;实现评论增删改查;前端通过 Axios 请求;后端用 Go/GORM 或 Node/Sequelize;用 Apifox 调试。

飞书思考题

你真的学会 SQL 了吗?

要检验 SQL 不能只会 select *。至少应能完成:建表、插入、更新、删除、条件查询、连接查询、聚合、分组、排序、事务。学生-课程-教师模型适合练习 JOIN、外键和聚合统计。

Go module path 为什么用 github.com/yourname/myproject

因为 Go 用 module path 标识模块。带域名和用户名可以降低重名概率,也方便开源项目被别人 import。它不能完全规避重名,项目名仍应避免过于通用。

CORS 里 OPTIONS 是什么,为什么要加?

浏览器对非简单跨域请求会先发 OPTIONS 预检,询问后端是否允许这个来源、方法和请求头。如果后端不处理 OPTIONS,真正的 POST/PUT 请求不会发出。

Go JSON tag 如何匹配字段?日期时间如何传?

Go 的 JSON 库通过反射读取导出字段。json:"json_field" 会把字段映射成 json_field。未写 tag 时默认用字段名。时间一般传 RFC3339 字符串,也可以约定 Unix timestamp,但前后端必须统一。

知识卡片

主键

主键不是“看起来唯一”的字段,而是数据库用来稳定识别一行的约束。主键最好不要频繁变化。

外键

外键维护引用完整性。它会让错误更早暴露,但也要求设计清楚删除、更新时的级联策略。

事务边界

事务不宜过长。事务越长,锁持有越久,并发性能越差。

ORM 和 SQL

ORM 提高开发效率,但 SQL 是理解数据库行为的底层语言。遇到性能问题时,最终还是要看 SQL。