数据库设计

Clara 52 张核心表结构、关键字段与关系,插件自建表的命名与规范参考。

05 · 数据库设计

DDL 源码:[install/schema.php](../install/schema.php)(`clara_schema()` 返回 DDL 数组,`{P}` 为表前缀占位符,安装时替换为实际前缀如 `clara_`)。引擎统一 InnoDB + utf8mb4\_unicode\_ci。

新装站点由安装向导执行全量 DDL;存量站点升级走后台「系统工具 → 数据库升级」(对比 schema 声明增量执行)。

1. 表清单总览(52 张核心表 · install/schema.php 建表,另有 cron_runs 等升级增量表)

领域表用途
系统`settings`KV 配置(站点设置 / 插件启用列表 / 插件配置)
用户`users`用户主表(账号/头像/组/经验/签到统计/隐私/记住我 token)
用户`user_groups`用户组(perms JSON / is\_admin / min\_exp 门槛 / auto\_upgrade)
用户`user_group_maps`用户 ↔ 附加组多对多映射
用户`follows`关注关系(uk user+target)
内容`forums`版块(parent\_id 树 / type 1分类2版块 / perms JSON 覆盖 / moderators 逗号uid / 统计冗余)
内容`forum_categories`版块子分类(版块内话题分类:forum\_id + name + sort;发帖可选、版块页 ?cat= 筛选、后台版块编辑页增删改)
内容`threads`主题(计数冗余 / is\_top 置顶 / is\_essence 精华 / is\_closed / status 软删 / category\_id 子分类 / tags 逗号分隔 / last\_post\_at 排序键 / bounty\_amount+bounty\_cid 悬赏托管 / best\_post\_id 最佳答案)
内容`posts`回帖(reply\_post\_id 楼中楼引用链 / is\_anonymous 匿名 / status 软删)
内容`topics`专题聚合(专辑/合集:forum_id/name/description/cover/auto_tag/auto_kw/status/sort/thread_count 冗余,聚合详情页与总览页展示)
内容`topic_threads`专题 ↔ 主题关联(uk topic+thread 幂等;sort 排序)
内容`attachments`附件(type=文件/网盘链接 / driver/path/url 云存储位置 / code 网盘提取码 / thread\_id+post\_id 关联 / price+currency\_id 出售 / perm\_type+perm\_groups 下载权限 / downloads 统计)
内容`attachment_purchases`附件购买记录(uk attachment+user 幂等;price/currency\_id 成交快照)
互动`polls`投票主表(uk thread / max\_choices 最多可选 / expires\_at 截止 / voters 参与人数)
互动`poll_options`投票选项(poll\_id / text / votes 票数 / sort)
互动`poll_votes`投票记录(uk poll+option+user 防重投)
互动`likes`点赞(uk user+target+target\_id,target 区分主题/回帖)
互动`favorites`收藏(uk user+thread)
财务`currencies`货币定义(code/name/sign/is\_default)
财务`user_currency`用户余额(uk user+currency)
财务`currency_logs`货币流水(amount/after 快照/type/note)
财务`credit_rules`积分规则(event 事件 / currency\_id / amount 正奖负扣 / daily\_limit 每日上限 0 不限 / enabled)
财务`credit_logs`积分发放记录(uk event+operator+source+user 去重防刷 / log\_date 每日上限计数;惩罚扣减失败自动回滚占位)
成长`exp_logs`经验流水(amount/after/type)
签到`checkins`签到记录(uk user+check\_date;rewards JSON,补签标记 `{"repair":1}`)
商城`memberships`会员套餐(price/duration\_days/checkin\_mult 签到倍率/name\_color)
商城`user_memberships`用户会员记录(start\_at/end\_at,多套餐叠加取最晚)
商城`avatar_frames`头像框(effect 特效 20 种/color/color2 双色/price/duration\_days/membership\_id 专属)
商城`user_frames`用户头像框(uk user+frame,expire\_at 过期)
荣誉`medals`勋章(type 1手动2自动;cond\_type/cond\_value 自动条件)
荣誉`user_medals`用户勋章(uk user+medal 幂等;is\_wear 佩戴)
社交`gifts`礼物定义
社交`gift_logs`赠送记录(from/to/thread/message)
运营`card_batches` / `cards`卡密批次与卡密(status/bind\_uid 绑定/expire\_at)
运营`invitation_codes`邀请码(creator/used\_by/expire\_at)
运营`announcements`公告(type/start\_at/end\_at 定时)
通知`notifications`站内通知(is\_read;notify() 合并同目标未读)
邮件`mail_logs`SMTP 发送日志(status/error)
系统`login_logs`登录审计日志(login\_name 尝试账号/user\_id 匹配用户/ip/user\_agent/success/reason 失败原因;Cron 按保留天数自动清理)
系统`search_logs`搜索日志(keyword 去重 + hits 计数 + last_at,全文搜索热词统计)
系统`cron_runs`计划任务运行记录(name/ok/summary/ran\_at;每任务保留最新一条 + 30 天历史;v2026.09.06 经数据库升级建表)
财务`transfer_logs`用户转账流水(from\_uid/to\_uid/currency\_id/amount/fee,transfer\_execute 事务内写入)
内容`thread_purchases`付费主题购买记录(uk thread+user 幂等;成交价快照)
互动`forum_follows`版块关注(uk user+forum;版块页关注者列表与通知)
私信`pm_conversations` / `pm_messages`私信会话(双方独立删除标记)与消息正文;权限形态 `perm_enabled('pm')`
运营`reports`举报(type/target\_id/reporter\_id/reason/status/handler\_id,后台队列处理)
系统`admin_logs`后台操作日志(module/action/target/detail/operator\_id,AdminLogsController 展示)
系统`ip_bans`IP 封禁(ip/reason/expires\_at;ip\_ban\_guard() 请求期拦截)
系统`audit_logs`发帖审核日志(AdminAuditController 过审/拒绝留痕)
系统`online`在线用户(uid/session\_id/ip/last\_at;60s 限流清理,online\_users() 统计)
GEO`geo_bot_stats`AI 爬虫访问监控(bot/day/hits/last\_at/sample\_url/geo\_endpoints 命中端点;GeoService::recordBotHit 写入,列由数据库升级补建)

插件自建表(前缀 `plugin_{目录名}_`):

表所属插件用途
`plugin_ai_reply_providers`ai\_replyAI 提供商列表(base\_url/key/model/启用/失败熔断计数)
`plugin_ai_reply_logs`ai\_reply调用日志(触发源/请求/回答/状态/耗时,后台日志面板与 retry 用)
`plugin_ai_writer_titles`ai\_writer标题池(forum\_id/category\_id/title/status 状态机 pending→preview/published/failed/content\_preview 暂存正文/thread\_id 已发布关联/retry\_count/tags\_preset 预设标签)
`plugin_ai_writer_tasks`ai\_writer发布任务(forum\_id/category\_id/bot\_uid 机器人/interval\_sec≥300 或 daily\_time/freq\_type/model/temperature/max\_tokens/prompt 任务级覆盖/batch\_count/next\_run\_at/enabled)
`plugin_ai_writer_jobs`ai\_writer异步生成任务(type=title/article/preview、topic、count\_target 目标数/inserted 实际入库/skipped/status pending→running→done/fail、token 轮询凭证、fail\_streak)
`plugin_ai_writer_logs`ai\_writer生成日志(action=title/article/publish、Token 出入/耗时/触发源 lazy·cron·manual·preview、error)
`plugin_api_hub_log`api\_hubAPI 工具箱解析记录(user/service/input\_url/title/result\_url/cover\_url/cost\_cid/cost\_num/created\_at)
`plugin_rank_scores`rank(已废弃:site_rank v1.x 起改纯查询聚合,无自建表,卸载零残留——见 06 § 4.2)
`plugin_thread_visitors`thread\_visitors帖子访客记录(thread\_id/user\_id/visited\_at,定期清理)
`plugin_member_wall`member_wall会员墙上墙记录(付费上墙,购买走行锁 + 事务范例)
`plugin_ad_slots` / `plugin_ad_orders`ad_self广告位定义与投放订单(坑位容量制;按天/周/月/年计费,懒过期 + 事务内行锁复查防超卖)
`plugin_lottery_threads` / `participants` / `slots` / `draws` / `winners`lottery回帖抽奖 / 概率抽奖 / 转盘抽奖五表(服务端权威判定 + 扇区签名)
`plugin_ks_categories` / `questions` / `attempts` / `answers` / `users` / `logs`ks_exam入站考试六表(题库分类/题目/组卷/作答/通过用户/日志)
`plugin_geo_qa_factory_queue`geo_qa_factoryGEO 问答草稿队列(AI 生成 → 人工审核 → 一键发布并采纳)

2. 核心表结构详解

users(用户主表)

id, username(uk), nickname, email(uk), password,            -- 账号
avatar, avatar_frame,                                         -- 头像 + 佩戴头像框
group_id(idx),                                                -- 主组
email_verified, status,                                       -- status>=0 可登录,-1 封禁
signature, bio, gender, homepage, location,                   -- 资料
thread_count, post_count,                                     -- 冗余计数
exp,                                                          -- 经验值
checkin_days, checkin_total, checkin_last_date,               -- 签到统计
remember_token,                                               -- 记住我(64 hex)
invite_by, last_login_at, last_ip, created_at,
privacy_no_follow, privacy_no_reply, privacy_hide_social,     -- 隐私开关
pwd_code, pwd_code_expires,                                   -- 找回密码验证码
login_fails, locked_until                                     -- 登录安全闭环(连续失败计数 / 临时锁定到期)

user\_groups(用户组 — 权限与等级合一)

id, name, color,          -- 组名与徽章色
perms TEXT,               -- 权限 JSON {"view":1,"thread":1,...}(16 键,含 attach/poll/bounty/anon_reply 内容形态键)
is_system, is_admin,      -- 系统组 / 管理员组(全权限)
min_exp, auto_upgrade,    -- 经验门槛 / 是否参与经验自动升级(等级组)
sort

等级组 = `auto_upgrade=1 AND is_admin=0`,经 `exp_level_groups()` 按 min\_exp 升序读取;管理员/版主等特殊组不参与自动升降级,前端也不显示经验进度。

forums(版块)

id, parent_id(idx),       -- type=1 分类(容器)、type=2 版块(发帖)
type, name, description, icon, sort,
thread_count, post_count, last_thread_id, last_post_at,   -- 冗余统计
perms TEXT,               -- 版块级组权限覆盖 JSON {"{gid}":{"view":1,"reply":0}}
moderators VARCHAR(255),  -- 版主 uid 逗号分隔
status,                   -- 0 关闭(仅管理员可见)
seo_keywords, seo_description, created_at

threads / posts(内容)

threads: forum_id(idx), user_id(idx), title, content(MEDIUMTEXT),
         views, replies, likes, favorites, gifts,          -- 计数冗余
         is_top, is_essence, is_closed, status,            -- status=1 正常 / 0 隐藏(回收站)
         deleted_at,                                      -- 前台软删时间戳(回收站保留计时;NULL = 后台隐藏,不自动清理)
         tags VARCHAR(150),                                -- 半角逗号分隔(FIND_IN_SET 查询)
         created_at, updated_at, edited_at,
         last_post_at(idx 组合), last_post_user_id         -- 列表排序与「最后回复」展示

posts:   thread_id(idx), user_id(idx), reply_post_id,      -- 楼中楼:指向被回复的 post id
         content(MEDIUMTEXT), likes, status, created_at

checkins(签到)

user_id, check_date(DATE, uk 组合), days,    -- 当日连签天数快照
rewards VARCHAR(500),                        -- 奖励 JSON;补签记录为 '{"repair":1}'
created_at

credit\_rules / credit\_logs(积分规则引擎)

credit_rules:  id, event VARCHAR(40),        -- thread_create / post_create / be_liked /
                                             -- be_post_liked / be_favorited / thread_delete / post_delete
               currency_id, amount DECIMAL,  -- 正数奖励 / 负数扣除
               daily_limit INT(0 不限), enabled, created_at
credit_logs:   id, user_id, event, currency_id, amount,
               operator_uid,                 -- 触发人(他人触发类事件;自赞不发放)
               source_id,                    -- 主题/回复 id(与 operator_uid 组成去重键)
               log_date DATE,                -- 每日上限计数键
               created_at
               UNIQUE(event, operator_uid, source_id, user_id)   -- 去重:点赞反复切换只发一次

发放链路:`CreditRuleService::apply()` → INSERT IGNORE 占位 → `currency_change(type='credit_rule')` 入账 → 失败(惩罚余额不足)回滚占位;规则长缓存 `Cache('credit_rules')`,后台变更主动失效。

3. 实体关系(ER 摘要)

user_groups 1──n users(group_id 主组)        user_group_maps n──n(附加组)
users 1──n threads / posts(user_id)
forums 1──n threads(forum_id);forums 自关联(parent_id 分类树)
threads 1──n posts(thread_id);posts 自关联(reply_post_id 楼中楼链)
users n──n threads(likes: user+target+target_id / favorites: user+thread)
users 1──n user_currency / currency_logs(经 currencies 关联)
users 1──n user_memberships n──1 memberships(叠加,取 end_at 最晚)
users 1──n user_frames n──1 avatar_frames(uk user+frame)
users 1──n user_medals n──1 medals(uk user+medal 幂等)
users n──n follows(user_id → target_id)
users 1──n notifications / checkins / exp_logs

4. 数据一致性约定

  • 冗余计数:threads.replies、forums.thread\_count/post\_count、users.thread\_count/post\_count 均为冗余字段,随发帖/回帖/删除同步增减;漂移时用后台「系统工具 → 重算统计」对账。
  • 软删除:threads/posts 用 status=-1;列表查询统一走 `thread_visibility_sql()`(管理员见全部,普通用户只见 status=1)。
  • 唯一键幂等:签到(user+date)、勋章(user+medal)、头像框(user+frame)、点赞(user+target+target\_id)均靠唯一键防重。
  • 流水快照:currency\_logs/exp\_logs 记录变动后余额(after 列),便于审计与防刷统计(当日计数查询)。
  • JSON 字段:user\_groups.perms、forums.perms、checkins.rewards 为 JSON 文本;写入方负责 `json_decode` 容错(`?: array()` 兜底)。

5. settings 表关键键位

键内容
`site_name` / `site_desc` / `site_url` / `brand_letter` / `site_favicon`站点基础信息
`reg_email_verify` / `invite_enabled`注册策略
`admin_login_email_verify`后台登录 2FA 开关
`thread_edit_enabled` / `thread_edit_window` / `membership_edit`帖子编辑策略
`exp_enabled` / `exp_thread` / `exp_post` / `exp_checkin` / `exp_daily_*`经验体系
`checkin_reward` 相关 / `checkin_repair_enabled` / `checkin_repair_cost` / `checkin_repair_monthly`签到与补签
`forum_layout` / `forum_layout_user_switch`版块列表布局(list/side + 访客切换)
`storage_driver` / `qiniu_*` / `oss_*` / `cos_*`云存储
`smtp_*`邮件
`upload_max_size` / `upload_exts`上传限制
`attach_enabled` / `attach_max_size` / `attach_exts`通用附件(开关/大小/白名单)
`allow_anonymous_reply`匿名回复开关
`enabled_plugins` / `installed_plugins` / `plugin_config_{dir}`插件状态与配置
`group_guest`游客组 id
`trusted_link_hosts`友链信任域名白名单
`notify_sound_enabled` / `notify_sound`通知提示音
`cron_key`计划任务外部触发密钥(/cron.html?key= 校验;后台系统工具可重新生成)
`trusted_proxies`可信代理清单(XFF 采信白名单:空 = 默认 127.0.0.1,::1;none = 全不信任;支持 CIDR 如 172.16.0.0/12)
`currency_reconcile_last`货币对账最近报告 JSON(ran_at/accounts/mismatch/negatives,每日 Cron 与手动对账写入,后台「业务对账」卡片展示)

本文档随系统发布维护;如发现与当前版本不符,欢迎到社区反馈。