一、系统设计目标
1. 完整记录商品全生命周期变更
2. 支持快速追溯商品历史版本
3. 提供商品变更审计能力
4. 实现商品数据版本对比功能
二、核心功能模块设计
1. 商品变更记录表设计
```sql
CREATE TABLE product_change_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT NOT NULL COMMENT 商品ID,
change_type VARCHAR(20) NOT NULL COMMENT 变更类型:CREATE/UPDATE/DELETE/STATUS_CHANGE,
change_field VARCHAR(50) COMMENT 变更字段,
old_value TEXT COMMENT 旧值,
new_value TEXT COMMENT 新值,
change_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 变更时间,
operator_id BIGINT COMMENT 操作人ID,
operator_name VARCHAR(50) COMMENT 操作人姓名,
remark VARCHAR(255) COMMENT 变更备注,
version INT DEFAULT 1 COMMENT 版本号,
INDEX idx_product_id (product_id),
INDEX idx_change_time (change_time)
) ENGINE=InnoDB COMMENT=商品变更记录表;
```
2. 商品快照表设计(可选)
```sql
CREATE TABLE product_snapshot (
snapshot_id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT NOT NULL COMMENT 商品ID,
version INT NOT NULL COMMENT 版本号,
snapshot_data JSON NOT NULL COMMENT 商品完整数据快照,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,
INDEX idx_product_version (product_id, version)
) ENGINE=InnoDB COMMENT=商品数据快照表;
```
三、实现方案
1. 基于AOP的自动记录方案
```java
@Aspect
@Component
public class ProductChangeAspect {
@Autowired
private ProductChangeLogService changeLogService;
@AfterReturning(
pointcut = "execution(* com.meituan.buyer.service.ProductService.update*(..)) " +
"|| execution(* com.meituan.buyer.service.ProductService.createProduct(..)) " +
"|| execution(* com.meituan.buyer.service.ProductService.deleteProduct(..))",
returning = "result"
)
public void afterProductChange(JoinPoint joinPoint, Object result) {
// 获取方法参数
Object[] args = joinPoint.getArgs();
// 根据方法名和参数判断具体操作类型
String methodName = joinPoint.getSignature().getName();
// 记录变更日志
recordChangeLog(methodName, args);
}
private void recordChangeLog(String methodName, Object[] args) {
// 实现具体的变更记录逻辑
// 1. 解析参数获取商品ID和变更信息
// 2. 对比变更前后数据
// 3. 记录到change_log表
// 4. 可选:创建完整数据快照
}
}
```
2. 手动记录方案(适用于复杂场景)
```java
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductChangeLogService changeLogService;
@Override
@Transactional
public Product updateProductPrice(Long productId, BigDecimal newPrice, String operator) {
// 1. 查询当前商品信息
Product product = productRepository.findById(productId).orElseThrow(...);
BigDecimal oldPrice = product.getPrice();
// 2. 更新商品价格
product.setPrice(newPrice);
productRepository.save(product);
// 3. 记录变更日志
ProductChangeLog log = new ProductChangeLog();
log.setProductId(productId);
log.setChangeType("PRICE_UPDATE");
log.setChangeField("price");
log.setOldValue(oldPrice.toString());
log.setNewValue(newPrice.toString());
log.setOperator(operator);
changeLogService.save(log);
return product;
}
}
```
四、高级功能实现
1. 商品版本对比功能
```java
@Service
public class ProductVersionService {
@Autowired
private ProductSnapshotRepository snapshotRepository;
public Map
compareVersions(Long productId, Integer version1, Integer version2) {
ProductSnapshot snap1 = snapshotRepository.findByProductIdAndVersion(productId, version1);
ProductSnapshot snap2 = snapshotRepository.findByProductIdAndVersion(productId, version2);
// 使用JSON库比较两个快照的差异
JSONObject json1 = new JSONObject(snap1.getSnapshotData());
JSONObject json2 = new JSONObject(snap2.getSnapshotData());
// 实现差异比较逻辑
// 返回差异字段和值
return compareJson(json1, json2);
}
}
```
2. 变更记录查询接口
```java
@RestController
@RequestMapping("/api/product/change-logs")
public class ProductChangeLogController {
@Autowired
private ProductChangeLogService changeLogService;
@GetMapping
public Page queryChangeLogs(
@RequestParam Long productId,
@RequestParam(required = false) String changeType,
@RequestParam(required = false) String changeField,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return changeLogService.queryChangeLogs(
productId, changeType, changeField, page, size);
}
}
```
五、数据存储优化策略
1. 冷热数据分离:
- 最近3个月的变更记录存放在MySQL
- 历史记录定期归档到对象存储或Hive
2. 压缩存储:
- 对大文本字段使用gzip压缩
- 对JSON数据使用二进制格式存储
3. 索引优化:
- 为常用查询字段建立索引
- 考虑使用Elasticsearch支持复杂查询
六、监控与告警
1. 变更频率监控:
- 监控单个商品的异常高频变更
- 设置阈值告警
2. 关键字段变更告警:
- 对价格、库存等关键字段的变更实时告警
3. 操作人行为分析:
- 识别异常操作模式
- 防止内部误操作或恶意修改
七、实施建议
1. 渐进式实施:
- 先实现核心变更记录功能
- 逐步完善快照和对比功能
2. 数据迁移策略:
- 对历史数据可考虑只保留关键变更
- 新系统上线后完整记录
3. 性能考虑:
- 高并发场景下考虑异步记录变更
- 批量写入优化
4. 合规性要求:
- 确保符合数据留存法规
- 实现必要的审计日志保留策略
该方案可根据美团买菜的实际业务规模和技术栈进行调整,核心思想是通过系统化的方式记录商品全生命周期变更,为运营、审计和问题排查提供可靠的数据支持。