blacklist 数据库设计
黑名单服务负责决定“哪些设备上的哪个应用,应卸载还是终止进程”,并保存设备执行后的反馈。理解本服务要分开看三件事:应用处置策略、策略适用的设备范围、设备实际执行结果。配置存在、审批通过、设备命中、执行成功不是同一个状态,不能用某一张表的行数互相替代。
当前源码对应 5 张 MySQL 表和 1 个 TDengine 超级表模型。2026-09-18 测试环境结构采集发现 MySQL ik_apk 有 7 张表、57 列,TDengine blacklisted 有 1 个超级表、46 张子表、0 张普通表。MySQL 采集时间为 20:50:56、TDengine 为 20:51:18(Asia/Shanghai)。本文只用元数据与源码核对,未读取业务记录、调用业务接口或验证设备实际执行。
阅读入口
- 策略、审批与生效版本:主表为何同时保留正式值和草稿,如何解释状态。
- 规则匹配与历史范围关系:当前规则链路与仍保留的渠道、MAC、地区关系。
- 设备执行反馈与时序记录:卸载明细、按天杀进程反馈和 report 推送历史补充。
- 分表、索引与查询指引:按策略、设备、时间窗口查数据时如何选表和理解索引边界。
- 结构差异与维护线索:注释滞后、额外表列、核验边界。
- MySQL 全量实测字典:含额外对象的物理类型、可空性、默认值、索引、约束。
- TDengine 实测字典:超级表字段、标签与子表数量。
数据源与所有权
| 存储 | 代码选择 | 提供的配置与实测库 | 所有权和用途 |
|---|---|---|---|
| MySQL | 普通 Mapper 使用默认 master | datasource.blacklist → ik_apk | blacklist 维护策略、兼容范围和卸载反馈 |
| TDengine | AppKillRecordMapper 的 @DS("tdBlacklistedKillCallback") | datasource.td_blacklisted_kill_callback → blacklisted | blacklist 维护应用杀进程反馈 |
| Redis / 本地缓存 | AppBlacklistedRedisDAO、@Cacheable | 共享连接配置,未采集实际键 | 配置及兼容范围的派生缓存,不是配置事实源 |
| 规则存储 | RuleBusinessApi / RuleRunUtil | 由 rule 服务管理 | businessType=2(BLACK_LIST)和策略 ID 关联,不是本库关系表 |
| 流程存储 | BpmProcessInstanceApi | 由 bpm 服务管理 | 流程实例与审批历史,不复制到本服务建一套流程表 |
配置证据:doc/数据库设计管理/nacos/blacklist-server.yaml:8、:16;数据库定义为同目录 datasource.yaml:121、:362。这些文件是提供的配置副本,不能证明运行中进程已加载同一版本。
主表继承 BaseDO,其他 4 个 MySQL DO 不继承审计基类。主表实库另有 tenant_id,不因 Java 未声明就认定冗余:租户插件可根据上下文参与 SQL;提供配置将四张 flow_blacklisted_* 业务子表和 app_kill_record 列为租户忽略表。设备入口显式设置租户 1。不要给这些关系表补写并不存在的 creator/deleted/tenant_id 字段。
从配置到反馈
图中都是应用调用、消息或逻辑关联,不是数据库外键。ik_apk 实测外键数为 0。一个配置可对应多个设备结果;结果需要借助配置 ID 才能解释包名和操作类型,设备关联使用 MAC 与 CPU 信息。配置删除还可能删除 MySQL 反馈,TDengine 记录并不随同清理,因此反馈留存范围也不相同。
全部源码持久化对象
以下源码基准目录为 ik_project/yudao-cloud/yudao-module-blacklist/yudao-module-blacklist-biz/src/main/java/cn/iocoder/yudao/module/blacklist/。
| 对象 | Java 模型及证据 | 业务含义 | 字段清单 |
|---|---|---|---|
app_blacklisted | dal/dataobject/blacklisted/AppBlacklistedDO.java:18 | 应用处置策略与审批状态 | 策略页 |
flow_blacklisted_channel | dal/dataobject/blacklisted/FlowBlacklistedChannelDO.java:17 | 兼容渠道范围 | 范围页 |
flow_blacklisted_mac | dal/dataobject/blacklisted/FlowBlacklistedMacDO.java:19 | 兼容 MAC 范围 | 范围页 |
flow_blacklisted_region | dal/dataobject/blacklisted/FlowBlacklistedRegionDO.java:15 | 兼容国家地区范围 | 范围页 |
flow_blacklisted_device | dal/dataobject/blacklisted/FlowBlacklistedDeviceDO.java:14 | 设备卸载反馈 | 反馈页 |
app_kill_record | dal/dataobject/blacklisted/AppKillRecordDO.java:18 | 按天、设备、策略记录杀进程次数 | 反馈页 |
@KeySequence 是跨数据库适配注解,不作为 MySQL 存在序列对象的证据。静态常量、Redis 派生字段、页面 VO 的统计结果不计入物理列;TDengine tbname 单独按子表定位信息解释。
黑名单结构差异与维护线索
本库体现了从卸载配置、旧审批和人工范围绑定,逐步转到统一 BPM 与规则引擎的业务演进。表名、注释和列没有始终同步变化,因此本页将“代码已明确的新语义”“结构兼容遗留”“尚未核验的数据问题”分开 记录。本次没有修改数据库、业务代码或历史文档,不依据额外表列提出自动删除。
对照结果
2026-09-18 的 MySQL ik_apk 快照包含 7 张表、57 列。当前 5 个 MySQL DO 共映射 40 个字段,均在对应表存在;5 张当前表合计 43 列,其中 3 列没有直接 DO 属性。其余 14 列分布在两张未发现当前服务映射的表。
| 范围 | 当前代码与实测区别 | 解释及维护线索 |
|---|---|---|
| app_blacklisted.type | 当前枚举 0 卸载、1 杀进程;DO 和库注释写为 1 删除、0 线程 | 以当前操作枚举和控制器分流解释新行为。存量数据是否存在其他编码未读取核验 |
| valid(主表及范围关系) | 当前枚举 2 待修改、3 待移除;旧注释顺序相反 | 当前业务按枚举运行,不能用旧注释生成审批判断或统计条件 |
| app_blacklisted.release_info | 实库 JSON,当前 AppBlacklistedDO 无此属性 | 注释涉及早期生效版本快照;当前代码用正式字段与 draft 管理版本,本服务当前 Java/XML 未发现读写该列 |
| app_blacklisted.flow_status | 实库 varchar(64),当前 DO 无此属性 | 旧文本流程状态仍留存;当前状态由 bpm_status / process_instance_id 表达,未核验其他版本是否仍用 |
| app_blacklisted.tenant_id | 实库 bigint、非空、默认 1,BaseDO 未声明 | 租户插件按上下文参与,不归类成普通废弃列 |
| flow_blacklisted_channel.id、flow_blacklisted_device.id | Java Long,实库 int | Java 承载范围大于数据库列范围;不等于当前溢出,数据量与增长余量未读取 |
| AppKillRecordDO.blackListId | Java Integer / 实测 TDengine INT TAG;MySQL 策略 ID 为 bigint/Long | 两侧 ID 范围不同,跨库长期容量需要单独评估;未发现实际超界的证据 |
| AppKillRecordDO.tbname | Java 声明且有计算 getter,实库 DESCRIBE 不列出 | 按子表定位信息处理,不计为缺失普通列 |
| AppKillRecordDO.dataKey | 旧注释出现 cpu+mac,getter 实际 mac+cpuId | 文档以 getter 为准;拼接无分隔符,不将其描述为数据库生成 ID |
| flow_blacklisted_region.draft | DO 声明类型处理,但未显式设置 autoResultMap | 只记录和渠道/MAC 映射声明的不同;未运行读取验证,不能据此直接判定功能失效 |
| 杀进程 opCount | 服务使用 COUNT,表另有 frequency | opCount 是记录数量,不是累计杀进程次数,详见反馈页 |
实库额外表
| 表 | 全部实测列 | 可确认的范围 |
|---|---|---|
| app_uninstall_detail | id, mac, package_name, cpu, create_time | 表注释为早期卸载明细;当前 blacklist 反馈写 flow_blacklisted_device,当前模块 Java/XML 未发现本表映射 |
| flow_blacklisted_flow | id, blacklisted_id, process_instance_id, flow_status, type, business_key, reason, create_time, update_time | 表注释为黑名单与流程关联;当前流程入口通过 BPM API 与主表实例 ID 关联,当前模块 Java/XML 未发现本表映射 |
两表实测都只有主键索引,没有实测外键。完整类型、空值规则和默认值保留于物理字典。表名及注释支持其历史用途线索,不能证明数据为空、已经弃用,或其他旧服务/报表从不访问。
当前范围检索没有发现本服务独立 ES 索引模型,也没有发现本服务 MySQL 动态表规则。TDengine 只有 app_kill_record 超级表模型;实测对象与该模型对应。Redis 是额外的派生键空间,见范围页,没有把 Redis 内容冒充数据库结构快照。
后续维护时应同时检查的业务关系
- 修改处置类型或枚举时,同时检查主表注释、客户端协议、后台统计分流和两类反馈来源,避免只更新某一处字典。
- 修改规则时,检查 rule 的 BLACK_LIST 绑定及审批变量;不要因旧范围表仍有数据就当成当前规则条件,也不要跳过兼容入口的存在。
- 调整审批字段时,检查哪些字段参与
IncludeInBpmDraft、正式值何时替换,以及免审批角色路径;名称修改与包名修改当前不是相同草稿语义。 - 解释执行效果时,分别标明覆盖数、反馈记录数、frequency、服务时间和设备时间;删除后的历史数据保留范围也要标明。
这些是未来业务变更时的维护检查点,不是本次修改数据库的要求。