Files
doodle-store/apps/server/prisma/sql/README.md
T

15 KiB
Raw Blame History

v3.5 PostgreSQL 初始化 SQL

2026-10-15:已接入 Prisma Schema 与 0_v35_baseline,本地现有库仅登记基线,没有重建业务表。下文保留原手工 SQL 的执行路径和历史核查;新的空库优先使用 Prisma migrate deploy,后续升级新增迁移。详见 Prisma 说明。

基于 数据库设计,面向 PostgreSQL 18。缩进统一 4 个空格;文件是普通 PostgreSQL SQL,可使用 psql 或数据库客户端执行。

2026-10-12 已在本地 PostgreSQL 18.6 临时数据库执行 001/002/003,并重复执行 003 验证不覆盖 enabled=false;10 张表与 19 项关键约束检查通过,历史 NULL 事件、标识大小写及资产所有者删除行为符合设计。验证库已删除;随后已在用户授权下正式初始化 doodle_dev,10 张表与两条配置记录核对通过。

文件 作用 执行位置
001-create-database.sql 创建 UTF-8 / C locale / UTC 的 doodle_dev 连接 postgres 管理数据库,有 CREATEDB 权限;不能包在事务里
002-create-tables.sql 创建 13 张表、约束、索引与注释 连接目标空数据库;单事务执行
003-initialize-settings.sql 初始化 current 页面配置及 homeAutoRefresh 开关 连接已建表数据库;可重复执行且不覆盖旧值
004-remove-users-mini-app-id.sql 单小程序身份简化,OpenID 唯一 仅旧版基线库,成功后不重复执行
005-add-worksheet-resources.sql 增加绘制配置、多文件内容及下载内容标识 仅未执行此升级的既有库,单事务执行
006-add-worksheet-grades.sql 增加功能适用年级关系 已完成 004/005 的既有库;不自动回填旧 grade
007-add-publication-and-resource-downloads.sql 功能/资源首次发布时间及资源下载量 已完成 004/005/006 的既有库;旧时间不推算、旧计数不分摊
008-add-resource-favorites.sql 统一收藏功能与具体内容、两种部分唯一索引 已完成 004~007 的既有库,旧收藏保持功能目标

Docker 已在首次启动时创建 doodle_dev,当前本地跳过 001。其他环境显式修改 001 的数据库名并用对应角色执行;本次不自动创建云端数据库、生产账号或测试库,不在 SQL 中硬编码密码。生产角色和权限在部署时落实。

最新执行路径

当前本地 doodle_dev 已执行至 008,使用最新 13 张表;不重跑 002 或任何已成功的增量 SQL。

数据库当前状态 升级至最新的执行顺序
空库 002 → 003;未建库时先执行 001,Docker 已建库则跳过 001
最初 10 张表的旧基线库 004 → 005 → 006 → 007 → 008
已执行部分增量的库 按编号顺序执行尚未应用的后续文件
已执行 008 的库 无需再次执行 DDL

004~008 是历史结构的升级文件,不能用于已执行最新 002 的空库基线。下文各阶段记录解释该次变更,不表示只完成其中某一步就已到最新结构。当前已接入 Prisma 迁移基线,旧手工库在登记前依据实际结构及执行记录确认当前版本。

空库初始化示例

从 doodle-store 根目录执行,以下仅适用于尚未建表的目标库。根 .env 当前指向已初始化的 doodle_dev,不在现有库再次运行 002。

pnpm infra:up

docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/002-create-tables.sql

docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/003-initialize-settings.sql

002 用显式 CREATE TABLE 而非 IF NOT EXISTS;已有同名表时返回错误并回滚,不覆盖已有结构或数据。它是空库基线,不是可反复执行的增量迁移;后续结构修改写新迁移文件。003 的重复执行不会覆盖导入内容、已递增版本或 enabled=false。

SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;
SELECT id, version FROM public.page_configs;
SELECT id, value FROM public.settings;

最新基线预期业务表共 13 张,页面配置有 current,设置有 homeAutoRefresh。2026-10-12 已在本地 doodle_dev 执行 002/003 并核对通过,当时已有 10 张表;不要再次执行 002。独立临时库验证与正式本地初始化分别记录,未连接云服务器。

实施边界

  • 字符串主键保留旧 ID,应用生成新 ID;所有身份/对象标识使用 C 排序规则。
  • 收藏/下载的用户外键限制直接删除;注销需先清关系、处理计数,再删用户。题型仅逻辑关联,保留缺失题型历史。
  • 资产 ready 必填元数据、avatar 必须 private;资产归属、用途匹配、签名地址、远程 URL 白名单和文件存在性仍由服务端校验。
  • 下载 NULL exportId 只允许 import 来源;非空事件按 userId + exportId 去重。计数不会通过触发器自动更新,由后续业务事务实现。
  • tags 元素类型、分类多层循环、任务租约/锁、JWT 失效与管理员权限由后续业务实现;SQL 不代表业务 API 已完成。
  • updatedAt 和 contentUpdatedAt 由服务显式维护,不添加把两者混为一谈的更新时间触发器。
  • Prisma Schema 和迁移历史已接入,本 SQL 已纳入正式基线;已有表的库须先核对再登记基线,不能直接再次执行同一 DDL。

单小程序身份简化(2026-10-14)

最新 002 已移除 users.mini_app_id,改为 users.openid 唯一,AppID 由服务端配置。 已执行旧版 002 的库使用 004-remove-users-mini-app-id.sql 增量升级;不要重跑 002。 新建库执行最新 002/003 即可,不执行 004。004 会先建立 OpenID 唯一约束, 如存在重复则全部回滚,不自动合并或删除用户;成功执行后不可重复执行。

2026-10-14 已在本地 doodle_dev 执行 004 并核对:mini_app_id 已移除,users_openid_key 为 UNIQUE (openid);执行时用户表为空。

Worksheet 多资源扩展(2026-10-14)

设计原因见 Worksheet 数据库设计说明。 最新 002 新建 13 张表;worksheet 增加 generation_mode、renderer_key、render_config,新增 worksheet_resources、worksheet_resource_assets,assets 支持 worksheet_source 用途, download_logs 增加可空 worksheet_resource_id。文件关联首期只有 outline/reference,无文件级配置。

  • 新空库:执行最新 002 → 003;不要执行 004/005/006/007/008,它们的结果已经包含在基线里。
  • 2026-10-12 旧基线库:先执行 004(若尚未执行),再执行 005。
  • 已执行 004 的本地库:只执行 005;不要重跑 002 或 004。
  • 005 为单事务增量升级,成功后不可重复执行;不使用 IF NOT EXISTS 隐藏结构差异。
docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/005-add-worksheet-resources.sql

旧 worksheet 的 ID/path、计数、预览及历史不变;新列默认 procedural、NULL renderer_key 和 {}。 导入时按实际功能核对,NULL renderer_key 仅供已登记的旧版映射兼容;新功能发布必须明确实现。 不把旧题型预览自动转为线框或参考资源,资源新表默认空。下载资源 ID 为逻辑关联,服务端需校验归属。

2026-10-14 验证记录:在两个隔离临时库分别执行最新 002/003 与旧版 002/003 + 005, 列定义、约束、索引及注释一致(忽略新增列的物理顺序)。两条路径均通过多线框、共享资产、 双用途引用、独立预览、JSON/状态/唯一性/外键/删除限制、旧数据保留与历史逻辑关联检查。 临时库均已删除;本地 doodle_dev 已执行 005,核对为 12 张表,current/homeAutoRefresh 保留, 两张资源新表为空,未导入测试内容或连接生产库。

多适用年级(2026-10-14)

categories 结构保持不变,新增 worksheet_grades(worksheet_id、grade),联合主键防重复, 反向索引供年级菜单筛选。固定编码 -4~6,0 为幼小衔接;不新增年级字典或菜单表。 旧 worksheets.grade 保留原值,关系表作为新适用年级筛选的唯一权威来源。

最新空库执行 002/003,跳过 004/005/006/007/008;已执行 005 的库仅执行 006。 更早的库先按版本补齐未执行的增量文件,不重复执行成功的 SQL。006 单事务、非重复执行脚本, 不自动从旧 grade 或年龄回填关系;经审核的 worksheetId → grades 映射另行导入。 无关系表示未配置,不表示全年级;年级筛选上线前完成对应题型的映射审核。

docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/006-add-worksheet-grades.sql

2026-10-14 验证:最新 002/003 与旧版基线 + 006 在两个隔离库中生成相同的列、约束、 索引及注释;多/不连续年级、合法编码边界、联合主键、外键、删除限制、旧值保留、 不自动回填及分类/年级组合查询不重复检查通过。临时库已删除。 本地 doodle_dev 已执行 006,共 13 张表;worksheet_grades 为空,初始配置保留。

首次发布与资源下载统计(2026-10-14)

最新空库只执行 002/003;已执行 006 的既有库执行 007,不重跑旧迁移。 007 在功能及内容上增加可空 first_published_at(无默认值),内容增加非负 downloads(默认 0)。 旧 is_new 保留为兼容值,is_hot 保留为功能运营推荐;不新增资源新品/热门布尔值、收藏计数或 seed。 未知旧发布时间保持 NULL,首次发布/新品派生及下载幂等事务由后续服务端业务实现。 文件访问、日志数量、创建时间和升级时间都不能冒充真实历史依据。

docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/007-add-publication-and-resource-downloads.sql

新结构仍为 13 张表。正常资源下载的日志及两层 downloads 由同一事务维护,不使用触发器自动加数。 功能原累计值不覆盖或分摊,资源默认 0;旧单独保存的 is_new 不变,不能据此伪造时间。

2026-10-14 验证:最新 002/003 与旧版基线 + 007 在两个临时库生成相同列、约束、索引及注释。 旧标记/计数/未知发布时间保留、资源默认 0、非负约束和独立发布时间检查通过; SQL 事务示例通过重复事件不加数、任一步失败全回滚、删除日志不扣累计的验证。 这些验证不代表真实下载 API 已实现。临时库已清理;本地 doodle_dev 已执行 007,仍为 13 张表, 新时间列可空且无默认值,资源 downloads 默认 0、NOT NULL 且非负,原初始配置保留。

统一功能与内容收藏(2026-10-14)

最新空库执行 002/003,跳过 004~008;已执行 007 的既有库仅执行 008,不重复已成功 SQL。 008 新增 favorites.worksheet_resource_id,旧记录为 NULL;撤销旧全局唯一约束, 创建功能和内容两个部分唯一索引。不新增资源收藏表/type 字段或资源 likes,仍为 13 张表。 旧收藏 ID、时间、归属和功能 likes 不变。新内容 ID 为逻辑关联,归属由服务校验,缺失不 SET NULL。

docker compose --env-file .env -f infra/compose.yaml exec -T postgres \
    sh -c 'exec psql -X -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
    < apps/server/prisma/sql/008-add-resource-favorites.sql

后续收藏 INSERT 的 ON CONFLICT 需带对应部分索引谓词,Prisma 接入时保留原生索引。 旧查询/数量/取消加 IS NULL;新资源关系不增减功能 likes,注销清理两类但仅扣功能贡献。 本次仅修改数据库与接口契约,资源收藏 API 及小程序页面尚待实现。

2026-10-14 验证:最新基线与旧版基线 + 008 的列、约束、索引、注释一致; 旧收藏保留、功能和同功能多资源共存、两种部分唯一索引/ON CONFLICT、用户隔离、 旧功能取消范围、资源取消不扣 likes、下架/失联目标保留及注销 SQL 示例通过。 临时验证库已删除;本地 doodle_dev 已执行 008,仍为 13 张表,两种部分索引生效, 原配置保留,未导入测试收藏。验证不代表业务 API 或小程序资源收藏页面已经实现。

最终对齐核查(2026-10-14)

  • 设计文档与最新 002 的 13 张表、135 个字段名称/类型/可空/默认值一致。
  • 实测 001 建隔离库;最新 002/003、原始旧基线 + 004~008 全链路、本地 doodle_dev 的列、约束、索引和注释一致,忽略物理列顺序。
  • 完整升级保留旧身份、功能、收藏、历史及计数;003 重复执行不覆盖关闭开关、页面内容及版本。
  • 最新基线下的资源、年级、发布/下载、两种收藏约束与 SQL 事务示例回归通过,标识列 C 排序规则核对通过。
  • 所有临时核查库已清理;开发库只读比对,无样本写入。本次只修正文档说明,无需新增 DDL 或再次升级开发库。

业务归属/权限、首次发布、计数和审计事务、任务调度等仍需服务端接入;SQL 验证不代替业务 API 验收。

分类发布状态(2026-10-16)

最新 002/003 包含分类 status,空库不再执行 009。原 004~008 及 Prisma 旧基线不改写;已有结构新增 009(或使用对应 Prisma 迁移,二者不能重复)。009 新增 status 默认 draft、三态 CHECK 和状态/父级索引,同时将既有分类置为 active 保持兼容。当前为 13 张表、136 个字段。新后端公开接口同时检查分类祖先状态,管理员状态修改使数据库页面快照失效。