Sequelize 查询与分页
真正让 ORM 见真章的,不是建模,而是列表查询。博客系统看起来简单,但一旦有分类、标签、发布时间、状态和关键词搜索,分页接口很容易被写成一锅粥。
真正让 ORM 见真章的,不是建模,而是列表查询。博客系统看起来简单,但一旦有分类、标签、发布时间、状态和关键词搜索,分页接口很容易被写成一锅粥。
做后台列表时,最容易失控的代码通常不是控制器,而是那段越来越长的 findAll 参数对象。筛选、排序、分页、include、权限条件不断往里塞,最后查询虽然还能跑,但没人敢再改。
Sequelize 的 include 第一次用起来很爽,因为它帮你把关联数据一次带回来了。可一旦团队形成习惯,列表、详情、后台搜索全都开始层层 include,接口就会慢慢变成一坨难调试的 SQL。
ORM 最容易让人上头的地方,是看起来什么关系都能一句话配完;但真正落到博客系统里,关联一旦建得太随意,列表接口的查询成本会立刻暴露出来。
Sequelize 的 belongsToMany 很方便,几行配置就能把多对多关系跑起来。可到了真实业务里,我越来越少把中间表只当“两个外键的过桥结构”,因为它往往很快就会承载排序、来源、状态和时间这些额外信息。
做内容系统时,我越来越确定一件事:表名和字段名的命名策略必须早点定。因为 ORM 能帮你屏蔽一部分 SQL 细节,但它并不能替你修复混乱命名带来的认知成本。
刚开始把博客系统往关系型数据库上迁的时候,我最先补的一块不是查询,而是模型设计。因为模型边界一旦定错,后面的列表、详情、标签、归档都会变得越来越绕。
Sequelize 默认帮我们带上时间戳,这一点很省事。但很多项目用着用着就会发现,时间戳和软删除并不是“打开就完事”的便利功能,它们会直接影响列表查询、唯一索引和后台恢复逻辑。
Sequelize 的 migration 在演示里总是很简单,真正到了团队协作阶段,问题就变成了另一种:本地能跑,测试环境半残,CI 里还会因为顺序不一致把表结构跑歪。
很多团队第一次上 Sequelize,最容易忽略的不是关联关系,而是字段约定。字段长度、是否允许为空、默认值和枚举范围如果一开始不说清楚,后面接口一多,数据库就会慢慢长成“谁都不敢动”的样子。