Files
ChuSQL/docs/blog-database.md
T
ChuNa7a 6996e19694
build / build (push) Blocked by required conditions
tests / build (push) Waiting to run
tests / tests (push) Waiting to run
修bug,完善功能
2026-10-16 23:52:12 +08:00

7.6 KiB

博客业务数据库接入

本页帮助 ChuBlog 开发者接入业务数据,运行真实 Rust 驱动验收,并区分数据库已验证的能力与博客服务端需要实现的规则。正文和资源保存在 Git 文件中,数据库只保存业务状态和可重建索引。

数据模型

验收表定义 在空库创建表,采用现有标量类型及 CHECK,不依赖 ENUM、外键或复合索引。它是供 ChuBlog 接入时采用的基线,不会自动替换 ChuBlog 当前文件账户实现,也不对已有库执行结构迁移。

PHC 是包含算法、版本、参数、盐和哈希的密码编码字符串。

数据 表 恢复要求
用户、完整密码 PHC、角色、撤权版本 blog_users 必须备份
发布路径与 SSH 公钥 blog_publish_grants、blog_ssh_keys 必须备份
可见性、查阅口令 PHC、撤销版本、隐藏、删除、精华与计数 blog_article_state 必须备份
评论与匿名或登录身份关联 blog_comments 必须备份
点赞、收藏的活动状态与去重键 blog_reactions 必须备份
管理审计与迁移完成标记 blog_audit、blog_migrations 必须备份
文件路径、标题与 Git 提交索引 blog_articles 可从 Git 重建

索引重建只能修改派生表。站长隐藏或删除、授权版本和查阅口令不能从文章元数据推导或被作者再次推送覆盖。停机备份应包含整个存储数据目录;正文仓库仍按 ChuBlog 的备份流程保存。

事务与权限检查

需要先检查再写入的操作使用独立连接上的 BEGIN ISOLATION LEVEL SERIALIZABLE,包括注册、发评论、点赞或收藏、撤权及物理删除关联数据。读取身份、文章状态和关联记录,检查结果后再更新明细、计数和审计,最后 COMMIT。不要把多个请求的事务交给共享的驱动 Client 克隆;克隆共用一个会话。

串行化模式在写事务提交时按表复查读依赖,包括子查询和幻行。其他连接改变读过的表,即使改的是不同行,也可能返回 serialization_failure。默认 BEGIN 使用行版本快照和行级写冲突检查,两种模式都校验合并后的最终列约束;工作行集仍需整库物化。

冲突行或唯一键会等待持锁事务结束,等待不占库提交门。死锁和超过 5 秒的锁等待分别返回 deadlock_detected、lock_timeout,事务已中止。收到这两个错误或 serialization_failure 后先 ROLLBACK,再从 BEGIN 重做业务检查;不要只重发 COMMIT。SAVEPOINT 回滚恢复数据与读依赖,已取得的锁保留到整个事务结束。

断线或超时后的提交结果可能未知。先通过稳定操作键查询结果,不盲目重做计数更新。生产中的操作键应由服务端按操作身份生成,例如将规范化的文章、主体和互动类别编码后计算 SHA-256,保存完整 64 位十六进制字符串;验收使用可读的固定键。匿名身份关联或合并也须在同一事务处理,避免用客户端任意提交的用户名去重。

本模型没有数据库外键。新增关联记录的事务必须检查被引用对象;物理删除对象的事务必须检查及处理关联记录,双方均采用串行化模式。逻辑删除保留业务对象,查询时过滤删除与隐藏状态。博客服务端检查角色继承、作者所有权、撤权版本、SSH 发布和访问授权,业务用户不需要各建数据库身份。

受保护访问遇到数据库查询、身份或哈希校验错误时直接拒绝,不回退为公开内容,也不使用过期的授权结果。博客需将会话和已签发访问凭据绑定到对应版本;数据库只持久化版本和哈希,不执行 HTTP 或 SSH 授权。

旧文件账户迁移

驱动验收程序 使用当前 accounts.rs 的凭据和授权字段构造迁移副本,原样保存完整 Argon2id PHC。PHC 包含算法、版本、参数、盐和哈希;不导入明文,不重新哈希旧凭据。文章查阅口令也保存独立加盐的完整 PHC。

旧授权 新角色
enabled=false BANNED
reader MEMBER
publisher AUTHOR
admin MASTER

迁移先校验两个文件的账号集合和字段,再在单次事务中写入账户、路径、公钥和完成标记。源文件保留;失败不留部分数据,同一来源重复执行由完成标记识别。缺少对应授权的凭据必须人工核对,不自动提升权限。

该程序是迁移验收样例,不读取生产文件。ChuBlog 需要配套实现停写、源文件权限校验、备份、生产文件读取、计数核对和切换流程。哈希计算、参数升级、密码限流和公钥格式校验也由博客完成。

评论、互动与容量

评论分页使用 ORDER BY created_at, id,下一页以最后一条的时间和 id 为游标,避免同一时间记录遗漏。样例建立文章和时间索引;热度可按活动互动与可见评论聚合、稳定排序,并在串行化事务内重算计数。权重、时间衰减和防刷规则由博客定义。

点赞或收藏将主体、文章及类别作为稳定去重键,只在活动状态改变时更新计数。重复取消和删除不得重复扣减;计数字段的 CHECK 拒绝负数。删除评论和互动应和相应计数、审计一起提交。

接入基线建议限制评论为 256 个 Unicode 字符且 UTF-8 不超过 768 字节,用户名 3 至 32 个 ASCII 字符,单条发布路径 256 字节,SSH 公钥 1024 字节。博客还应限制每用户路径数量、请求体和累计配额,逐字段限制不能替代整行容量校验。数据库默认 4096 字节页,整行超限会在 WAL 前拒绝;无长行或溢出存储。

标量索引键按 UTF-8 字节计算,默认配置最多 128 字节,覆盖 32 字节作者名、一个分隔符与 80 字节文章标识。有效上限还取决于页大小和 B+ 树分支数,密集旧配置可能仍只容纳 64 字节;不截断键。原索引无需重建即可打开,首次写长键会更新文件头的键长能力;写入长键后不得降级到仅支持 64 字节的旧二进制。

运行验收

前提是已按门禁说明重建 release 动态库、服务端和引导程序,且本地有 ChuBlog 的实际 Rust 驱动及 Cargo 依赖缓存。验收不使用 Docker,也不验证 Dockerfile 的镜像源。

  1. 准备当前构建的 chusql-server 与 csql-bootstrap 的绝对路径。

  2. 从 ChuSQL 根目录运行以下命令,替换两个二进制路径。驱动默认读取相邻 ChuBlog 仓库,可通过 --driver 指定其他路径。

    python3 examples/blog/test-business.py \
      --server /path/to/chusql-server \
      --bootstrap /path/to/csql-bootstrap \
      --driver ../ChuBlog/external/ChuSQL-RustDriver
    
  3. 确认输出 blog business: real driver, restart and cold backup restore passed。日志和测试 Cargo 清单位于 logs/blog-business/;临时数据库与备份副本自动删除。

程序只使用临时目录和本机随机端口,单任务编译 Rust 验收程序。业务验收后启动连续关联写入,收到至少十次提交回执后强杀测试服务,再在重启和备份副本中核对全部回执及明细 / 计数一致性。它验证迁移、完整 PHC 校验、并发注册、权限变更、文章管理状态、索引重建、稳定评论分页、重复操作、计数与容量拒绝,并在服务重启和停机备份副本中重新核对业务数据。不据此宣称博客 HTTP、SSH、文件访问控制、匿名身份合并或生产迁移已实现。