作为一名数据治理工程师,我最近刚完成了一个医药行业SAAS平台的网点数据重构项目。原始数据存在严重的分级混乱问题,经过两周的梳理和重构,最终形成了规范的两级分类体系。这个案例非常典型,相信对需要处理类似地域分类问题的同行会有参考价值。
先看原始数据的问题:所有网点被扁平化存储在一张表中,混杂了实际行政区划(如"重庆")、特殊渠道(如"KA")、线上平台(如"B端-药师帮")和模糊分类(如"其他")。更麻烦的是,部分分类存在业务数据关联,不能简单删除或合并。下面我会详细拆解整个治理过程的关键步骤和决策逻辑。
原始数据采用单级编码结构,主要包含三个字段:
通过抽样检查发现三个典型问题:
关键发现:通过统计各异常分类在业务表中的引用次数,确认"KA"、"第三终端部"等特殊分类虽然逻辑不规范,但都是活跃业务数据,不能直接删除。
与销售、财务部门沟通后,了解到这些"不规范"分类的实际用途:
同时发现报表系统已经存在大区划分(华东、华南等),但与行政区域存在包含关系冲突。例如:
基于业务实际需求,确立两级分类体系:
几个关键决策点:
建立新旧代码的转换对照表,核心规则包括:
| 原分类类型 | 处理方式 | 新一级分类 | 示例 |
|---|---|---|---|
| 省级行政区 | 按地理大区归类 | 华北/华东/华南/华西 | 上海→华东 |
| 港澳台地区 | 统一归为海外 | 海外 | 香港→海外 |
| 电商平台 | 单独归类 | 线上 | B端-药师帮→线上 |
| 特殊业务单元 | 保留原分类 | 其他 | KA→其他 |
实施要点:需要保留原始代码到新编码的映射关系,确保历史业务数据可追溯。
sql复制-- 新网点表结构
CREATE TABLE dim_network_node (
node_id VARCHAR(6) PRIMARY KEY, -- 新编码规则:1位类型+2位大区+2位顺序
parent_id VARCHAR(3), -- 所属大区代码
node_name VARCHAR(50) NOT NULL,
node_type CHAR(1) NOT NULL, -- R地区/O线上/S特殊
original_code VARCHAR(2) -- 原始代码,用于数据追溯
);
-- 大区维度表
CREATE TABLE dim_region (
region_id VARCHAR(2) PRIMARY KEY,
region_name VARCHAR(10) NOT NULL
);
编码规则设计:
数据清洗阶段:
分类转换阶段:
python复制def convert_category(old_code):
if old_code in ONLINE_PLATFORMS: # 电商平台
return '2', 'ONLINE', old_code
elif old_code in SPECIAL_UNITS: # 特殊业务单元
return '9', 'OTHER', old_code
elif is_overseas(old_code): # 海外地区
return '1', 'OVERSEAS', '00'
else: # 国内地区
region = get_region_by_province(old_code)
return '1', region, old_code
数据验证阶段:
采用"双跑"过渡方案:
sql复制-- 订单表改造示例
ALTER TABLE sales_order ADD COLUMN std_region VARCHAR(6);
UPDATE sales_order SET std_region =
(SELECT new_code FROM network_mapping WHERE old_code = sales_order.region);
主要修改点:
踩坑提醒:财务部门的返利计算模块对"KA"分类有硬编码,需要单独处理兼容。
这次重构最大的体会是:数据治理不能纯粹追求理论上的规范,必须兼顾业务实际。比如"第三终端部"这个分类,从数据模型角度看应该拆分,但实际业务中它对应着独立的销售团队和考核体系,强行规范化反而会影响业务运作。好的数据治理方案应该像这件案例一样,在规范性和实用性之间找到平衡点。