# 设备ID存储策略

<cite>
**本文档中引用的文件**  
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go)
- [restriction.go](file://internal/logic/restriction/restriction.go)
- [restriction.go](file://internal/model/restriction.go)
- [v_1_restrict_client_access_record.go](file://internal/dao/internal/v_1_restrict_client_access_record.go)
- [v_1_restrict_client_access_ip_relation.go](file://internal/dao/internal/v_1_restrict_client_access_ip_relation.go)
- [restriction_v1_user_info_collection.go](file://internal/controller/restriction/restriction_v1_user_info_collection.go)
- [cache.go](file://utility/cache/cache.go)
- [consts.go](file://utility/cache/consts.go)
</cite>

## 目录
1. [简介](#简介)
2. [数据库表结构设计](#数据库表结构设计)
3. [设备ID与其他限制条件的关联关系](#设备id与其他限制条件的关联关系)
4. [性能优化措施](#性能优化措施)
5. [存储容量规划与数据清理策略](#存储容量规划与数据清理策略)
6. [数据安全性与访问控制](#数据安全性与访问控制)
7. [结论](#结论)

## 简介
本系统通过设备ID记录机制实现对用户访问行为的追踪与限制管理。设备ID作为核心标识，与IP地址、用户代理等信息共同构成访问控制策略的基础。系统采用数据库持久化存储结合Redis缓存的方式，确保数据的高可用性和访问效率。设备信息在用户每次请求时被采集并记录，用于后续的风险识别、反欺诈分析和访问权限控制。

**Section sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)
- [restriction_v1_user_info_collection.go](file://internal/controller/restriction/restriction_v1_user_info_collection.go#L1-L33)

## 数据库表结构设计

### 设备访问记录表 (restrict_client_access_record)
该表用于存储设备的基本访问信息，是设备ID存储的核心表。

| 字段名 | 类型 | 是否主键 | 允许为空 | 默认值 | 说明 |
|--------|------|----------|----------|--------|------|
| id | int64 | 是 | 否 | 自增 | 主键ID |
| visitor_id | varchar(255) | 否 | 否 | 无 | 设备ID，唯一标识客户端设备 |
| device_model | varchar(255) | 否 | 是 | null | 设备型号 |
| user_agent | text | 否 | 是 | null | 用户代理字符串 |
| is_use_proxy | tinyint(1) | 否 | 否 | 0 | 是否使用代理（0:否, 1:是） |
| created_at | datetime | 否 | 否 | 当前时间 | 创建时间 |
| updated_at | datetime | 否 | 是 | null | 更新时间 |
| deleted_at | datetime | 否 | 是 | null | 软删除时间戳 |

```mermaid
erDiagram
restrict_client_access_record {
int64 id PK
varchar255 visitor_id
varchar255 device_model
text user_agent
tinyint1 is_use_proxy
datetime created_at
datetime updated_at
datetime deleted_at
}
```

**Diagram sources**
- [v_1_restrict_client_access_record.go](file://internal/dao/internal/v_1_restrict_client_access_record.go#L33-L73)

### 设备IP关联表 (restrict_client_access_ip_relation)
该表用于记录设备与IP地址的关联关系，支持多IP追踪。

| 字段名 | 类型 | 是否主键 | 允许为空 | 默认值 | 说明 |
|--------|------|----------|----------|--------|------|
| id | int64 | 是 | 否 | 自增 | 主键ID |
| ip | varchar(45) | 否 | 否 | 无 | IP地址（支持IPv4/IPv6） |
| is_remote_ip | tinyint(1) | 否 | 否 | 0 | 是否为远程真实IP（0:代理IP, 1:真实IP） |
| restrict_ip_record_id | int64 | 否 | 否 | 无 | 外键，指向IP记录表 |
| restrict_client_access_record_id | int64 | 否 | 否 | 无 | 外键，指向设备访问记录表 |
| session_id | varchar(64) | 否 | 否 | 无 | 会话ID，用于关联同一次访问的多个IP |

```mermaid
erDiagram
restrict_client_access_ip_relation {
int64 id PK
varchar45 ip
tinyint1 is_remote_ip
int64 restrict_ip_record_id FK
int64 restrict_client_access_record_id FK
varchar64 session_id
}
```

**Diagram sources**
- [v_1_restrict_client_access_ip_relation.go](file://internal/dao/internal/v_1_restrict_client_access_ip_relation.go#L33-L73)

### 索引策略
为确保查询性能，系统在关键字段上建立了索引：

```sql
-- 设备ID索引（高频查询）
CREATE INDEX idx_visitor_id ON restrict_client_access_record(visitor_id);

-- IP地址索引（用于IP限制检查）
CREATE INDEX idx_ip ON restrict_client_access_ip_relation(ip);

-- 复合索引（用于会话关联查询）
CREATE INDEX idx_session_access ON restrict_client_access_ip_relation(session_id, restrict_client_access_record_id);

-- 创建时间索引（用于数据清理）
CREATE INDEX idx_created_at ON restrict_client_access_record(created_at);
```

**Section sources**
- [v_1_restrict_client_access_record.go](file://internal/dao/internal/v_1_restrict_client_access_record.go#L33-L73)
- [v_1_restrict_client_access_ip_relation.go](file://internal/dao/internal/v_1_restrict_client_access_ip_relation.go#L33-L73)

## 设备ID与其他限制条件的关联关系

### 与IP地址的关联
系统通过`restrict_client_access_ip_relation`表建立设备ID与IP地址的多对多关系。当用户访问时，系统会记录所有相关的IP地址（包括代理链中的多个IP）和真实的远程IP。通过`is_remote_ip`字段区分真实IP和代理IP，并通过`session_id`将同一次访问的所有IP关联起来。

```mermaid
flowchart TD
A[客户端请求] --> B{获取IP列表}
B --> C[遍历所有IP]
C --> D[保存IP记录]
D --> E[创建IP关联关系]
E --> F[标记真实IP]
F --> G[生成会话ID关联]
G --> H[完成设备信息存储]
```

**Diagram sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)

### 与用户行为的关联
设备ID与用户行为通过访问记录进行关联。系统在`SaveDeviceInfo`方法中，将设备ID、设备型号、UserAgent等信息与访问行为绑定。当需要判断设备是否受限时，系统会查询`restrict_client_access_record`表中该设备ID的状态。

```mermaid
sequenceDiagram
participant Client as 客户端
participant Controller as 控制器
participant Service as 限制服务
participant DB as 数据库
Client->>Controller : 提交设备信息
Controller->>Service : SaveDeviceInfo()
Service->>DB : 开启事务
Service->>DB : 查询或创建访问记录
Service->>DB : 插入IP关联记录
DB-->>Service : 返回结果
Service-->>Controller : 返回成功
Controller-->>Client : 响应结果
```

**Diagram sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)
- [restriction.go](file://internal/logic/restriction/restriction.go#L17-L35)

### 存储周期
设备访问记录的存储周期由系统配置决定，目前采用软删除机制。已删除的记录保留在数据库中，通过`deleted_at`字段标记删除时间。历史数据清理任务会定期清理超过保留周期的记录。

**Section sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)
- [v_1_restrict_client_access_record.go](file://internal/dao/internal/v_1_restrict_client_access_record.go#L33-L73)

## 性能优化措施

### 分表策略
当前系统未实现分表策略，所有设备记录存储在单表中。考虑到未来数据量增长，建议实施按时间分表策略，如按月或按季度创建新表，以提高查询性能和管理效率。

### 缓存机制
系统采用Redis作为缓存层，但设备ID记录本身未直接缓存。缓存主要用于存储频繁访问的配置信息和临时状态。对于设备ID的查询，系统依赖数据库索引进行快速检索。

```mermaid
flowchart LR
A[应用层] --> B{查询设备信息}
B --> C[数据库查询]
C --> D[使用索引扫描]
D --> E[返回结果]
E --> A
```

**Diagram sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)

### 数据归档方案
系统目前未实现自动数据归档功能。建议建立定期归档机制，将超过一定时间（如6个月）的历史访问记录迁移到归档数据库或数据仓库中，以减少主库压力。归档数据可用于离线分析和审计。

**Section sources**
- [device_id_record.go](file://internal/logic/restriction/device_id_record.go#L1-L44)

## 存储容量规划与数据清理策略

### 存储容量估算
根据当前业务规模，单条设备访问记录约占用500字节存储空间。按日均10万次访问计算，年存储量约为18.25GB。建议初始分配50GB存储空间，并设置监控告警。

### 数据清理策略
系统采用软删除+定期清理的策略：
1. 正常业务中通过`deleted_at`字段标记删除记录
2. 后台任务定期执行物理删除，清理超过保留周期（建议90天）的记录
3. 清理任务在低峰期执行，避免影响业务性能

```go
// 伪代码：数据清理逻辑
func CleanExpiredRecords(ctx context.Context) {
    expireTime := time.Now().AddDate(0, 0, -90) // 90天前
    _, err := dao.V1RestrictClientAccessRecord.Ctx(ctx).
        Where("created_at < ?", expireTime).
        Delete()
    if err != nil {
        log.Error(ctx, "清理过期设备记录失败:", err)
    }
}
```

**Section sources**
- [v_1_restrict_client_access_record.go](file://internal/dao/internal/v_1_restrict_client_access_record.go#L33-L73)

## 数据安全性与访问控制

### 数据加密
设备ID等敏感信息在传输过程中采用HTTPS加密。存储层面，数据库连接使用加密通道，但设备ID本身未进行加密存储。建议对设备ID进行哈希处理后再存储，以增强数据安全性。

### 访问控制
系统通过RBAC（基于角色的访问控制）模型管理数据访问权限。访问控制策略定义在`rbac_model.conf`文件中，通过Casbin实现细粒度的权限控制。

```mermaid
graph TD
A[用户] --> B{权限检查}
B --> C[拥有访问权限?]
C --> |是| D[允许访问设备数据]
C --> |否| E[拒绝访问]
D --> F[记录访问日志]
E --> F
```

**Diagram sources**
- [rbac_model.conf](file://resource/casbin/rbac_model.conf#L1-L13)

### 安全审计
所有对设备数据的访问和修改操作都会被记录在系统日志中。关键操作如设备禁用、IP限制等都有详细的审计日志，便于事后追溯和分析。

**Section sources**
- [restriction.go](file://internal/logic/restriction/restriction.go#L139-L172)

## 结论
kami_backend系统的设备ID存储策略通过`restrict_client_access_record`和`restrict_client_access_ip_relation`两张表实现了设备信息的完整记录。系统能够有效关联设备ID、IP地址和其他访问信息，为访问控制和风险识别提供数据支持。虽然当前架构满足基本需求，但在大规模场景下建议引入分表、缓存和数据归档等优化措施，并加强数据加密和访问控制，以提升系统性能和安全性。