引言
在上一篇《OMS订单管理系统全景图》中,我们建立了对OMS的全局认知。本文将深入OMS的基础层,理解订单管理领域的核心概念和数据模型设计。
掌握这些概念,是设计一个高质量OMS系统的基础。
一、OMS核心概念
1.1 订单(Order)
定义:订单是买卖双方的一份合约,记录了商品、价格、数量、地址、时间等信息。
订单的三个维度:
维度1:业务维度
从业务角度看,订单包含:
- 订单头(Order Header):订单号、下单时间、客户信息、收货地址、总金额
- 订单行(Order Line):商品SKU、数量、单价、小计
维度2:系统维度
从系统角度看,订单包含:
- 原始订单(Source Order):来自渠道的原始订单
- 内部订单(Internal Order):OMS内部统一格式的订单
- 子订单(Sub Order):拆分后的订单
维度3:状态维度
从状态角度看,订单有生命周期:
- 创建 → 待支付 → 已支付 → 待审核 → 待分配 → 待出库 → 已出库 → 配送中 → 已签收 → 已完成
1.2 子订单(Sub Order)
定义:原始订单经过拆分后生成的订单。
拆分场景:
场景1:跨仓拆分
原始订单:
- 商品A(北京仓)x 1
- 商品B(上海仓)x 1
拆分为2个子订单:
- 子订单1:商品A x 1(北京仓)
- 子订单2:商品B x 1(上海仓)
场景2:跨品类拆分
原始订单:
- 图书(普通仓)x 1
- 生鲜(冷链仓)x 1
拆分为2个子订单:
- 子订单1:图书 x 1(普通仓)
- 子订单2:生鲜 x 1(冷链仓)
场景3:预售+现货拆分
原始订单:
- 预售商品(15天后发货)x 1
- 现货商品(立即发货)x 1
拆分为2个子订单:
- 子订单1:预售商品 x 1(15天后处理)
- 子订单2:现货商品 x 1(立即处理)
关键设计要点:
- 子订单有独立的订单号
- 子订单共享父订单的客户信息
- 子订单状态独立变化
- 父订单状态由所有子订单状态聚合决定
1.3 订单行(Order Line / Order Item)
定义:订单中的每一个商品明细。
订单行结构:
{
"line_id": "LINE001",
"order_id": "ORD20251122001",
"sku": "MACBOOK-PRO-14",
"product_name": "MacBook Pro 14寸",
"quantity": 1,
"unit_price": 14999.00,
"discount": 0.00,
"tax": 0.00,
"subtotal": 14999.00,
"warehouse": "SHA",
"status": "PENDING_SHIP"
}
订单行的状态机:
待处理 → 待出库 → 已出库 → 配送中 → 已签收 → 已完成
↓
缺货 → 取消 / 补货
1.4 SKU(Stock Keeping Unit)
定义:库存保有单位,是库存管理的最小单位。
SKU与商品的关系:
商品:iPhone 15
├── SKU1: iPhone 15 黑色 128GB
├── SKU2: iPhone 15 黑色 256GB
├── SKU3: iPhone 15 白色 128GB
└── SKU4: iPhone 15 白色 256GB
SKU编码设计:
SKU: IPHONE-15-BLK-128GB
└─┬──┘ └┬┘ └┬┘ └──┬──┘
│ │ │ └─ 规格
│ │ └─ 颜色
│ └─ 型号
└─ 品类
1.5 订单类型
类型1:按来源分类
- B2C订单:消费者订单(淘宝、京东)
- B2B订单:企业订单(批发、大客户)
- O2O订单:线上下单、线下自提
类型2:按履约方式分类
- FBM(Fulfilled by Merchant):商家自发货
- FBA(Fulfilled by Amazon):亚马逊代发货
- JIT(Just In Time):零库存订单,收到订单后再采购
类型3:按特殊属性分类
- 预售订单:提前预定,延期发货
- 赠品订单:促销活动赠品
- 售后订单:退货、换货、补发
二、订单状态机设计
2.1 订单状态机的核心原则
原则1:单向流转
- 订单状态应该单向流转,避免循环(如:已发货 → 待发货)
- 异常状态通过独立的状态表示(如:缺货、取消)
原则2:状态粒度适中
- 状态过细:增加系统复杂度
- 状态过粗:缺少监控点
原则3:状态与动作分离
- 状态:订单当前所处的阶段(名词)
- 动作:触发状态变化的事件(动词)
2.2 标准订单状态机
+----------------+
| CREATED | 订单创建
+----------------+
↓ 提交订单
+----------------+
| PENDING_PAYMENT| 待支付
+----------------+
↓ ↓
支付成功 支付超时/取消
↓ ↓
+----------------+ +----------------+
| PAID | | CANCELLED | 已取消
+----------------+ +----------------+
↓
+----------------+
| APPROVED | 审核通过
+----------------+
↓
+----------------+
| PENDING_ALLOCATE| 待分配仓库
+----------------+
↓
+----------------+
| PENDING_SHIP | 待出库
+----------------+
↓
+----------------+
| SHIPPED | 已出库
+----------------+
↓
+----------------+
| IN_TRANSIT | 配送中
+----------------+
↓
+----------------+
| DELIVERED | 已签收
+----------------+
↓
+----------------+
| COMPLETED | 已完成
+----------------+
2.3 状态转换规则表
| 当前状态 | 触发动作 | 下一状态 | 系统动作 |
|---|---|---|---|
| CREATED | 提交订单 | PENDING_PAYMENT | 生成支付链接 |
| PENDING_PAYMENT | 支付成功 | PAID | 库存预占、发送订单处理消息 |
| PENDING_PAYMENT | 支付超时 | CANCELLED | 释放库存(如有) |
| PAID | 审核通过 | APPROVED | 进入订单处理流程 |
| PAID | 审核不通过 | CANCELLED | 退款、释放库存 |
| APPROVED | 仓库分配成功 | PENDING_ALLOCATE | 记录分配仓库 |
| PENDING_ALLOCATE | 订单下发WMS成功 | PENDING_SHIP | 生成出库指令 |
| PENDING_SHIP | WMS反馈已发货 | SHIPPED | 生成运单号、通知客户 |
| SHIPPED | 物流揽收 | IN_TRANSIT | 开始物流追踪 |
| IN_TRANSIT | 客户签收 | DELIVERED | 扣减实际库存、同步ERP结算 |
| DELIVERED | 确认收货(或自动) | COMPLETED | 订单归档、支持售后(7-15天) |
| 任意状态 | 用户申请取消 | CANCELLED | 根据当前状态,执行相应回滚(释放库存、退款、取消出库) |
2.4 状态机代码实现
方式1:枚举+Switch(简单场景)
public enum OrderStatus {
CREATED,
PENDING_PAYMENT,
PAID,
APPROVED,
PENDING_ALLOCATE,
PENDING_SHIP,
SHIPPED,
IN_TRANSIT,
DELIVERED,
COMPLETED,
CANCELLED
}
public class OrderService {
public void changeStatus(Order order, OrderStatus targetStatus) {
OrderStatus currentStatus = order.getStatus();
switch (currentStatus) {
case CREATED:
if (targetStatus == OrderStatus.PENDING_PAYMENT) {
// 允许转换
order.setStatus(targetStatus);
} else {
throw new IllegalStateException("Invalid state transition");
}
break;
case PENDING_PAYMENT:
if (targetStatus == OrderStatus.PAID || targetStatus == OrderStatus.CANCELLED) {
order.setStatus(targetStatus);
} else {
throw new IllegalStateException("Invalid state transition");
}
break;
// ... 其他状态
}
}
}
方式2:状态模式(复杂场景)
public interface OrderState {
void pay(OrderContext context);
void approve(OrderContext context);
void ship(OrderContext context);
void cancel(OrderContext context);
}
public class PendingPaymentState implements OrderState {
@Override
public void pay(OrderContext context) {
// 支付成功,转换到PAID状态
context.setState(new PaidState());
// 执行库存预占等业务逻辑
context.reserveInventory();
}
@Override
public void cancel(OrderContext context) {
// 取消订单,转换到CANCELLED状态
context.setState(new CancelledState());
}
@Override
public void approve(OrderContext context) {
throw new IllegalStateException("Cannot approve before payment");
}
@Override
public void ship(OrderContext context) {
throw new IllegalStateException("Cannot ship before payment");
}
}
public class OrderContext {
private OrderState state;
private Order order;
public void pay() {
state.pay(this);
}
public void setState(OrderState state) {
this.state = state;
this.order.setStatus(state.getStatus());
}
}
三、数据模型设计
3.1 核心表结构
表1:订单主表(t_order)
CREATE TABLE t_order (
-- 主键
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(64) NOT NULL UNIQUE COMMENT '订单号',
-- 渠道信息
channel VARCHAR(32) NOT NULL COMMENT '渠道:taobao/jd/shopify',
channel_order_id VARCHAR(64) COMMENT '渠道订单号',
shop_id VARCHAR(32) COMMENT '店铺ID',
-- 客户信息
buyer_id VARCHAR(64) COMMENT '买家ID',
buyer_name VARCHAR(128) COMMENT '买家姓名',
buyer_phone VARCHAR(32) COMMENT '买家手机',
buyer_email VARCHAR(128) COMMENT '买家邮箱',
-- 收货地址
receiver_name VARCHAR(128) COMMENT '收货人',
receiver_phone VARCHAR(32) COMMENT '收货电话',
receiver_province VARCHAR(64) COMMENT '省份',
receiver_city VARCHAR(64) COMMENT '城市',
receiver_district VARCHAR(64) COMMENT '区县',
receiver_address VARCHAR(512) COMMENT '详细地址',
receiver_postcode VARCHAR(16) COMMENT '邮编',
-- 金额信息
total_amount DECIMAL(12,2) NOT NULL COMMENT '订单总金额',
discount_amount DECIMAL(12,2) DEFAULT 0.00 COMMENT '优惠金额',
shipping_fee DECIMAL(12,2) DEFAULT 0.00 COMMENT '运费',
tax_amount DECIMAL(12,2) DEFAULT 0.00 COMMENT '税费',
paid_amount DECIMAL(12,2) COMMENT '实付金额',
-- 订单状态
status VARCHAR(32) NOT NULL COMMENT '订单状态',
sub_status VARCHAR(32) COMMENT '子状态',
-- 业务信息
order_type VARCHAR(32) COMMENT '订单类型:normal/presale/gift',
payment_method VARCHAR(32) COMMENT '支付方式',
payment_time DATETIME COMMENT '支付时间',
-- 履约信息
warehouse_code VARCHAR(32) COMMENT '分配仓库',
carrier_code VARCHAR(32) COMMENT '物流公司',
tracking_number VARCHAR(64) COMMENT '运单号',
shipped_time DATETIME COMMENT '发货时间',
delivered_time DATETIME COMMENT '签收时间',
-- 备注
buyer_message VARCHAR(512) COMMENT '买家留言',
seller_memo VARCHAR(512) COMMENT '卖家备注',
-- 父子订单关系
parent_order_id VARCHAR(64) COMMENT '父订单号(拆分场景)',
is_split TINYINT DEFAULT 0 COMMENT '是否已拆分:0否1是',
-- 时间戳
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- 索引
INDEX idx_channel_order_id (channel, channel_order_id),
INDEX idx_buyer_id (buyer_id),
INDEX idx_status (status),
INDEX idx_created_at (created_at),
INDEX idx_parent_order_id (parent_order_id)
) COMMENT='订单主表';
表2:订单明细表(t_order_item)
CREATE TABLE t_order_item (
-- 主键
id BIGINT PRIMARY KEY AUTO_INCREMENT,
item_id VARCHAR(64) NOT NULL UNIQUE COMMENT '订单行ID',
order_id VARCHAR(64) NOT NULL COMMENT '订单号',
-- 商品信息
sku VARCHAR(64) NOT NULL COMMENT 'SKU编码',
product_id VARCHAR(64) COMMENT '商品ID',
product_name VARCHAR(256) COMMENT '商品名称',
product_image VARCHAR(512) COMMENT '商品图片',
-- 规格信息
spec_desc VARCHAR(256) COMMENT '规格描述:颜色/尺寸',
barcode VARCHAR(64) COMMENT '商品条码',
-- 数量与价格
quantity INT NOT NULL COMMENT '购买数量',
unit_price DECIMAL(12,2) NOT NULL COMMENT '单价',
discount_amount DECIMAL(12,2) DEFAULT 0.00 COMMENT '优惠金额',
tax_amount DECIMAL(12,2) DEFAULT 0.00 COMMENT '税费',
subtotal DECIMAL(12,2) NOT NULL COMMENT '小计',
-- 履约信息
warehouse_code VARCHAR(32) COMMENT '分配仓库',
location_code VARCHAR(64) COMMENT '库位编码',
-- 状态
status VARCHAR(32) NOT NULL COMMENT '订单行状态',
-- 时间戳
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- 索引
INDEX idx_order_id (order_id),
INDEX idx_sku (sku),
INDEX idx_status (status)
) COMMENT='订单明细表';
表3:订单状态流转记录表(t_order_status_history)
CREATE TABLE t_order_status_history (
-- 主键
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(64) NOT NULL COMMENT '订单号',
-- 状态变更
from_status VARCHAR(32) COMMENT '变更前状态',
to_status VARCHAR(32) NOT NULL COMMENT '变更后状态',
-- 变更原因
reason VARCHAR(512) COMMENT '变更原因',
operator VARCHAR(64) COMMENT '操作人',
operator_type VARCHAR(32) COMMENT '操作类型:system/user',
-- 时间戳
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 索引
INDEX idx_order_id (order_id),
INDEX idx_created_at (created_at)
) COMMENT='订单状态流转记录表';
3.2 扩展表设计
表4:订单扩展信息表(t_order_extra)
用于存储不常用但又需要保留的信息,避免主表字段过多。
CREATE TABLE t_order_extra (
-- 主键
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(64) NOT NULL UNIQUE COMMENT '订单号',
-- JSON格式存储扩展信息
extra_data JSON COMMENT '扩展信息',
-- 常用扩展字段(也可以放在JSON中)
coupon_code VARCHAR(64) COMMENT '优惠券编码',
promotion_id VARCHAR(64) COMMENT '促销活动ID',
member_level VARCHAR(32) COMMENT '会员等级',
points_used INT DEFAULT 0 COMMENT '使用积分',
-- 时间戳
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) COMMENT='订单扩展信息表';
表5:订单日志表(t_order_log)
记录订单的所有操作日志,用于问题排查和审计。
CREATE TABLE t_order_log (
-- 主键
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(64) NOT NULL COMMENT '订单号',
-- 日志信息
log_type VARCHAR(32) NOT NULL COMMENT '日志类型:API调用/状态变更/异常',
log_level VARCHAR(16) COMMENT '日志级别:INFO/WARN/ERROR',
message TEXT COMMENT '日志内容',
-- 操作信息
operator VARCHAR(64) COMMENT '操作人',
ip_address VARCHAR(64) COMMENT 'IP地址',
-- 时间戳
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 索引
INDEX idx_order_id (order_id),
INDEX idx_log_type (log_type),
INDEX idx_created_at (created_at)
) COMMENT='订单日志表';
四、订单编号规则设计
4.1 订单号设计原则
原则1:全局唯一
- 订单号在整个系统中必须唯一
- 避免使用数据库自增ID作为订单号(安全风险)
原则2:可读性
- 订单号包含业务含义,便于识别
- 例如:包含日期、渠道、序列号
原则3:可排序
- 订单号可按时间排序
- 便于查询和分析
原则4:防篡改
- 避免连续的订单号(如123456、123457),防止恶意猜测
4.2 订单号生成方案
方案1:时间戳 + 随机数
订单号格式:ORD + YYYYMMDDHHMMSS + 6位随机数
示例:ORD20251122103045123456
优点:
- 简单易实现
- 可排序
- 全局唯一(概率极高)
缺点:
- 无业务语义
- 高并发下可能重复(需要唯一性校验)
Java实现:
public class OrderIdGenerator {
private static final String PREFIX = "ORD";
private static final SecureRandom random = new SecureRandom();
public static String generate() {
// 时间戳部分:YYYYMMDDHHmmss
String timestamp = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
// 随机数部分:6位
int randomNum = random.nextInt(900000) + 100000; // 100000-999999
return PREFIX + timestamp + randomNum;
}
}
方案2:雪花算法(Snowflake)
订单号格式:64位Long型数字
结构:1位符号 + 41位时间戳 + 10位机器ID + 12位序列号
优点:
- 全局唯一
- 趋势递增
- 高性能(本地生成,无需数据库)
缺点:
- 纯数字,不易读
- 需要转换为字符串展示
Java实现:
public class SnowflakeOrderIdGenerator {
// 起始时间戳(2025-01-01 00:00:00)
private static final long START_TIMESTAMP = 1735660800000L;
// 机器ID位数
private static final long WORKER_ID_BITS = 10L;
// 序列号位数
private static final long SEQUENCE_BITS = 12L;
// 最大机器ID
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
// 最大序列号
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
// 时间戳左移位数
private static final long TIMESTAMP_SHIFT = WORKER_ID_BITS + SEQUENCE_BITS;
// 机器ID左移位数
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
private final long workerId;
private long sequence = 0L;
private long lastTimestamp = -1L;
public SnowflakeOrderIdGenerator(long workerId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID out of range");
}
this.workerId = workerId;
}
public synchronized long generateId() {
long timestamp = System.currentTimeMillis();
// 时钟回拨检测
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards");
}
// 同一毫秒内,序列号递增
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
// 序列号溢出,等待下一毫秒
if (sequence == 0) {
timestamp = waitNextMillis(timestamp);
}
} else {
// 新的毫秒,序列号重置为0
sequence = 0L;
}
lastTimestamp = timestamp;
// 拼接ID
return ((timestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT)
| (workerId << WORKER_ID_SHIFT)
| sequence;
}
private long waitNextMillis(long currentTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= currentTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
// 转换为字符串订单号
public String generateOrderId() {
return "ORD" + generateId();
}
}
方案3:业务前缀 + 时间 + 序列号(推荐)
订单号格式:业务前缀 + 日期 + 序列号
示例:ORD20251122000001
优点:
- 有业务语义
- 可读性强
- 可排序
缺点:
- 需要维护序列号(Redis或数据库)
Redis实现:
public class OrderIdGenerator {
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final String PREFIX = "ORD";
public String generate() {
// 日期部分:YYYYMMDD
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
// Redis Key:ORDER:ID:20251122
String redisKey = "ORDER:ID:" + date;
// 自增序列号
Long sequence = redisTemplate.opsForValue().increment(redisKey);
// 设置过期时间:7天后过期
if (sequence == 1) {
redisTemplate.expire(redisKey, 7, TimeUnit.DAYS);
}
// 拼接订单号:ORD20251122000001
return String.format("%s%s%06d", PREFIX, date, sequence);
}
}
4.3 订单号校验
public class OrderIdValidator {
// 订单号格式:ORD + 8位日期 + 6位序列号
private static final Pattern PATTERN = Pattern.compile("^ORD\\d{8}\\d{6}$");
public static boolean validate(String orderId) {
if (orderId == null || orderId.isEmpty()) {
return false;
}
// 格式校验
if (!PATTERN.matcher(orderId).matches()) {
return false;
}
// 日期校验
String dateStr = orderId.substring(3, 11); // 提取日期部分
try {
LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyyMMdd"));
return true;
} catch (Exception e) {
return false;
}
}
}
五、订单类型分类
5.1 按业务场景分类
| 订单类型 | 英文简称 | 说明 | 特殊处理 |
|---|---|---|---|
| 普通订单 | NORMAL | 常规销售订单 | 无 |
| 预售订单 | PRESALE | 提前预定,延期发货 | 延迟下发WMS,需记录预计发货时间 |
| 赠品订单 | GIFT | 促销活动赠品 | 金额为0,不参与财务结算 |
| 换货订单 | EXCHANGE | 售后换货订单 | 关联原订单,退货后自动发货 |
| 补发订单 | RESEND | 物流丢失或破损后补发 | 关联原订单,不收费 |
| 退货订单 | RETURN | 退货订单(逆向订单) | 逆向物流,退款处理 |
| 拼团订单 | GROUP_BUY | 拼多多等拼团订单 | 成团后才处理,需等待拼团成功 |
| 秒杀订单 | FLASH_SALE | 秒杀活动订单 | 高并发,需特殊库存预占机制 |
| 虚拟商品订单 | VIRTUAL | 充值卡、会员卡等虚拟商品 | 无需物流,自动发货(发码) |
| 跨境订单 | CROSS_BORDER | 跨境电商订单 | 需报关、清关,履约周期长 |
| 企业采购订单 | B2B | 企业批量采购订单 | 支持账期结算,需开具发票 |
| O2O订单 | O2O | 线上下单、线下自提 | 无需物流,到店核销 |
| 定制订单 | CUSTOMIZED | 定制化商品订单 | 需生产周期,延期发货 |
| 分期付款订单 | INSTALLMENT | 分期付款订单 | 需对接金融机构,支持分期扣款 |
5.2 订单类型枚举
public enum OrderType {
NORMAL("NORMAL", "普通订单"),
PRESALE("PRESALE", "预售订单"),
GIFT("GIFT", "赠品订单"),
EXCHANGE("EXCHANGE", "换货订单"),
RESEND("RESEND", "补发订单"),
RETURN("RETURN", "退货订单"),
GROUP_BUY("GROUP_BUY", "拼团订单"),
FLASH_SALE("FLASH_SALE", "秒杀订单"),
VIRTUAL("VIRTUAL", "虚拟商品订单"),
CROSS_BORDER("CROSS_BORDER", "跨境订单"),
B2B("B2B", "企业采购订单"),
O2O("O2O", "O2O订单"),
CUSTOMIZED("CUSTOMIZED", "定制订单"),
INSTALLMENT("INSTALLMENT", "分期付款订单");
private final String code;
private final String description;
OrderType(String code, String description) {
this.code = code;
this.description = description;
}
// Getter方法...
}
六、总结
6.1 核心要点回顾
- 订单的三个维度:业务维度(订单头+订单行)、系统维度(原始订单+子订单)、状态维度(生命周期)
- 订单状态机:单向流转、状态粒度适中、状态与动作分离
- 数据模型设计:订单主表、订单明细表、状态流转表、扩展表、日志表
- 订单号设计:全局唯一、可读性、可排序、防篡改
- 订单类型分类:14种典型订单类型,每种类型有特殊处理逻辑
6.2 设计建议
- 状态机不要过度设计:根据业务实际需要设计状态,避免过细或过粗
- 数据表分离关注点:主表存核心信息,扩展表存可选信息,日志表存操作记录
- 订单号方案选择:
- 小型系统:时间戳+随机数
- 中型系统:业务前缀+日期+Redis序列号(推荐)
- 大型系统:雪花算法+业务前缀
- 预留扩展字段:订单表预留JSON字段,存储不常用的扩展信息
6.3 下一步学习
本文详细讲解了OMS的核心概念和数据模型。在下一篇文章中,我们将探讨多渠道订单接入与标准化,了解如何对接淘宝、京东、Shopify等平台的订单API。
关键词:OMS数据模型、订单状态机、订单编号、订单类型、数据库设计、领域建模、订单管理