2. 供应商主数据模型设计
供应商主数据模型是整个SRM平台的“地基”。如果主数据模型设计得不好,后续的准入、绩效、寻源、结算等模块都会反复打补丁。本节围绕供应商唯一标识、组织架构、联系人、银行信息、资质证照五类核心字段展开,并进一步讨论多组织、多语言、多币种场景下的模型扩展方式。
一、供应商唯一标识:主键与业务编码分离
供应商唯一标识要解决两个问题:一是系统内部如何唯一定位一条供应商记录,二是业务人员如何用可读的编码找到它。推荐做法是“代理主键 + 业务编码”双轨制。
- 代理主键 supplier_id:由系统生成,建议使用雪花ID或UUID,永不复用、永不修改,作为所有外键关联的锚点。
- 业务编码 supplier_code:如
SUP-2024-000871,按“前缀-年份-流水号”规则生成,便于人工识别与对账。 - 统一社会信用代码 tax_no:作为自然键参与查重,但不做主键,因为境外供应商可能没有该代码。
查重逻辑建议采用“强匹配 + 弱匹配”两级:统一社会信用代码完全一致时判定为重复;名称相似度超过阈值(如85%)且法人代表或注册地址一致时进入人工复核队列。这样既避免误合并,也避免同一供应商被重复建档。
二、组织架构:多组织建模的核心
供应商的组织架构字段不是简单存一个“公司名称”,而要能表达集团—子公司—工厂的层级关系。核心字段包括:
legal_entity_name:法人实体名称,用于合同签署主体。parent_supplier_id:自关联外键,指向集团母公司,形成树形结构。org_type:组织类型,枚举值如 GROUP、SUBSIDIARY、BRANCH、PLANT。registration_country/registration_address:注册国与注册地址。
通过 parent_supplier_id 自关联,可以在一张表内表达任意深度的集团树。查询某集团下所有子公司时,使用递归CTE即可,无需额外建表。
三、联系人、银行信息与资质证照
这三类信息都属于“一对多”关系,必须拆成子表,不能塞进主表字段。
- 联系人表 supplier_contact:字段包括 contact_id、supplier_id、name、role(销售/财务/质量)、phone、email、is_primary。一个供应商可有多个联系人,但主联系人唯一。
- 银行信息表 supplier_bank:字段包括 bank_id、supplier_id、bank_name、account_no、swift_code、currency、is_default。多币种场景下,同一供应商可维护多个币种账户。
- 资质证照表 supplier_certificate:字段包括 cert_id、supplier_id、cert_type(营业执照/ISO9001/排污许可证)、cert_no、issue_date、expire_date、file_url、status。证照到期前30天触发预警。
**** **** 1234,仅授权角色可查看完整账号。四、多组织、多语言、多币种扩展
当平台服务集团型客户时,同一供应商可能同时与多个采购组织发生业务关系。此时不能把“供应商—采购组织”关系写死在主表,而应引入关系表 supplier_org_relation,字段包括 supplier_id、purchase_org_id、supplier_status、payment_terms、currency。这样同一供应商在A组织是合格供应商,在B组织可能仍是潜在供应商。
多语言方面,供应商名称、地址、联系人职务等需要支持多语言展示。推荐使用翻译子表 supplier_i18n,字段为 supplier_id、lang_code(zh-CN/en-US/ja-JP)、field_name、field_value。主表只存默认语言值,查询时按用户语言回退到默认值。
多币种方面,银行账户、报价、合同金额都可能涉及不同币种。模型上应遵循“金额 + 币种 + 汇率”三件套,汇率单独存 exchange_rate 表,记录 from_currency、to_currency、rate、effective_date。任何金额字段都必须带 currency_code,禁止出现无币种的裸金额。
五、建模落地要点
第一,所有子表都必须带 supplier_id 外键并建立索引,避免全表扫描。第二,状态字段统一使用枚举编码而非中文文本,便于多语言展示。第三,任何“一对多”信息都不要在主表用逗号拼接,否则后续查询和权限控制会非常困难。第四,主数据变更要留痕,建议增加 supplier_change_log 表记录字段级变更前后值。
下面给出一份可直接参考的建表片段,展示主表与银行子表的关键字段定义:
CREATE TABLE supplier (
supplier_id BIGINT PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL UNIQUE,
tax_no VARCHAR(32),
legal_entity_name VARCHAR(200) NOT NULL,
parent_supplier_id BIGINT,
default_lang VARCHAR(10) DEFAULT 'zh-CN',
status VARCHAR(20) DEFAULT 'POTENTIAL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE supplier_bank (
bank_id BIGINT PRIMARY KEY,
supplier_id BIGINT NOT NULL,
bank_name VARCHAR(200),
account_no VARCHAR(128),
swift_code VARCHAR(32),
currency CHAR(3) NOT NULL,
is_default BOOLEAN DEFAULT FALSE,
FOREIGN KEY (supplier_id) REFERENCES supplier(supplier_id)
);
CREATE INDEX idx_bank_supplier ON supplier_bank(supplier_id);
判断模型是否合格,可以用三个问题自检:能否在不改表结构的前提下新增一种证照类型?能否让同一供应商在不同采购组织下拥有不同状态?能否在界面上按用户语言显示供应商名称?如果三个答案都是“能”,说明模型具备足够的扩展性。