数据库结构文档
Rin 使用 SQLite 数据库(通过 Drizzle ORM),共包含 12 张表。
表概览
users(用户表)
存储用户信息,支持账号密码、OAuth、QQ、邮箱等多种登录方式。
索引:
- 唯一索引
users_username_uniqueONusername
注意:
- 同一用户可通过多种方式登录(GitHub + QQ + 邮箱),
openid用于区分不同登录方式 email字段用于邮箱验证码登录,登录后 username 为完整邮箱地址
密码哈希规则:
users.password保存的是 SHA-256(无盐) 哈希值,格式为 64 位十六进制小写字符串,服务端登录时对输入的密码做同样的哈希计算后比对- 需要手动在 D1 数据库中为用户设置密码时,必须写入加密后的哈希值,直接填写明文密码会导致该账号无法登录
- 计算哈希值(Linux):
- 计算哈希值(macOS):
- 更新 D1 中的密码:
feeds(文章/动态表)
存储博客文章内容。
关系:
uid→users.id(文章属于一个用户)
moments(动态/朋友圈表)
存储用户发布的短动态。
关系:
uid→users.id(动态属于一个用户)
comments(评论表)
存储文章评论,支持游客评论。
关系:
feed_id→feeds.idON DELETE CASCADEuser_id→users.idON DELETE CASCADE(可为空)
注意:
- 游客评论时
user_id为空,使用guest_name/guest_email/guest_website记录游客信息
visits(访问记录表)
记录每篇文章的每次访问。
关系:
feed_id→feeds.idON DELETE CASCADE
注意:
- 此表记录原始访问数据,统计时通过
visit_stats表聚合
visit_stats(访问统计表)
存储文章的访问统计信息,使用 HyperLogLog 去重。
关系:
feed_id→feeds.idON DELETE CASCADE
friends(友链表)
存储友情链接。
关系:
uid→users.idON DELETE CASCADE
hashtags(标签表)
存储文章标签。
feed_hashtags(文章-标签关联表)
关联文章和标签的多对多关系。
关系:
feed_id→feeds.idON DELETE CASCADEhashtag_id→hashtags.idON DELETE CASCADE
注意:
- 复合主键为
(feed_id, hashtag_id),确保同一文章不会重复添加同一标签
info(系统配置表)
存储系统键值对配置。
索引:
- 唯一索引
info_key_uniqueONkey
常见 key 示例:
site.name- 网站名称site.description- 网站描述site.avatar- 网站头像site.page_size- 分页大小rss- RSS 启用状态- 其他运行时配置
cache(缓存表)
存储应用缓存数据。
约束:
- 复合唯一约束
cache_key_type_uniqueON (key,type)
索引:
idx_cache_typeONtypeidx_cache_keyONkey
邮件自动友链申请使用的 type 值:
friend.email:以申请人邮箱为key,存储其在途申请的状态(阶段、操作类型、JSON 载荷、验证码、截止时间等)。friend.email.lock:固定key为global,用于实现「同一时间仅允许一个申请」的并发锁。
友链分组使用的 type='client.config' 键:
friend_groups:管理员自定义的分组名 JSON 数组(不含默认分组)。friend_group_order:控制友链展示顺序的 JSON 数组,空字符串元素代表默认分组(「朋友们」),新建分组默认插入到它之后。
linked_accounts(第三方登录绑定表)
存储用户绑定的第三方登录账号(GitHub、Gitee、QQ、WeChat 等)。
关系:
user_id→users.idON DELETE CASCADE
注意:
- 同一用户可绑定多个第三方账号
- 同一第三方账号不可绑定到多个用户
表关系图
直接修改数据库注意事项
- 使用 Drizzle ORM 迁移:修改表结构时,应生成 Drizzle 迁移文件而非直接执行 SQL
- 禁止 DROP/RENAME:Cloudflare D1 不支持
DROP TABLE和RENAME TABLE,迁移需使用ALTER TABLE添加列 - 时间戳格式:所有时间戳使用 Unix 时间戳(整数,单位秒)
- 外键约束:SQLite 默认不强制外键约束,应用层负责维护数据一致性
- 游客评论:
comments.user_id可为空,删除对应用户时级联删除该用户的所有评论
sqlite_sequence 表
sqlite_sequence 是 SQLite 内部系统表,不需要手动创建或修改。
作用:
- 记录使用
AUTOINCREMENT的表的当前最大 ROWID - 确保
INTEGER PRIMARY KEY AUTOINCREMENT列的值单调递增,避免 ROWID 复用 - 每次插入新行时,SQLite 会自动从该表读取并更新序列值
注意:
- 这是 SQLite 自动维护的内部表,不应直接修改
- 如果某张表的序列值出现异常,可使用
UPDATE sqlite_sequence SET seq = N WHERE name = 'table_name'修复,但通常不需要