3. 数据库设计(上)

数据库设计是工程合同义务跟踪系统的数据基石。本章聚焦于概念模型(ER图)与逻辑模型(合同主表字段),为后续的义务分解、动态监控接口提供稳定的数据结构。

3.1 核心实体关系(ER图)

工程合同义务跟踪系统涉及四个核心实体:合同、合同义务、参与方、履行记录。它们之间的关系如下:

  • 合同 与 合同义务:一对多(1:N)。一份合同包含多项义务(付款、验收、提交资料等)。
  • 合同 与 参与方:多对多(M:N)。一份合同有甲方、乙方、监理方;一个参与方可参与多份合同。
  • 合同义务 与 履行记录:一对多(1:N)。一项义务可产生多次履行记录(如分期付款)。
设计原则: 合同主表只存储合同级静态属性,义务、参与方、履行记录均拆分为子表,确保数据无冗余、更新无异常。
工程合同义务跟踪系统 ER 图 合同 合同义务 参与方 履行记录 1 N M N 1 N 关系说明 合同 1→N 合同义务 合同 M←→N 参与方 合同义务 1→N 履行记录

3.2 合同主表字段设计

合同主表(contract)是系统的核心表,存储合同级静态信息。字段设计遵循最小化、标准化原则,避免将义务、参与方等动态数据混入主表。

字段名 数据类型 长度 约束 说明
id BIGINT — PK, AUTO_INCREMENT 自增主键
contract_code VARCHAR 50 UNIQUE, NOT NULL 合同编号(业务唯一标识)
contract_name VARCHAR 200 NOT NULL 合同名称
party_a VARCHAR 100 NOT NULL 甲方(发包方)
party_b VARCHAR 100 NOT NULL 乙方(承包方)
contract_amount DECIMAL (18,2) NOT NULL, DEFAULT 0.00 合同金额(元)
sign_date DATE — NOT NULL 签订日期
status TINYINT — NOT NULL, DEFAULT 0 状态:0-进行中,1-已完成,2-已终止
created_at DATETIME — NOT NULL 创建时间
updated_at DATETIME — NOT NULL, ON UPDATE 更新时间
字段设计要点:
  • contract_code 使用 VARCHAR 而非 INT,支持“GC-2025-001”等业务编码格式。
  • contract_amount 使用 DECIMAL(18,2) 保证金额精度,避免浮点误差。
  • status 使用 TINYINT 枚举,预留扩展空间(如 3-待归档)。

3.3 合同主表建表 SQL(MySQL 示例)

CREATE TABLE `contract` (
  `id`            BIGINT        NOT NULL AUTO_INCREMENT  COMMENT '自增主键',
  `contract_code` VARCHAR(50)   NOT NULL                 COMMENT '合同编号',
  `contract_name` VARCHAR(200)  NOT NULL                 COMMENT '合同名称',
  `party_a`       VARCHAR(100)  NOT NULL                 COMMENT '甲方',
  `party_b`       VARCHAR(100)  NOT NULL                 COMMENT '乙方',
  `contract_amount` DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '合同金额',
  `sign_date`     DATE          NOT NULL                 COMMENT '签订日期',
  `status`        TINYINT       NOT NULL DEFAULT 0       COMMENT '状态:0-进行中 1-已完成 2-已终止',
  `created_at`    DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at`    DATETIME      NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_contract_code` (`contract_code`),
  KEY `idx_sign_date` (`sign_date`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合同主表';

3.4 字段设计决策对比

以下对比帮助理解关键字段的设计取舍:

决策点 方案A(选用) 方案B(不推荐) 理由
合同编号类型 VARCHAR(50) + UNIQUE INT AUTO_INCREMENT 业务编号含前缀、年份,INT 无法表达语义
金额字段类型 DECIMAL(18,2) FLOAT / DOUBLE DECIMAL 精确,避免浮点舍入误差
甲方乙方存储 VARCHAR 直接存储名称 外键关联参与方表 主表高频查询,减少JOIN;参与方详情可冗余在子表
签订日期 DATE 类型 VARCHAR / INT DATE 支持日期函数、索引、范围查询
合同主表字段设计架构图 合同主表 标识字段 id, contract_code 基本信息 contract_name, party_a, party_b 财务与日期 contract_amount, sign_date 状态与审计 status, created_at, updated_at 字段分组说明 标识字段:唯一识别合同 基本信息:合同核心内容
避坑提醒: 不要将合同义务字段(如“付款节点”“验收日期”)直接放在合同主表中。义务是动态、多实例的,应单独建表,通过外键 contract_id 关联。主表只存合同级静态属性,否则后续义务跟踪将陷入字段爆炸与更新异常。