4. 批次与序列号标识设计

在食品追溯数据库中,标识体系是整个数据模型的“主键骨架”。如果标识设计不合理,后续的关联查询、召回定位、防窜货分析都会变得困难。本节围绕三个层次展开:批次编码规则、序列号生成策略,以及多级包装之间的标识关联,并给出一套可直接落地的方案与数据库存储结构。

一、批次编码:GTIN + 批号 + 日期段

批次(Batch/Lot)是同一生产条件下、同一时间段内产出的一组产品,是召回定位的最小业务单元。国际通行的做法是以 GS1 体系为基础:用 GTIN(全球贸易项目代码,14 位)标识“这是什么产品”,用批号(Lot Number)标识“哪一批”。一个实用的批次编码可设计为:

批次编码 = GTIN(14) + 生产日期(YYMMDD) + 产线号(2) + 班次(1) + 流水号(3)
示例:06901234567890 + 250318 + 03 + A + 007
     → 069012345678902503180 3A007(实际存储时以分隔符或定长字段拆分)

这里需要强调“可读性”与“唯一性”的平衡。纯随机码唯一性强但人工无法识别,纯日期流水码可读但存在跨厂冲突风险。推荐做法是:编码本身可读(含日期、产线、班次),唯一性由数据库唯一约束和厂内前缀共同保证。GTIN 已隐含厂商前缀,因此不同工厂不会冲突;同一工厂内,日期+产线+班次+流水号在一天内天然唯一。若企业无 GTIN,可用内部产品码(如 8 位物料号)替代,但需在数据库中保留 GTIN 字段以便对接零售端。

批号中的日期建议使用生产日期而非包装日期,因为召回追溯以“何时生产”为判断依据;若同一天多班次生产,班次位不可省略,否则无法区分责任班组。

二、序列号生成策略

序列号(Serial Number, SN)用于单品级追溯,常见于高价值食品、婴幼儿配方奶粉、保健食品等。生成策略主要有三种:

  • 集中式发号:由数据库序列或发号服务统一分配,全局唯一、无冲突,但依赖网络,产线断网时无法赋码。
  • 分段式发号:预先为每条产线/每个班次分配号段(如产线03班次A分配 0000001–0500000),产线本地递增,离线可用,号段用尽再申请。这是食品工厂最常用的方案。
  • 随机码:如 16 位字母数字随机串,防伪性强,但不可读、需查表校验,适合高端防伪场景。

以分段式为例,SN 可设计为“批次编码 + 6 位序号”,如 069012345678902503180 3A007-000123。数据库中对 SN 建唯一索引,同时对“批次编码+序号”建联合唯一约束,防止号段重复分配。发号表记录每个号段的起始值、当前值、状态(已分配/使用中/已用尽),产线赋码时先本地取号、再异步回传,保证断网时仍可生产。

三、多级包装的标识关联

食品通常存在“单品—箱—托盘”三级包装。追溯要求是:任一单品能向上查到所属箱、托盘,任一托盘能向下展开到全部单品。实现方式是给每一级包装都赋予唯一标识(SSCC 用于托盘和箱,SN 用于单品),并在数据库中建立“父子包含关系”表,而不是把上级标识冗余写进单品记录。这样包装关系变更(如拆箱、重新组托)时只需新增关系记录,历史关系可保留时间戳,满足追溯审计。

多级包装标识关联(单品 → 箱 → 托盘) 托盘 SSCC (00)106141411234567897 箱 SSCC (00)106141411234567903 箱 SSCC (00)106141411234567910 包含 包含 单品 SN …3A007-000123 单品 SN …3A007-000124 包含 包含 数据库存储:包装包含关系表 packaging_relation parent_code (SSCC) | child_code (SSCC/SN) | child_level | relation_type | created_at 106141411234567897 | 106141411234567903 | 箱 | 组托 | 2025-03-18 08:12 106141411234567903 | …3A007-000123 | 单品 | 装箱 | 2025-03-18 08:20

图中展示了三级标识的包含关系,以及数据库中以“父子关系表”承载关联的设计。注意:单品记录本身只存 SN 和批次编码,不存箱号;箱号通过关系表反查。这样拆箱、并托、退货重包装都不会破坏历史数据。

四、某食品企业批次标识方案与存储结构

假设某乳品企业生产 900g 罐装奶粉,产线 03、A 班,2025-03-18 生产批次。方案如下:产品 GTIN 为 06901234567890,批次编码 069012345678902503180 3A007,单品 SN 为批次编码加 6 位序号,箱 SSCC 由 GS1 前缀 1061414 加 10 位序列生成,托盘 SSCC 同理。数据库核心表设计:

表名关键字段约束与说明
productgtin, product_name, specgtin 主键,14 位定长
batchbatch_code, gtin, produce_date, line_no, shift, statusbatch_code 唯一;gtin 外键
serialsn, batch_code, seq_no, status, packed_flagsn 唯一;(batch_code, seq_no) 联合唯一
packaging_relationparent_code, child_code, child_level, relation_type, created_at(parent_code, child_code) 唯一;child_code 建索引
sn_segmentsegment_id, batch_code, line_no, start_seq, end_seq, used_seq, status号段不重叠,status 控制发号

查询“某托盘内全部单品”时,从 packaging_relation 以托盘 SSCC 为 parent_code 递归向下展开;查询“某单品属于哪个托盘”时,以 SN 为 child_code 向上回溯。由于关系表带 created_at,可还原任意时点的包装状态,满足监管审计对“历史包装关系”的要求。唯一性由数据库约束兜底,可读性由编码规则保证,二者结合即构成一套可落地、可扩展的批次与序列号标识体系。