Skip to content

数据库设计

本文档详细说明 MagicPush 的数据库表结构、字段定义和迁移策略。


目录


1. 存储引擎

属性说明
数据库SQLite3 (better-sqlite3 同步 API)
文件路径默认 ./data/push_service.db(可通过 DB_PATH 环境变量配置)
日志模式WAL (Write-Ahead Logging),提升并发读写性能
外键约束已启用
时区默认东八区 Asia/Shanghai(可通过 TZ 环境变量覆盖)
持久化Docker 部署时通过 Volume 挂载到宿主机

2. ER 关系

users (1) ─────< (N) channels        (一个用户拥有多个渠道)


  (1) ─────< (N) endpoints           (一个用户拥有多个推送接口)
  │                                  │
  │                                  │
  │                    (N) endpoint_channels (N)    多对多: 接口与渠道的关联
  │                                  │
  (1) ─────< (N) push_logs          (用户的推送记录)

                    ├──> (N..1) endpoints   (可选外键)
                    └──> (N..1) channels    (可选外键)

users (1) ─────< (N) refresh_tokens   (用户的刷新令牌,用于吊销)

system_settings                      (全局 KV 键值对设置,无用户归属)

3. 表结构详情

3.1 users — 用户表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
usernameTEXTNOT NULL UNIQUE用户名
emailTEXTNOT NULL UNIQUE邮箱(登录凭证)
passwordTEXTNOT NULLbcrypt 哈希密码
avatarTEXT头像 URL
roleTEXTDEFAULT 'user'角色: admin / user
created_atDATETIMEDEFAULT now创建时间
updated_atDATETIMEDEFAULT now更新时间

3.2 channels — 渠道配置表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
user_idINTEGERFK → users.id所属用户
channel_typeTEXTNOT NULL渠道类型标识(如 telegram, bark)
nameTEXTNOT NULL渠道自定义名称
configTEXTNOT NULLJSON 格式的渠道配置参数
is_activeINTEGERDEFAULT 1是否启用: 1=启用, 0=禁用
created_atDATETIMEDEFAULT now创建时间
updated_atDATETIMEDEFAULT now更新时间

3.3 endpoints — 推送接口表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
user_idINTEGERFK → users(id) ON DELETE CASCADE所属用户
nameTEXTNOT NULL接口名称
tokenTEXTNOT NULL UNIQUE推送 Token(用于 API 调用)
descriptionTEXT接口描述
is_activeINTEGERDEFAULT 1是否启用
inbound_configTEXTJSON入站 Webhook 配置(数据来源模板等)
keyword_filterTEXTJSON关键词过滤配置
do_not_disturbTEXTJSON免打扰时段配置
last_used_atDATETIME最后使用时间
created_atDATETIMEDEFAULT now创建时间
updated_atDATETIMEDEFAULT now更新时间

3.4 endpoint_channels — 接口-渠道多对多关联表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
endpoint_idINTEGERFK → endpoints(id) CASCADE接口 ID
channel_idINTEGERFK → channels(id) CASCADE渠道 ID
UNIQUE(endpoint_id, channel_id)同一接口不能重复绑定同一渠道
created_atDATETIMEDEFAULT now绑定时间

3.5 push_logs — 推送记录表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
user_idINTEGERFK → users(id) CASCADE用户 ID
endpoint_idINTEGERFK → endpoints(id) SET NULL接口 ID
endpoint_nameTEXT接口名称冗余存储(便于查询展示)
channel_idINTEGERFK → channels(id) SET NULL渠道 ID
channel_typeTEXT渠道类型冗余存储
titleTEXT消息标题
contentTEXTNOT NULL消息内容
message_typeTEXTDEFAULT 'text'消息类型: text/markdown/html
statusTEXTNOT NULL状态: success / failed / skipped_dnd / pending
responseTEXT渠道原始返回结果
error_messageTEXT错误信息
ipTEXT请求来源 IP
created_atDATETIMEDEFAULT now推送时间

3.6 refresh_tokens — 刷新令牌表

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
user_idINTEGERFK → users(id) CASCADE用户 ID
tokenTEXTNOT NULL UNIQUE刷新令牌值
expires_atDATETIMENOT NULL过期时间
created_atDATETIMEDEFAULT now创建时间

3.7 system_settings — 系统设置表(KV 键值对)

字段类型约束说明
idINTEGERPK AUTOINCREMENT主键
keyTEXTNOT NULL UNIQUE设置键名
valueTEXTNOT NULL设置值
created_atDATETIMEDEFAULT now创建时间
updated_atDATETIMEDEFAULT now更新时间

常用设置项:

key类型默认值说明
registration_enabledbooltrue是否开放注册
dnd_global_enabledboolfalse免打扰功能全局开关

4. 数据库迁移策略

采用 try-catch ALTER TABLE 的增量迁移方式,在 server/src/database/init.js 中逐步添加新字段:

4.1 迁移方式

javascript
// server/src/database/init.js

// 新增字段时:try-catch 包裹,已存在则忽略
try {
  db.exec(`ALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user'`);
} catch (e) {
  // 字段已存在,忽略错误(正常情况)
}

4.2 迁移原则

  • 字段已存在时静默忽略(catch 后不做处理)
  • 新字段带默认值,不影响现有数据
  • 不做破坏性变更(不删除列、不修改类型)

4.3 已执行的迁移历史

迁移内容目标表说明
ip 字段push_logs记录请求来源 IP
endpoint_name 冗余字段push_logs避免联表查询
inbound_config 字段endpoints入站 Webhook 配置
keyword_filter 字段endpoints关键词过滤配置
do_not_disturb 字段endpoints免打扰时段配置
role 字段users用户角色区分

基于 MIT 许可证开源