4. 批次主数据建模

在智慧养殖系统中,批次主数据是连接生产计划、饲喂记录、健康事件与成本核算的“主键骨架”。如果批次模型设计得松散,后续的存栏统计、料肉比核算、追溯查询都会出现口径不一致。本节围绕三件事展开:批次实体应具备哪些属性、批次如何与栏舍/栋舍/养殖单元建立关系、以及如何用状态机与生命周期标识管理批次从入栏到归档的全过程。

一、批次实体属性设计

批次实体不是简单的“编号+名称”,而应划分为四类属性:标识属性、业务属性、时间属性和统计属性。标识属性包括批次号(业务唯一键)、批次ID(系统主键)、来源类型(自繁/外购/转入);业务属性包括畜种、品种品系、代次、性别结构、初始数量、计划出栏日龄;时间属性包括入栏日期、预计出栏日期、实际清栏日期;统计属性包括当前存栏、累计死淘、累计转出、累计耗料。设计时建议把“初始数量”与“当前存栏”分开存储,前者是批次建档时的快照,后者由事件驱动更新,避免历史数据被覆盖。

批次号建议采用可读编码规则,例如“场区码-畜种码-入栏年月-流水号”,如 F01-PIG-202503-0012。这种编码便于人工核对,但业务唯一性仍应由数据库唯一约束保证,不能仅依赖编码规则。对于外购批次,还应记录供应商、检疫证明编号、运输车牌等追溯字段,这些字段在自繁批次中可为空,因此建模时宜采用可空字段或扩展属性表,而不是强行填充。

批次属性设计的一个实用原则:凡是会随时间变化的量(存栏、体重、耗料),都不应作为批次的静态字段直接覆盖,而应通过事件表汇总或定期快照写入,保证任意历史时点可回溯。

二、批次与栏舍、栋舍、养殖单元的关系

养殖场的空间层级通常是“场区—栋舍—栏舍—养殖单元”。批次与空间的关系不是简单的一对一,而是“批次占用空间、空间承载批次”的多对多时序关系。一个批次可以先后占用多个栏舍(转群),一个栏舍在不同时间也可以承载不同批次。因此,正确的建模方式是引入“批次—栏舍占用关系”中间实体,记录批次ID、栏舍ID、占用开始时间、占用结束时间、占用数量。这样既能表达当前占用,也能还原历史转群轨迹。

栋舍和养殖单元更多承担“归属与统计”角色:栋舍用于环境控制与防疫分区,养殖单元(如产床、保育栏组)用于精细饲喂。批次可以直接关联到栋舍作为管理归属,但实际存栏应以栏舍占用关系为准。若系统只记录“批次属于某栋舍”,转群后就会出现统计偏差。下图展示了批次、占用关系与空间层级之间的结构:

批次与空间层级的关系结构 批次实体 批次ID / 批次号 初始数量 / 入栏日期 批次—栏舍占用关系 开始时间 / 结束时间 占用数量 / 转群原因 栏舍 栏舍ID / 容量 所属栋舍ID 栋舍 防疫分区 / 环境控制 养殖单元 产床 / 保育栏组 关系要点 • 批次与栏舍为多对多时序关系,必须用中间实体记录占用区间 • 栋舍承担防疫分区与环境控制归属,不直接等于存栏口径 • 养殖单元用于精细饲喂,可挂接在栏舍之下 • 转群即关闭旧占用、开启新占用,存栏按占用数量汇总 • 历史占用记录是追溯与成本分摊的依据

三、批次状态机与生命周期标识

批次状态机应覆盖“计划—在养—转群—清栏—归档”的主线,并允许异常分支。一个可落地的状态集合为:草稿(建档未确认)、待入栏(计划已审批)、在养(已入栏且有存栏)、部分转出(存在转群但未清空)、已清栏(存栏归零)、已归档(结算完成、只读)。状态迁移必须由业务事件触发,而不是人工随意修改:入栏事件使“待入栏→在养”,转群事件使“在养→部分转出”或维持“在养”,清栏事件使“部分转出/在养→已清栏”,结算完成后进入“已归档”。

生命周期标识建议采用“状态码+状态时间+版本号”的组合。状态码用于查询过滤,状态时间记录每次迁移的时刻,版本号用于并发控制,防止两个终端同时提交转群导致存栏重复扣减。对于需要对外追溯的场景,还可增加“生命周期流水号”,每次状态迁移生成一条不可变记录,形成批次的时间线。这样即使批次主表被更新,历史轨迹仍可完整还原。

批次状态迁移示例(事件驱动):
入栏登记  : 待入栏 → 在养      记录入栏日期、初始数量
转群出栏  : 在养   → 部分转出  关闭旧栏舍占用,开启新占用
清栏确认  : 部分转出 → 已清栏  当前存栏 = 0,记录清栏日期
财务结算  : 已清栏 → 已归档    批次转为只读,禁止新增生产事件
常见错误是把“已清栏”直接当作“已归档”。清栏只代表生产结束,此时仍可能有死淘复核、料耗结算、药品休药期核对等业务;过早归档会导致这些事件无法挂接到批次上。

四、建模落地时的几个判断点

第一,批次数量口径要统一。建议以“入栏数量-累计死淘-累计转出-累计销售”作为当前存栏的计算式,并定期与栏舍占用数量核对,差异超过阈值时触发盘点任务。第二,转群不要直接修改批次的栏舍字段,而应新增占用记录,否则历史成本无法按栏舍分摊。第三,状态机迁移应配置前置校验,例如“存栏大于零才能进入部分转出”“存在未结算事件时禁止归档”。第四,批次号与批次ID分离,业务人员使用批次号,系统内部关联使用批次ID,避免编码规则调整影响历史数据。

把上述三部分合起来看,批次主数据建模的本质是:用稳定的标识描述“是谁”,用占用关系描述“在哪里”,用状态机描述“处于什么阶段”。三者分离又互相约束,才能支撑智慧养殖中存栏、饲喂、健康与成本数据的统一口径。