仓储系统核心编码设计与分布式ID生成实践

张开发
2026/4/17 12:38:14 15 分钟阅读

分享文章

仓储系统核心编码设计与分布式ID生成实践
引言在供应链与仓储管理系统开发中编码设计与唯一标识生成是基础但至关重要的环节。一套科学、可扩展的编码体系不仅能提升人工操作效率更是系统间数据交互、财务对账、库存追溯的基石。本文结合领域驱动设计DDD思想与分布式系统实践经验系统梳理了SKU编码、业务单据号、库存业务编码的设计原则并对比了数据库自增、号段模式、雪花算法等主流ID生成策略的适用场景希望能为同类系统的开发者提供参考。一、SKU编码稳定标识与灵活属性的平衡SKUStock Keeping Unit库存量单位是商品主数据的核心标识。在设计SKU编码时我们面临两个互斥的目标编码本身应具有业务可读性同时又必须保持长期稳定一旦生成绝不修改。经过多轮讨论我们确立了以下原则唯一性与稳定性优先SKU编码一旦分配给某个商品其生命周期内不可变更。因此编码中不宜包含易变的业务属性如供应商、商品分类、销售渠道等否则当这些属性调整时编码将被迫修改导致历史订单、库存标签失效。适度可读保持简短可通过一级大类代码 年份/月份 流水号的结构实现基本可读性。例如FO2401001食品类2024年1月第001号。大类代码2位字母极少变动年份月份仅为时间参考不参与业务逻辑。扩展属性通过关联表管理商品分类、品牌、供应商、规格参数等属性应存放在独立的表中SKU通过外键或值对象引用。这样既能支持复杂的多维查询又不会破坏编码的稳定性。在DDD架构中我们明确将Category分类与Sku设计为两个独立的聚合根。Sku聚合中仅保存CategoryId不保存分类名称修改分类名称或调整分类树时无需触碰任何SKU记录。查询时通过CQRS读模型或应用层关联获取分类信息。二、业务单据号可读性、唯一性与高可用入库单号、出库单号等业务单据需要满足以下特性业务可读通常包含日期如IN202412200001便于线下沟通与快速识别。全局唯一同一租户下不能重复。趋势递增有利于数据库索引性能。高可用生成服务不能成为单点瓶颈。我们选择数据库号段模式Segment作为单据号生成的核心技术。该模式在保证唯一性的同时通过批量获取号段大幅降低数据库压力且天然支持按日期重置序号。实现要点号段表结构id_allocator(biz_tag, max_id, step)将日期编码到biz_tag中例如inbound_no_20241220。这样每天的序号独立自动从1开始。应用层缓存号段使用双Buffer预加载避免号段耗尽时的阻塞等待。使用SELECT FOR UPDATE保证并发安全配合唯一索引实现不存在则插入的原子语义。该方案已在生产环境中支撑日均十万级单据量性能与可靠性均满足要求。三、库存业务编码stock_no仓库SKU批次序号库存记录除了技术主键stock_id外通常还需要一个业务可见的编码用于打印货位标签、人工盘点、与外协系统交换数据。我们设计的格式为启用批次管理[仓库码(4)] [SkuCode] [批次日期(6)] [序号(6)]示例WH01SK2401241220000001不启用批次管理[仓库码(4)] [SkuCode] [序号(6)]示例WH01SK2401000001序号生成同样采用号段模式但分组键根据是否启用批次而不同有批次时分组键 仓库码 SkuCode 批次日期批次日期为yyMMdd每个批次独立计数。无批次时分组键 仓库码 SkuCode可选追加年份实现年度重置。注意stock_no应包含货位信息吗不包含。货位是可变的移动货位时只更新数据库中的location_no字段stock_no保持不变。这确保了已打印的标签长期有效。四、分布式ID生成策略对比在系统设计中我们同时面临多种ID生成需求技术主键如stock_id、业务单据号、库存编码等。下表总结了常见方案的适用场景方案优点缺点推荐场景数据库自增简单、有序、事务内方便分库分表困难、性能瓶颈单库、低并发、非核心表号段模式Leaf Segment高性能、可重置、强一致需维护数据库表、应用缓存业务单据号、每日重置的编码雪花算法Snowflake无中心、高性能、全局唯一依赖时钟、需管理workerId技术主键、超高并发、分布式环境Redis原子自增极高性能、简单持久化风险、可能丢失序列容忍丢失的非关键流水号对于技术主键无业务含义我们采用雪花算法并通过ZooKeeper动态分配workerId避免了人工配置的繁琐和时钟回拨问题。对于业务单据号和库存编码我们统一使用数据库号段模式因为它天然支持按日期/批次重置序号且实现简单可靠。五、号段模式的高阶实践为了使号段模式在仓储系统中发挥最大效用我们总结了以下实践要点合理设置步长step根据业务量调整如日均单据量1万步长可设为1000~5000。过小会增加数据库请求过大会浪费ID。双Buffer预加载当当前号段使用超过80%时异步加载下一个号段彻底消除号段切换时的等待。分组键设计对于需要按天重置的编码将日期作为分组键的一部分对于不需要重置的分组键固定。不同分组的数据在数据库中独立互不影响。缓存清理策略对于带日期的分组键当日期变为旧日期后缓存中的号段不会再被使用可设置定期清理或采用软引用自动回收。监控与告警监控号段消耗速率、数据库锁等待时间、号段分配失败次数以便及时发现性能瓶颈或配置不当。六、总结仓储系统中的编码设计是一项需要兼顾业务语义、技术实现与长期演进的系统工程。通过将稳定属性固化在编码中、易变属性剥离到关联表我们可以获得既清晰又灵活的编码体系。在ID生成技术上数据库号段模式以其平衡的性能、可靠性和易于实现的特点成为业务单据号和库存编码的首选而雪花算法则更适合无业务含义的技术主键尤其是在分库分表或微服务架构下。最后无论选择哪种方案都应当将编码规则文档化并在代码中通过统一的生成服务领域服务或应用服务来强制执行避免各模块随意创造编码逻辑。希望本文的实践总结能帮助读者少走弯路构建出健壮、可扩展的仓储管理系统。

更多文章