引言
- 在门店中台长期运行过程中,行政区划代码(province / city / area)会因政府区划调整、数据迁移等原因出现旧码。
- 本次任务需要批量修正“非上海门店”的 area / city 字段,确保与国家行政区划最新版本保持一致。
需求拆解
- 找到所有需更新门店:通过业务报表 + 人工确认得到门店清单。
- 获取正确行政区编码:比对国家统计局最新区划发布表。
- 生成脚本并在生产库执行:保证幂等、安全、可回滚。
脚本生成思路
- 源数据整理至 CSV:
STORE_CODE,STORE_TYPE,OLD_AREA,NEW_AREA
。 - 使用简单 Python 模版批量输出:
import csv, datetime
tpl = "update site_store set area = {new} where store_code = '{code}' and store_type = '{typ}';"
with open('mapping.csv') as f, open('update.sql','w') as out:
for row in csv.DictReader(f):
out.write(tpl.format(**row)+'\n')
- 模板优势:
- 可读性强,后期维护仅需修改 CSV。
- 支持追加其他字段(如 city)而无需改脚本主体。
执行前校验
-
备份:
- 利用
CREATE TABLE site_store_bak AS SELECT * FROM site_store WHERE store_code IN (...)
备份受影响行。
- 利用
-
常量检查:
SELECT COUNT(1) FROM site_store_bak
与脚本行数一致。- 编码有效性:通过
sys_area
字典表校验new_area
均存在。
最佳执行姿势
- 会话设置:
SET SERVEROUTPUT ON
WHENEVER SQLERROR EXIT SQL.SQLCODE
- 使用
@update.sql
执行,遇错即停。 - 分批提交:
- 每 500 条 COMMIT 一次,减少回滚体积。
校验与回滚
-
快速校验:
SELECT COUNT(*) WHERE area = new_area
验证成功率。
-
聚合对比:
SUM(old_area)
vsSUM(new_area)
。 -
回滚方案:若发现误更新,使用
MERGE
将备份表写回原表。
常见坑
- 行锁争抢:门店表被其他业务写入,可在夜间窗口操作。
- 错误编码:脚本中若写错
WHERE
条件,可能更新全国门店。务必在测试库实测并EXPLAIN PLAN
确认命中行。 - 权限问题:生产执行需 DBA 协助,提前走变更流程。
优化与扩展
- 改用 MERGE INTO 一次完成:
MERGE INTO site_store s USING tmp_area_map m
ON (s.store_code = m.store_code AND s.store_type = m.store_type)
WHEN MATCHED THEN UPDATE SET s.area = m.new_area;
- 加
CHECK(area IN (SELECT id FROM sys_area))
防止脏数据。 - 自动化校验:脚本执行完触发 Jenkins Job,对比异常差异并出报警。
总结
- 批量数据脚本需求看似简单,核心在于 生成可靠脚本 + 完善备份校验。
- 小型场景用单条
UPDATE
直观易读;大规模可考虑MERGE
或 ETL 工具。 - 数据治理应在源头加约束,降低后期修补成本。
脱敏说明:本文所有出现的表名、字段名、接口地址、变量名、IP地址及示例数据等均非真实, 仅用于阐述技术思路与实现步骤,示例代码亦非公司真实代码。 示例方案亦非公司真实完整方案,仅为本人记忆总结,用于技术学习探讨。
• 文中所示任何标识符并不对应实际生产环境中的名称或编号。
• 示例 SQL、脚本、代码及数据等均为演示用途,不含真实业务数据,也不具备直接运行或复现的完整上下文。
• 读者若需在实际项目中参考本文方案,请结合自身业务场景及数据安全规范,使用符合内部命名和权限控制的配置。版权声明:本文版权归原作者所有,未经作者事先书面许可,任何单位或个人不得以任何方式复制、转载、摘编或用于商业用途。
• 若需非商业性引用或转载本文内容,请务必注明出处并保持内容完整。
• 对因商业使用、篡改或不当引用本文内容所产生的法律纠纷,作者保留追究法律责任的权利。
Copyright © 1989–Present Ge Yuxu. All Rights Reserved.