123 lines
4.3 KiB
Markdown
123 lines
4.3 KiB
Markdown
# 标签更新时间记录方案分析
|
||
|
||
## 1. 需求概述
|
||
|
||
在客户通过标签替换接口更新标签时,需要记录客户更新标签的时间。目前有两套方案:
|
||
- 方案1:采用数据库trigger去实现,数据库是mysql。
|
||
- 方案2:修改代码逻辑。
|
||
|
||
## 2. 现状分析
|
||
|
||
### 2.1 数据库结构
|
||
|
||
`LabelReplaceEntity` 类映射到 `label_replace_requests` 表,包含以下时间相关字段:
|
||
|
||
```csharp
|
||
/// <summary>
|
||
/// 创建时间
|
||
/// </summary>
|
||
[SugarColumn(IsNullable = false)]
|
||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||
|
||
/// <summary>
|
||
/// 更新时间
|
||
/// </summary>
|
||
[SugarColumn(IsNullable = false)]
|
||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||
```
|
||
|
||
### 2.2 代码逻辑
|
||
|
||
1. **LabelReplaceRepository.CreateAsync** 方法:
|
||
```csharp
|
||
// 设置时间戳
|
||
entity.CreatedAt = DateTime.UtcNow;
|
||
entity.UpdatedAt = DateTime.UtcNow;
|
||
```
|
||
|
||
2. **LabelReplaceRepository.UpdateAsync** 方法:
|
||
```csharp
|
||
// 更新时间戳
|
||
entity.UpdatedAt = DateTime.UtcNow;
|
||
```
|
||
|
||
3. **LabelReplaceService.ProcessLabelReplaceAsync** 方法:
|
||
```csharp
|
||
// 更新现有记录时
|
||
existingRecord.UpdatedAt = DateTime.UtcNow;
|
||
```
|
||
|
||
## 3. 方案分析
|
||
|
||
### 3.1 方案1:数据库Trigger
|
||
|
||
**实现方式**:
|
||
- 在MySQL数据库中为 `label_replace_requests` 表创建一个更新触发器
|
||
- 当记录被更新时,自动将 `UpdatedAt` 字段设置为当前时间
|
||
|
||
**优点**:
|
||
- 数据库层面自动处理,无需修改应用代码
|
||
- 无论通过什么方式更新数据,都会自动更新时间戳
|
||
- 确保时间戳更新的一致性
|
||
|
||
**缺点**:
|
||
- 增加了数据库的复杂性
|
||
- 触发器可能会影响数据库性能,特别是在高频更新场景下
|
||
- 代码逻辑和时间戳更新逻辑分离,不利于维护
|
||
- 需要数据库管理员权限来创建触发器
|
||
|
||
### 3.2 方案2:修改代码逻辑
|
||
|
||
**实现方式**:
|
||
- 确保所有更新操作都通过 `LabelReplaceRepository.UpdateAsync` 方法
|
||
- 利用现有的代码逻辑,在更新时自动设置 `UpdatedAt` 字段
|
||
|
||
**优点**:
|
||
- 代码逻辑和时间戳更新逻辑集中在一处,便于维护
|
||
- 不需要修改数据库结构
|
||
- 性能影响小,不会增加数据库负担
|
||
- 符合现有的代码架构
|
||
|
||
**缺点**:
|
||
- 需要确保所有更新操作都通过相同的代码路径
|
||
- 如果有其他地方直接操作数据库,可能会导致时间戳不更新
|
||
|
||
## 4. 性能分析
|
||
|
||
### 4.1 方案1(数据库Trigger)
|
||
- **性能影响**:每次更新操作都会触发触发器,增加数据库负载
|
||
- **适用场景**:数据更新频率较低,需要确保时间戳一致性的场景
|
||
|
||
### 4.2 方案2(代码逻辑)
|
||
- **性能影响**:仅在代码层面设置时间戳,几乎无性能影响
|
||
- **适用场景**:数据更新频率较高,系统架构清晰的场景
|
||
|
||
## 5. 推荐方案
|
||
|
||
**推荐方案**:方案2(修改代码逻辑)
|
||
|
||
**推荐理由**:
|
||
1. **符合现有架构**:系统已经在使用代码逻辑的方式来更新时间戳,保持一致性
|
||
2. **性能优势**:代码层面设置时间戳,无数据库性能开销
|
||
3. **维护性好**:代码逻辑和时间戳更新逻辑集中在一处,便于理解和维护
|
||
4. **无需额外权限**:不需要数据库管理员权限来创建触发器
|
||
5. **可靠性高**:现有代码已经实现了时间戳更新逻辑,只需确保所有更新操作都通过该逻辑
|
||
|
||
**关键修改**:
|
||
1. 确保所有更新 `label_replace_requests` 表的操作都通过 `LabelReplaceRepository.UpdateAsync` 方法
|
||
2. 验证 `LabelReplaceService.ProcessLabelReplaceAsync` 方法中的时间戳更新逻辑是否正确
|
||
3. 考虑在 `LabelReplaceEntity` 类中添加构造函数,确保 `CreatedAt` 和 `UpdatedAt` 字段始终有默认值
|
||
|
||
## 6. 验证方法
|
||
|
||
1. **功能验证**:
|
||
- 发送标签替换请求,验证 `UpdatedAt` 字段是否被更新
|
||
- 发送多次请求,验证每次请求后 `UpdatedAt` 字段是否都被更新为最新时间
|
||
|
||
2. **性能验证**:
|
||
- 批量发送标签替换请求,测量响应时间
|
||
- 比较使用方案2前后的性能差异
|
||
|
||
## 7. 结论
|
||
|
||
方案2(修改代码逻辑)是性能最高、最合理的方案。它符合现有系统架构,性能影响小,维护性好,并且已经在系统中实现。只需确保所有更新操作都通过现有的代码逻辑,即可实现记录客户更新标签时间的需求。 |