考点: 数据库集成能力、数据驱动架构
参考答案:
不同数据用不同存储:
- 实时状态(当前温度/位置)→ Redis(内存缓存,微秒级)→ WebSocket/MQTT 推送;
- 时序历史(过去24h曲线)→ InfluxDB / TimescaleDB → UE5 请求 → API 服务 → 数据库;
- 结构化业务(设备台账、权限、配置)→ PostgreSQL / MySQL;
- 非结构化(点云、倾斜摄影、BIM 文件)→ MinIO / 阿里云 OSS,CDN+流式加载。
推荐架构:UE5 → REST API 服务 → 数据库(而非 UE5 直连):
- 避免数据库凭据暴露在客户端、便于鉴权/限流/连接池、可横向扩展;
- UE5 侧用 FHttpModule 异步请求,Lambda 回调解析 JSON。
UE5 直接连 PostgreSQL(libpq,不推荐但需了解):
#include "libpq-fe.h"
bool UPostgreSQLClient::Connect(const FString& Host, int32 Port,
const FString& Database, const FString& User, const FString& Password)
{
FString ConnStr = FString::Printf(
TEXT("host=%s port=%d dbname=%s user=%s password=%s"),
*Host, Port, *Database, *User, *Password);
PGconn* Conn = PQconnectdb(TCHAR_TO_UTF8(*ConnStr));
if (PQstatus(Conn) != CONNECTION_OK) { PQfinish(Conn); return false; }
Connection = Conn;
return true;
}
- 时序数据库交互(InfluxDB):HTTP POST Flux 查询,CSV 响应解析:
void UInfluxDBClient::QueryTemperatureHistory(const FString& DeviceId,
int32 Hours, TFunction<void(const TArray<FTemperaturePoint>&)> Callback)
{
FString Query = FString::Printf(TEXT(
"from(bucket: \"iot_data\") |> range(start: -%dh) "
"|> filter(fn: (r) => r[\"_measurement\"] == \"temperature\" "
"&& r[\"device_id\"] == \"%s\") "
"|> aggregateWindow(every: 1m, fn: mean)"), Hours, *DeviceId);
}
- 数据缓存策略:本地 TTL 缓存(
TMap<FString, FCacheEntry>),过期清理(LRU),避免每帧请求数据库拖垮帧率。
易错点: 客户端直连数据库(安全+性能问题);同步查询阻塞游戏线程(必须异步);查询延迟影响帧率。
延伸: 连接池;历史数据冷热分离;多数据源聚合;TLS 加密与访问控制;云数据库(阿里云 RDS、华为云 GaussDB)。