4. 数据模型设计:材料价格信息的数据结构

材料价格信息的数据结构是联动体系的数据基石。一个设计良好的数据结构,需要同时满足采集端(供应商报价、市场询价)的录入效率,以及消耗端(定额库匹配、造价计算)的查询精度。本节围绕核心字段展开设计,并给出标准化的数据模型。

4.1 核心字段定义与业务含义

材料价格信息表(t_material_price)包含以下 7 个核心字段,每个字段均对应明确的业务规则:

字段名称 数据类型 主键/约束 业务说明
材料编码 VARCHAR(32) PK, NOT NULL 全局唯一标识,与定额库消耗量编码体系对齐
名称 VARCHAR(120) NOT NULL 国标/行业标准名称,禁止使用俗称
规格 VARCHAR(200) NOT NULL 包含型号、技术参数、等级,如“HRB400 Φ25”
单位 VARCHAR(10) NOT NULL 统一使用计量单位(t、m³、m、㎡、个)
含税价 DECIMAL(12,2) DEFAULT 0.00 含增值税专用发票价格,元为单位
除税价 DECIMAL(12,2) DEFAULT 0.00 扣除增值税后的裸价,用于计价取费
供应商 VARCHAR(100) NOT NULL 报价单位全称,支持多源比价
日期 DATE NOT NULL 价格采集/报价生效日期,用于时间序列分析
设计要点:材料编码必须与定额库中的“材料编码”字段保持完全一致,这是实现“价格→消耗量”联动的唯一外键桥梁。建议采用“大类码+中类码+顺序码”的层级编码规则(如 010101001),避免使用自增ID。

4.2 数据模型 E-R 关系与物理表结构

材料价格信息表与定额消耗量表之间通过材料编码建立一对多关系。一个材料编码在定额库中可能对应多条消耗量记录(不同定额子目),但在价格表中,同一编码+同一供应商+同一日期只允许一条记录。

核心关联逻辑:
t_quota_consumption.material_code = t_material_price.material_code
通过该关联,定额库中的每一条消耗量记录都能实时获取最新的含税价/除税价,实现动态调价。
材料价格信息与定额消耗量联动 E-R 图 定额消耗量表 t_quota_consumption PK 消耗量ID (consumption_id) FK 定额子目编码 (quota_code) FK 材料编码 (material_code) ← 关键 消耗量 (quantity) 损耗率 (loss_rate) 材料价格信息表 t_material_price PK 材料编码 (material_code) 名称 (name) 规格 (specification) 单位 (unit) 含税价 (price_tax_included) 除税价 (price_tax_excluded) material_code 联动计算规则 定额基价材料费 = Σ(消耗量 × 材料除税价) × (1 + 损耗率) 当价格表更新时,所有引用该材料编码的定额子目自动重算

4.3 物理建表 SQL(MySQL 语法)

以下为材料价格信息表的完整建表语句,包含索引设计和注释:

-- 材料价格信息表
CREATE TABLE t_material_price (
    material_code   VARCHAR(32)     NOT NULL COMMENT '材料编码(主键,与定额库对齐)',
    name            VARCHAR(120)    NOT NULL COMMENT '材料名称(国标)',
    specification   VARCHAR(200)    NOT NULL COMMENT '规格型号',
    unit            VARCHAR(10)     NOT NULL COMMENT '计量单位',
    price_tax_included DECIMAL(12,2) DEFAULT 0.00 COMMENT '含税价(元)',
    price_tax_excluded DECIMAL(12,2) DEFAULT 0.00 COMMENT '除税价(元)',
    supplier        VARCHAR(100)    NOT NULL COMMENT '供应商名称',
    price_date      DATE            NOT NULL COMMENT '价格生效日期',
    created_at      DATETIME        DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
    updated_at      DATETIME        DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
    PRIMARY KEY (material_code, supplier, price_date),
    INDEX idx_name (name),
    INDEX idx_price_date (price_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='材料价格信息采集表';
注意:主键采用联合主键(material_code + supplier + price_date),确保同一供应商在同一天对同一材料只能有一条报价记录。如果业务允许同一供应商一天多次调价,建议增加自增ID作为逻辑主键,并将原联合字段改为唯一索引。

4.4 字段设计中的关键避坑点

  • 编码长度预留:材料编码建议使用 VARCHAR(32),避免因编码规则扩展(如增加项目代号)导致截断。
  • 含税价与除税价分离:不要只存含税价然后通过税率计算除税价。不同供应商、不同材料的税率可能不同(13%、9%、3%),且历史税率可能调整,必须分别存储原始值。
  • 日期精度:使用 DATE 类型而非 DATETIME,因为价格通常以“天”为粒度生效。如果存在日内多次调价,可扩展为 DATETIME 并增加批次号。
  • 供应商去重:供应商字段应关联供应商信息表(t_supplier),通过 supplier_id 外键关联,避免同一供应商名称录入不一致(如“XX建材有限公司” vs “XX建材”)。

4.5 数据模型扩展建议(进阶)

在实际生产环境中,建议在上述核心字段基础上增加以下辅助字段,以提升数据治理能力:

扩展字段 数据类型 说明
税率 (%) DECIMAL(5,2) 增值税税率,用于校验含税价与除税价的换算关系
价格来源 VARCHAR(20) 枚举值:供应商报价/信息价/市场询价/历史参考
数据状态 TINYINT 0=待审核,1=已生效,2=已作废
备注 VARCHAR(500) 价格异常说明、运输方式、付款条件等
最佳实践:建议将材料价格信息表设计为增量追加模式,即每次采集都新增一条记录,而非覆盖旧数据。这样既能保留完整的价格历史轨迹,又便于后续进行时间序列分析、价格趋势预测以及审计追溯。