Files
2026-09-30 11:11:54 +08:00

3.3 KiB
Raw Permalink Blame History

数据库约定

本目录的 .sql 是表结构的设计稿,供评审和后续 Laravel migration 对照。不要把这些文件当作生产迁移直接执行,也不要一次把尚未开工的 Phase 全部做成 migration。

库与字符集

  • MySQL 8、InnoDB、utf8mb4、utf8mb4_0900_ai_ci
  • 时间用 DATETIME(3),由应用写入租户或仓库时区换算后的时刻,库内不存时区

命名

  • 表名使用单数,统一 wms_ 前缀,例如 wms_sku、wms_stock_log
  • 每张表一个文件,文件名即表名,放在对应领域目录
  • 字段 snake_case。业务编码以 _code 或 _no 结尾

公共字段

  • id:BIGINT UNSIGNED 自增,只做内部主键和加锁顺序
  • tenant_code:核心业务表必有。例外只有两张全局目录:wms_tenant、wms_permission
  • created_at、updated_at:每张表都有
  • 单据头有 created_by、updated_by,存 user_code
  • 不使用 deleted_at。主数据用 status=disabled 停用;流水和日志只追加,禁止修改和删除

类型

  • 数量:DECIMAL(16,4),禁止 FLOAT / DOUBLE
  • 金额:DECIMAL(16,4),币种 CHAR(3)
  • 重量:千克,DECIMAL(12,4);尺寸:厘米
  • 状态:VARCHAR(32),取值写在字段注释里。应用层用 Enum 和集中定义的合法迁移,禁止散落比较魔法字符串

关联

  • 表与表用业务编码关联,不建外键。编码的唯一约束都包含 tenant_code
  • 需要「允许多个空值」的可选单号(外部订单号、入库参考号、非销售出库的订单号)使用 NULL,不要用空字符串,否则唯一索引会撞车
  • 参与库存唯一键的可选编码(库位、批次)使用空字符串,保证唯一索引生效
  • Laravel 的 personal_access_tokens、队列表、缓存表由框架 migration 维护,不在这里重复

库存

余额行的粒度是:租户 + 仓库 + 货主 + 库位 + SKU + 批次。

库存状态不另做一行维度,由数量桶表达:

字段 含义
available_qty 可用
reserved_qty 已分配、未拣货
picked_qty 已拣货、未出库
hold_qty 冻结
damaged_qty 残损
in_transit_qty 在途,只放在库位编码为空的行

待检、待上架的实物放在收货或质检库位,仍记在 available_qty,靠库位策略排除出可分配范围。

任何余额变化必须和 wms_stock_log 在同一事务。扣减用带数量条件的原子更新。一次动作跨两个桶或两个库位时写多行流水,共用 biz_type 和 biz_no。打包不改数量桶。

订单和出库

  • wms_order 是统一履约订单,不包含任何平台专用列
  • wms_outbound 是仓库作业单。一笔订单可以按仓库拆成多张出库单
  • 平台差异留在 wms_platform_shop 和连接器

不单独建表的概念

概念 落点
库位容量 wms_location 的容量列
收货差异 wms_inbound_receipt_item 的差异列
入库流水 wms_stock_log,biz_type 为入库相关
库存锁定 / 预占 wms_allocation
复核 wms_outbound.review_status
报废单 退货明细的处置加 wms_stock_log
订单渠道、来源、外部单号、状态 wms_order 的列,不是独立表
报表、AI 分析结果 查询或 Python 服务返回,不落核心业务表