第2章:SQL在风控评分中的角色
2.1 SQL与规则引擎的配合模式
在风控评分系统中,SQL与规则引擎并非替代关系,而是分层协作。规则引擎负责业务逻辑的编排与决策树遍历,而SQL负责在数据层完成特征提取、聚合计算与批量匹配。两者通过“特征预计算 + 规则后决策”的流水线协同工作。
核心配合原则:SQL做“重计算、轻逻辑”,规则引擎做“轻计算、重逻辑”。SQL将海量原始数据压缩为高价值特征,规则引擎基于这些特征执行可配置的决策流。
| 配合维度 | SQL负责 | 规则引擎负责 |
|---|---|---|
| 数据来源 | 从关系库、Hive、Kafka实时流中提取原始数据 | 接收SQL输出的特征向量(如近30天逾期次数) |
| 计算复杂度 | 窗口函数、多表JOIN、聚合、去重 | 条件判断、阈值比较、权重叠加 |
| 变更频率 | 低(表结构、索引、分区策略) | 高(规则阈值、决策树分支、策略版本) |
| 性能瓶颈 | I/O、数据倾斜、大表关联 | 规则数量、循环嵌套、外部服务调用 |
| 典型场景 | 特征工程、黑名单批量匹配、额度聚合 | 反欺诈规则链、授信决策、人工审核分流 |
2.2 SQL在特征计算中的典型用法
特征计算是风控SQL最密集的战场。一个典型的实时风控请求,需要在毫秒级完成数十个特征的提取。以下是三种最常用的SQL特征计算模式:
- 窗口聚合特征:使用
PARTITION BY+ORDER BY窗口函数,计算用户近7天/30天的交易次数、金额总和、最大间隔等。 - 时序偏移特征:利用
LAG()/LEAD()获取上一次交易时间、金额,计算间隔与增长率。 - 多表关联特征:通过
LEFT JOIN关联黑名单、设备指纹、联系人网络表,聚合出关联风险计数。
-- 窗口聚合特征:近30天交易次数与金额
SELECT
user_id,
COUNT(*) OVER (PARTITION BY user_id ORDER BY trans_time
ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS trans_cnt_30d,
SUM(amount) OVER (PARTITION BY user_id ORDER BY trans_time
ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS trans_amt_30d,
MAX(amount) OVER (PARTITION BY user_id ORDER BY trans_time
ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS max_amt_30d
FROM transaction_log
WHERE trans_time >= NOW() - INTERVAL '30 days';
-- 时序偏移特征:上次交易时间间隔
SELECT
user_id,
trans_time,
LAG(trans_time) OVER (PARTITION BY user_id ORDER BY trans_time) AS last_trans_time,
EXTRACT(EPOCH FROM (trans_time - LAG(trans_time)
OVER (PARTITION BY user_id ORDER BY trans_time))) AS interval_seconds
FROM transaction_log;
-- 多表关联特征:关联黑名单与设备指纹
SELECT
a.user_id,
COUNT(DISTINCT b.black_id) AS black_contact_cnt,
COUNT(DISTINCT c.device_id) AS device_cnt
FROM user_base a
LEFT JOIN blacklist b ON a.contact_phone = b.phone
LEFT JOIN device_fingerprint c ON a.user_id = c.user_id
GROUP BY a.user_id;
2.3 SQL在规则匹配中的典型用法
规则匹配阶段,SQL通常以批量判黑和实时阈值过滤两种形态出现。批量判黑用于预计算,将命中规则的用户打标;实时阈值过滤则在请求链路中直接返回匹配结果。
| 匹配模式 | SQL实现方式 | 性能要求 | 典型场景 |
|---|---|---|---|
| 批量判黑 | 多表JOIN + CASE WHEN + 子查询 | 分钟级,可接受离线调度 | 每日黑名单更新、团伙挖掘 |
| 实时阈值过滤 | 索引覆盖 + 单表简单WHERE | 毫秒级,RT < 50ms | 登录风控、支付拦截 |
| 规则链匹配 | UNION ALL + 优先级排序 | 百毫秒级 | 多层规则叠加评分 |
-- 批量判黑:命中任意一条规则即标记
SELECT
user_id,
CASE
WHEN trans_cnt_30d > 100 THEN 'R01_高频交易'
WHEN max_amt_30d > 50000 THEN 'R02_大额异常'
WHEN black_contact_cnt >= 1 THEN 'R03_关联黑名单'
ELSE 'PASS'
END AS rule_hit
FROM user_feature
WHERE trans_cnt_30d > 100
OR max_amt_30d > 50000
OR black_contact_cnt >= 1;
-- 实时阈值过滤:索引加速
SELECT user_id, risk_level
FROM user_risk_cache
WHERE user_id = :uid
AND risk_level IN ('HIGH', 'CRITICAL')
AND expire_time > NOW();
2.4 SQL在分数聚合中的典型用法
分数聚合是风控评分的最后一公里。SQL需要将多个规则命中的分数进行加权求和、分段映射,并最终输出一个可解释的评分结果。常见的聚合模式包括:
- 加权总分:使用
SUM(weight * score)聚合多规则得分。 - 分段映射:通过
CASE WHEN将总分映射为A/B/C/D等级。 - 百分位排名:使用
PERCENT_RANK()窗口函数输出相对风险排序。
-- 加权总分 + 分段映射
WITH score_cte AS (
SELECT
user_id,
SUM(CASE rule_id
WHEN 'R01' THEN 10
WHEN 'R02' THEN 20
WHEN 'R03' THEN 30
ELSE 0
END) AS total_score
FROM rule_hit_result
WHERE user_id = :uid
GROUP BY user_id
)
SELECT
user_id,
total_score,
CASE
WHEN total_score >= 80 THEN 'D-高风险'
WHEN total_score >= 60 THEN 'C-中高风险'
WHEN total_score >= 40 THEN 'B-中风险'
ELSE 'A-低风险'
END AS risk_level
FROM score_cte;
-- 百分位排名:输出用户在全量中的风险位置
SELECT
user_id,
total_score,
ROUND(PERCENT_RANK() OVER (ORDER BY total_score DESC) * 100, 2) AS risk_percentile
FROM user_daily_score
WHERE dt = CURRENT_DATE;
2.5 SQL与NoSQL的对比
在高并发风控场景中,SQL与NoSQL并非二选一,而是互补共存。SQL擅长复杂关联与聚合,NoSQL擅长高吞吐键值查询与灵活schema。下表从风控视角对比两者的核心差异:
| 对比维度 | SQL(关系型) | NoSQL(如Redis、HBase) |
|---|---|---|
| 数据模型 | 结构化表、严格Schema | Key-Value、宽表、文档 |
| 特征计算 | 窗口函数、多表JOIN、聚合 | 不擅长,需在应用层实现 |
| 实时查询 | 依赖索引,复杂查询RT不稳定 | 单Key查询RT稳定 < 5ms |
| 批量处理 | 强项,支持复杂ETL | 弱项,批量扫描性能差 |
| 数据一致性 | ACID事务保障 | 最终一致性为主 |
| 风控典型用途 | 特征工程、规则匹配、评分聚合 | 缓存特征、黑名单、限流计数器 |
架构建议:在风控评分链路中,推荐“SQL计算 + NoSQL缓存”的混合架构。SQL负责离线/准实时的复杂特征计算,将结果写入Redis/HBase;实时请求链路直接从NoSQL读取特征,避免在线JOIN带来的性能抖动。这样既保留了SQL的强计算能力,又获得了NoSQL的高吞吐与低延迟。
2.6 本章小结
- SQL与规则引擎是分层协作关系,SQL做重计算,规则引擎做轻决策。
- SQL在风控评分中的三大典型用法:特征计算(窗口函数、时序偏移、多表关联)、规则匹配(批量判黑、实时过滤)、分数聚合(加权求和、分段映射、百分位排名)。
- SQL与NoSQL在风控架构中互补共存,SQL负责复杂计算与批量处理,NoSQL负责高并发缓存与键值查询。
- 掌握SQL在风控中的角色定位,是后续章节优化高并发评分SQL的基础。