--- title: SQL 查询规范、只读执行边界与部署脚本规范 source_status: user_confirmed_agent_rule --- # SQL 查询规范、只读执行边界与部署脚本规范 ## 1. 交互式查询规范(临时取数) - 只允许一条只读 `SELECT`、`WITH` 或 `EXPLAIN`;禁止 DDL、DML、管理命令、多语句、注释。 - 禁止 `SELECT *`;使用显式字段和全限定表名(`wanshifu_dw.`)。 - JOIN 必须写明确关联条件,禁止笛卡尔积;写 JOIN 前先确认两侧粒度和唯一键,防止行数放大。 - 分区表做分区裁剪,非分区表允许全表扫描(不要为非分区表编造分区条件)。 - 按指标定义要求显式加业务时间过滤。 - 默认不暴露敏感明细字段。 - 超时上限:1800 秒。 **格式约定:**关键字大写;表名字段名小写;缩进 4 空格;SELECT 列表一行一个字段、逗号前置;复杂逻辑在生成脚本中加业务注释,只有在安全执行器要求时才删除注释。 **指标后缀语义(分析师标准,优先于数仓开发规范里的旧例子):** | 后缀 | 含义 | |---|---| | `cnt` | 非去重的事件/人次计数 | | `num` | 去重后的实体计数 | | `amt` | 金额 | > 注意:数仓开发规范里的示例是反过来的(`times`=非去重,`cnt`=去重)。分析师产出统一使用上表,冲突已裁决,见 [decisions.md](decisions.md)。 ## 2. 只读执行边界(JDBC / Kyuubi-Hive) - 默认关闭,需经安全评审后显式开启。 - 只放行单条 `SELECT`、`WITH`、`EXPLAIN`;要求全限定 `wanshifu_dw` 表名和时间/分区谓词;拒绝注释、`SELECT *`、DDL、DML、管理命令和高危函数。 - `Connection.setReadOnly(true)` 只是辅助信号,**不是安全边界**——Kyuubi 明确不支持它,真正边界是数据库只读权限 + Python 策略层与 Java JDBC 层的双重校验。 - 执行器只用 `executeQuery`,同时限制超时(120s 登录超时 / 30s 及以上按配置)和结果行数(默认导出上限 100,000 行且 100MB;聊天展示默认 100 行)。 - 普通查询不留文件;只有用户明确要求导出才保留最终文件,且需清理中间文件。 - **中文常量编码降级(重要坑点):**JDBC/Kyuubi 链路可能让中文字符串常量失真,导致中文显示为问号或精确过滤误返回 0 行。 - 默认继续提交原始 UTF-8 SQL,不预先改写中文条件。 - 出现空结果或异常结果时,先用同分区/时间范围内的纯 ASCII 条件 + `HEX(ENCODE(TRIM(field), 'UTF-8'))` 诊断,证明目标中文值确实存在且原条件未命中,才能判定是编码问题而非业务无数据。 - 只对已证明等价的精确 `=`/`IN` 条件做十六进制降级;`LIKE`、正则、范围、排序等依赖字符归一化的条件禁止自动转换,必须退回审查。 - 降级 SQL 必须重新走安全校验;执行记录要保留 `ENCODING_FALLBACK_APPLIED`、原始/实际 SQL 哈希及字面量映射。 - 十六进制过滤可能影响谓词下推,只作临时兜底;长期应修复链路的字符编码配置。 ## 3. 分析师取数脚本部署规范(ADS/MID) **触发条件:**只有用户在查询结果验证通过后明确要求生成部署脚本才执行;本环节只生成 SQL,**不执行、不建 WeData 任务、不部署、不提交审批**。 **命名:** | 层 | 前缀 | 分区表后缀 | 非分区表后缀 | |---|---|---|---| | ADS | `ads_analyze_` + 子类型(`ds`/`bi`/`ibigdata`) | `_d_v` | `_v` | | MID | `mid_analyze_` | `_d_v` | `_v` | > 注意:这套前缀是"分析师 Agent 规则",跟数仓开发规范里的 `ads_ds_`/`ads_bi_`/`ads_iBigdata_`、`mid_` 不同。本 Agent 场景一律用分析师规则,冲突已裁决,见 [decisions.md](decisions.md)。 **依赖:**只能依赖 DWD/DWS/DWM/DIM/MID;禁止依赖 ODS、ADS、其他脚本的临时表。 **分区字段:**统一用 `stat_date`;日表 `yyyyMMdd`、月表 `yyyyMM`、年表 `yyyy`;**周表的 `stat_date` 语义(周起始/周结束/其他业务日期)没有默认值,生成脚本前必须询问用户**。 **生命周期天数:**`bi`=365 天;`ibigdata`=90 天;`mid`=与下游一致;`ds`=需向需求方确认。 **输出内容:**每个任务只对应一张正式目标表;允许脚本内使用物理临时表但必须清理(命名 `tmp_{table}_{bizdate}_{sequence}`);产出应包含建表 SQL、写入 SQL、验证 SQL 和部署检查清单;默认不生成删除目标表的语句。 **运行时长上限:**1800 秒。 ## 相关 - 数仓分层、选表、分区规则见 [warehouse.md](warehouse.md)。 - 冲突裁决细节见 [decisions.md](decisions.md)。