8月5号新增筛选条件
商户预警筛选功能设计一个「看起来简单」的筛选功能背后隐藏了几个值得深挖的架构判断。一、需求回顾这个功能的起点是一句话连续3天未交易的通过审核商户记录下来方便查哪天有哪些人不交易。随着需求的展开它演变成了一个带有多维筛选的预警系统按公司信息搜索公司名/法人/注册号按审核状态过滤已通过/待审核/已驳回按指定上级手机号查其所有下级的流失数据每个筛选维度背后都有一个值得说说的架构决策。二、筛选维度一公司信息搜索数据来源公司信息法人、注册号、公司名本属于 cn_user_company但我们选择了反规范化——在每日快照写入时把这些字段冗余到 cn_user_churn_warning_record。为什么不联表查最直接的方案是查询时 JOIN cn_user_company但我没有这么做。原因历史快照语义快照记录的是「统计那一天用户的状态」。如果用户之后修改了公司信息JOIN 拿到的是现在的公司信息而不是快照时间点的。冗余字段保证了历史快照的完整性。查询性能cn_user_company 有近万行高频查询时 JOIN 每次都要关联冗余后直接走快照表索引。筛选简洁搜索直接 LIKE business_name 或 LIKE register_number不需要跨表。代价冗余字段在公司信息变更后不自动同步但快照本来就是历史记录这个代价可以接受。三、筛选维度二审核状态过滤设计决策// 前端默认传 companyStatus 1后端 SQL 加过滤if testcompanyStatus ! nulland r.company_status #{companyStatus}/if默认值的选择是这里最重要的决策默认 status1已通过而不是「全部」。理由运营看这个页面的目的是「找需要跟进的活跃商户」未审核或被驳回的商户在这个场景下几乎没有运营价值。所以默认过滤掉降低认知负担。但允许选「全部/待审核/已驳回」给运营留了灵活空间——比如想看「即使是待审核用户也3天没交易」的情况。四、筛选维度三指定上级手机号这是最有技术含量的一个维度也是我做过几次方案选择的地方。数据结构系统的邀请关系通过两个字段记录inviter_id: 直接上级inviter_path: /10/25/30/ 完整邀请链路径inviter_path 是一种树形结构的路径压缩存储用 LIKE 可以高效查任意层级的下级-- 查 user_id25 的所有下级直接间接WHERE inviter_path LIKE %/25/%方案选择Java层 vs SQL层我考虑了两种实现方式方案ASQL子查询AND w.user_id IN (SELECT user_id FROM cn_user WHERE inviter_path LIKE %/X/%)方案BJava层处理// 先查下级列表ListLong subordinates cnUserMapper.getInviterIds2(targetUserId);// 再传给Mapper做IN过滤query.setUserIdList(subordinates);选择方案B理由报错友好手机号不存在时可以提前返回「该用户不存在」而不是静默返回空数据代码清晰查下级和过滤预警是两个独立逻辑放在一起的子查询难以维护符合项目风格getInviterIds2 在项目中已有多处复用不新造轮子扩展灵活下级 ID 列表可以在 Service 层做更多处理如限量、排重但方案B有个隐患下级列表可能非常大间接下级可能数千甚至上万。IN 列表过长会导致 SQL 性能下降。当前数据规模下没有问题但上规模后需要考虑分页或改用关联查询。五、一个踩坑记录XML 不转义在实现「下级过滤」时我在 CnUserMapper.xml 里写了and u.user_id #{getUserId} 在 XML 里是标签起始符必须写成 lt;。这导致 MyBatis 解析 XML 失败整个应用启动退出码1。正确写法and u.user_id lt;gt; #{getUserId}这是 XML 开发中最经典的低级错误之一。MyBatis Mapper 文件是 XML 格式SQL 里涉及比较运算符时必须转义原符号 XML 转义 lt; gt;严格来说 不强制但建议转义 lt;gt; lt;更好的防护方式是用 ![CDATA[...]] 包裹含有特殊字符的 SQL 片段![CDATA[ and u.user_id #{getUserId} ]]CDATA 块内的内容不会被 XML 解析器处理可以写原始 SQL 字符更直观。六、数据快照的语义边界筛选功能的背后其实是「快照表」和「实时联表查询」之间的权衡。快照表的核心价值是历史可追溯 查询性能但它有一个固有的语义问题快照是某一时刻的状态不随时间自动更新。这对筛选有直接影响筛选字段 数据时效 可能的语义问题business_name 快照时间点 用户改了公司名后快照里是旧名字legal_person 快照时间点 同上company_status 快照时间点 状态变更后快照不反映last_trade_time 快照时间点 每天更新较准确当前处理方式每次手动统计或定时任务跑时ON DUPLICATE KEY UPDATE 会刷新当天快照公司信息随之更新。所以实际上每天的快照是当天最新状态只有历史快照如昨天的才可能有偏差。对于运营来说看最新一次快照默认行为时数据是准确的。七、架构总结这个筛选功能的设计体现了几条可以复用的原则原则 体现反规范化换查询效率 冗余公司字段进快照表避免 JOIN默认值决定用户心智 默认 status1降低认知负担Java层做报错SQL层做过滤 下级查询在 Service 层控制边界SQL 层做 IN 过滤XML 特殊字符必须转义 → lt;gt;或用 CDATA 块快照语义需明确边界 快照是时间点状态每日更新保证最新快照准确性筛选功能不难但把它做对——既高效又语义清晰——需要在每个维度上都做出合理的判断。这大概是架构工作的本质不是找最复杂的解而是找在当前约束下最合适的解。先读一下现有的 Mapper 和 Service 代码再写这篇分析。先读一下现有的 Mapper 和 Service 代码再写这篇分析。智能体读取商户预警相关代码思考▼

相关新闻

从零做一个自己的 CLI

从零做一个自己的 CLI

从零做一个自己的 CLI 引言 装过 Claude Code 或 Codex CLI 的人都有同感:终端里敲一行命令,在哪个项目文件夹都能用,不用点开浏览器,也不用先找脚本在哪。 这篇文章做两件事:第一,给已经能跑的 Agent 加…

2026/10/4 15:39:03 阅读更多 →
运算放大器非理想特性解析:从直流精度到动态响应的工程实践

运算放大器非理想特性解析:从直流精度到动态响应的工程实践

1. 从“理想”到“现实”:运算放大器的两面性如果你问一个刚接触模拟电路的学生,运算放大器是什么,他大概率会告诉你:一个增益无穷大、输入阻抗无穷大、输出阻抗为零、带宽无穷大的“神器”。没错,这就是教科书上定义的…

2026/10/4 15:40:18 阅读更多 →
不止影音娱乐!智慧病房专用IPTV系统,解锁病房全新服务形态

不止影音娱乐!智慧病房专用IPTV系统,解锁病房全新服务形态

不止影音娱乐!智慧病房专用IPTV系统,解锁病房全新服务形态随着智慧医院建设持续升级,传统病房电视功能单一、适配性差的短板愈发凸显。区别于普通家用、商用IPTV,智慧病房专用IPTV系统深耕医疗专属场景,搭载多项独有核…

2026/10/4 16:20:36 阅读更多 →

最新新闻

欧姆龙PLC与MCGS组态的5层电梯控制系统完整方案

欧姆龙PLC与MCGS组态的5层电梯控制系统完整方案

做这套5层电梯控制系统,其实起因很朴素:学校实训室需要一套能稳定演示电梯运行逻辑的微型装置,而我又想完整跑一遍 Omron 欧姆龙 PLC 和 MCGS 组态从选型、接线到联调刷机的全流程。项目做完后回头看,真正有门槛的并不是梯形图本身…

2026/10/5 15:49:19 阅读更多 →
如何为项目写一份高效的CLAUDE.md?AI编程协作实战指南

如何为项目写一份高效的CLAUDE.md?AI编程协作实战指南

给项目配一份CLAUDE.md这事,听起来特别像"写文档",但实际做起来完全是另一码事。我做AQ-Chat(一个把实时聊天和大模型对话揉在一起的应用)时,被Claude Code坑过很多次——不是它能力不行,而是它每…

2026/10/5 15:49:19 阅读更多 →
多目标跟踪核心:卡尔曼滤波与匈牙利算法原理及实战调优

多目标跟踪核心:卡尔曼滤波与匈牙利算法原理及实战调优

做多目标跟踪(MOT)的开发者,大概率都和我一样,曾经把卡尔曼滤波和匈牙利算法当成必须背下来的名字,却在项目里只知道调用现成代码。这两个算法听起来吓人,实际拆开,一个负责“猜位置”&#xff…

2026/10/5 15:49:18 阅读更多 →
二叉树前序遍历全解析:递归、迭代、Morris与实战优化

二叉树前序遍历全解析:递归、迭代、Morris与实战优化

前序遍历这道题在LeetCode和力扣上基本上是二叉树入门的第一道坎,也是“二叉树的遍历”里最容易被问出花样的考点。不管是刚刷题的新手,还是面试前冲刺的求职者,前序遍历都是必须彻底吃透的基础操作。 这道题本身不难,难的是把思…

2026/10/5 15:49:18 阅读更多 →
WD 2TB移动硬盘磁头损坏开盘换头数据恢复实战解析

WD 2TB移动硬盘磁头损坏开盘换头数据恢复实战解析

1. 故障诊断:磁头损坏叠加长时间通电,是如何把“可恢复”拖成“高风险”的手头这块盘是一位客户送来的WD西部数据2TB移动硬盘,2.5英寸规格,插上电脑后盘体有规律的“咔哒、咔哒”敲击声,系统里完全不认盘。客户说这盘是…

2026/10/5 15:49:18 阅读更多 →
开源健身教练平台Workout.cool:训练计划与进度追踪实战解析

开源健身教练平台Workout.cool:训练计划与进度追踪实战解析

最近逛GitHub的时候翻到一个挺有意思的项目:Workout.cool,定位是“现代化开源健身教练平台”。顺手把仓库拉下来跑了一遍,又把文档和代码过了一遍,今天这篇就把这个项目掰开揉碎聊一聊——它到底解决了什么问题、训练计划和进度追…

2026/10/5 15:48:18 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →