
AI 辅助数据建模从业务问题反向推导数据模型的设计思路大家好我是朱大喜。传统数据建模是先设计表再想能回答什么业务问题——问题在于等你建好表发现回答不了核心问题时返工成本已经很高了。今天聊一种反向建模法从业务问题出发用 AI 辅助推导数据模型。一、正向建模 vs 反向建模不是语法问题是思维问题传统建模流程正向业务需求 → 分析需求 → 抽象实体 → ER图 → 建表 → 发现少了字段 → ALTER TABLE → ...反向建模流程业务问题 → 分解为数据子问题 → 每个子问题需要什么字段 → 字段间什么关系 → 建表两者的核心区别正向建模从数据本身出发有哪些实体、它们什么关系反向建模从数据用途出发要回答什么问题、需要什么信息。graph LR subgraph 正向: 先设计再验证 A[订单实体] -- B[用户实体] A -- C[商品实体] B -- D[会员实体] C -- E[品类实体] Z[业务问题:br/为什么新用户首单br/转化率在下降?] -.-|发现缺字段| B end subgraph 反向: 从问题出发 W[业务问题:br/为什么新用户首单br/转化率在下降?] -- X[需要的数据:br/新用户注册时间br/首次浏览到下单时长br/各环节转化率br/同期对比数据] X -- Y[数据模型:br/用户注册流水表br/行为路径明细表br/下单漏斗宽表] end style Z fill:#faa,stroke:#333 style W fill:#afa,stroke:#333二、用 AI 做问题到模型的分解反向建模最难的一步是把业务问题拆成数据子问题。这件事 AI 非常擅长因为它本质上是语义到数据模型的映射。我们让 AI 来完成一次完整的反向建模过程第一步业务问题 → 数据子问题假设业务方提出我们想分析为什么最近新用户的次日留存率持续下降。# 用 LLM 将业务问题拆解为数据子问题 def decompose_business_question(question: str) - list: 让 AI 把模糊的业务问题拆成可量化的数据子问题 为什么需要拆解 业务方的问题常常是感觉比如留存下降了 但留存有7日留存、30日留存下降可能是绝对值下降也可能是增速放缓 AI 的职责是帮我们把模糊问题变成精确问题 prompt f 作为数据分析师请将以下业务问题拆解为可量化的数据子问题。 每个子问题必须包含 1. 需要什么数据具体到字段级别 2. 数据的粒度天/小时/用户级 3. 对比维度同比/环比/分群对比 业务问题{question} 请以结构化格式输出。 response llm.generate(prompt) return parse_sub_questions(response)AI 的典型输出[ { 子问题: 新用户次日留存率的整体趋势如何, 数据需求: { 核心字段: [user_id, register_date, is_active_d1], 粒度: 日粒度, 数据源: dws.user_retention_daily, 计算逻辑: 次日登录用户数 / 当日新注册用户数 } }, { 子问题: 不同渠道来源的新用户留存是否有差异, 数据需求: { 核心字段: [user_id, channel, register_date, is_active_d1], 粒度: 用户级 日粒度, 数据源: dwd.user_register_detail JOIN dwd.channel_dim, 分组维度: channel } }, { 子问题: 新用户在产品内的首日行为路径是否有变化, 数据需求: { 核心字段: [user_id, page_name, event_time, duration, session_id], 粒度: 事件级, 数据源: dwd.user_behavior_detail, 分析维度: 首日浏览页面数、核心功能使用率、路径跳转序列 } }, { 子问题: 最近是否有版本更新或运营活动影响了新用户体验, 数据需求: { 核心字段: [event_date, event_type, event_name, affected_users], 粒度: 事件级, 数据源: dim.product_event_dim dwd.user_campaign_log, 关联条件: event_date 留存开始下降的日期 } } ]第二步数据子问题 → 数据模型设计有了子问题接下来就是从子问题反推表结构def derive_model_from_questions(sub_questions: list) - dict: 从数据子问题推导数据模型设计 核心逻辑 1. 收集所有子问题需要的字段 2. 分析字段间的关联关系1:1 / 1:N / N:M 3. 按实体聚合生成 DWD 层的事实表和维度表 4. 按分析频率生成 DWS 层的汇总表 # 第一步汇总所有需要的字段 all_fields {} for q in sub_questions: for field in q[数据需求][核心字段]: # 标记每个字段被哪些问题依赖 if field not in all_fields: all_fields[field] set() all_fields[field].add(q[子问题]) # 第二步通过字段在问题中的共现关系推断实体 # 比如 user_id 和 register_date 总是在一起出现它们属于用户实体 entities cluster_fields_by_cooccurrence(all_fields, sub_questions) # 第三步生成 DDL models [] for entity in entities: ddl generate_ddl(entity, all_fields) models.append(ddl) return { entities: entities, ddl_templates: models, field_to_question_map: all_fields # 每个字段能回答哪些问题 }第三步AI 生成的数据模型实际产出-- AI 推导新用户留存分析相关的数据模型 -- 1. 用户注册明细事实表DWD 层 -- 每行 一个用户的一次注册事件 CREATE TABLE dwd.dwd_user_register_detail ( user_id BIGINT COMMENT 用户ID, register_date STRING COMMENT 注册日期, register_hour INT COMMENT 注册小时0-23用于分析不同时段的留存差异, channel STRING COMMENT 渠道来源从归因数据解析, device_type STRING COMMENT 设备类型iOS/Android/Web, app_version STRING COMMENT 注册时 App 版本号用于归因版本更新的影响, invite_user_id BIGINT COMMENT 邀请人ID如果有, register_ip STRING COMMENT 注册IP脱敏处理, dt STRING COMMENT 数据日期分区 ) PARTITIONED BY (dt STRING) STORED AS ORC; -- 2. 用户留存汇总表DWS 层 -- 每行 一个用户在某一日的留存状态 -- 为什么存成汇总表留存计算是每天都要跑的常规任务 -- 预先汇总好ADS 层直接查询避免每天重复扫 DWD 明细 CREATE TABLE dws.dws_user_retention_daily ( user_id BIGINT COMMENT 用户ID, register_date STRING COMMENT 注册日期, channel STRING COMMENT 渠道来源, -- 各天留存标记 is_active_d1 BOOLEAN COMMENT 次日是否活跃, is_active_d2 BOOLEAN COMMENT 第2日是否活跃, is_active_d3 BOOLEAN COMMENT 第3日是否活跃, is_active_d7 BOOLEAN COMMENT 第7日是否活跃, is_active_d30 BOOLEAN COMMENT 第30日是否活跃, -- 首日行为特征 first_day_pv INT COMMENT 注册首日 PV, first_day_duration BIGINT COMMENT 注册首日时长(秒), first_day_core_used INT COMMENT 首日使用核心功能次数, dt STRING COMMENT 统计日期 ) PARTITIONED BY (dt STRING) STORED AS ORC;三、AI 辅助建模的优势与边界优势AI 不会遗漏隐含的维度人类建模时容易遗漏一些大家都知道但没人提的维度。比如上面的版本号字段app_version——在讨论留存下降时很少有人会第一时间想到留存下降是因为新版 App 出了 bug。AI 的价值在于它不知道什么是大家都知道的所以它会追问。当你给它新用户留存下降这个问题AI 会自动联想到是哪个渠道的用户留存下降了渠道维度是哪个版本的留存下降了版本维度下降了多久了之前有没有类似的情况时间维度下降的用户有什么共同特征用户画像维度这些追问会让数据模型从一开始就包含这些分析维度而不像传统建模那样等出了问题再ALTER TABLE ADD COLUMN。边界AI 不知道业务真实结构# AI 可能会犯的错误 # ⚠️ 假设 AI 推导出一个用户 → 订单 → 退款的简单模型 # 但实际上你们的退款流程是 # 用户申请 → 客服审核 → 财务打款 → 用户确认 # 中间有三层审批和多个状态这是 AI 推导不出来的 # 所以 AI 生成的模型需要人工校验 def human_review_ai_model(ai_generated_model: dict, domain_experts: list) - dict: 人工校验 AI 生成的数据模型 校验重点 1. 实体关系是否正确AI 可能把 1:N 理解成 N:M 2. 业务状态机是否完整审批流、状态扭转 3. 计算口径是否和公司现有指标定义一致 4. 数据安全和合规敏感字段是否做了脱敏或权限控制 issues [] for table in ai_generated_model[tables]: # 校验一主键是否唯一 if not has_unique_key(table): issues.append(f{table[name]} 缺少主键或唯一约束) # 校验二状态字段是否覆盖所有业务状态 if table.get(status_fields): for status_field in table[status_fields]: business_states get_known_business_states(status_field) ai_states table[enum_values].get(status_field, []) missing set(business_states) - set(ai_states) if missing: issues.append( f{table[name]}.{status_field} 缺少状态值: {missing} ) # 校验三敏感字段是否标注 sensitive_fields [mobile, id_card, bank_card, real_name] for field in table[columns]: if any(s in field[name].lower() for s in sensitive_fields): if field.get(security_level) ! high: issues.append( f{table[name]}.{field[name]} 是敏感字段但未标注安全等级 ) return issues四、反向建模的实践流程经过我们团队的实践一套AI 辅助 人工把关的建模流程是这样的graph TB A[业务方提问题] -- B[AI 拆解为数据子问题] B -- C[AI 分析所需字段和关系] C -- D[AI 生成初版数据模型br/事实表 维度表 汇总表] D -- E{人工校验} E --|业务规则不完整| F[补充业务状态机br/补充审批流关系br/补充合规要求] E --|指标口径不统一| G[对齐现有指标定义br/确认计算逻辑] E --|实体关系错误| H[修正 JOIN 关系br/修正主外键] E --|通过| I[输出最终模型] F -- I G -- I H -- I I -- J[生成 DDL ETL 脚本] J -- K[部署到测试环境验证] K -- L[数据质量检查] L -- M{质量问题?} M --|有| E M --|无| N[上线] style B fill:#afa,stroke:#333 style C fill:#afa,stroke:#333 style D fill:#afa,stroke:#333 style E fill:#ffa,stroke:#333 style N fill:#afa,stroke:#333关键节点是人工校验。AI 能大幅加速从 0 到 1的建模过程但从 1 到 100的精细化调整还需要懂业务的建模人员来完成。人机协作的黄金分工是AI 做问题分解、字段推导、初版 DDL 生成、关系推断人做业务规则校验、指标口径确认、合规性审核、性能优化分区策略、索引设计五、总结AI 辅助数据建模的核心思路是反向推导——从要回答什么问题出发而不是从有什么数据出发。这样做的好处是不建废表每张表的每个字段都能倒推到某个具体的业务问题不存在建了但没人用的情况不返工因为分析维度在建模阶段就考虑到了不用等到用的时候发现缺字段可追溯每个字段都可以追溯到它要回答的业务问题数据血缘非常清晰。落地建议选一个业务方怨气最大的数据需求做试点比如每次分析都要 JOIN 七八张表用反向建模法重构这部分数据模型。效果出来了再推广。不要试图一下子重构整个数仓——那和推倒重来没区别。这周的 10 篇文章到这里就结束了覆盖了架构进阶和性能优化两大主题。从平台架构到执行引擎从 ClickHouse 高可用到 Numba 性能优化从 AI 看板到 Agent 探索再到数仓分层和数据建模希望对你有所帮助。下周见