71 lines
4.6 KiB
Markdown
71 lines
4.6 KiB
Markdown
---
|
||||
|
|
title: SQL 查询规范、只读执行边界与部署脚本规范
|
|||
|
|
source_status: user_confirmed_agent_rule
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# SQL 查询规范、只读执行边界与部署脚本规范
|
|||
|
|
|
|||
|
|
## 1. 交互式查询规范(临时取数)
|
|||
|
|
|
|||
|
|
- 只允许一条只读 `SELECT`、`WITH` 或 `EXPLAIN`;禁止 DDL、DML、管理命令、多语句、注释。
|
|||
|
|
- 禁止 `SELECT *`;使用显式字段和全限定表名(`wanshifu_dw.<table>`)。
|
|||
|
|
- 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)。
|