核心需求分析
数据仓库方案设计
我们将采用经典的星型模型(Star Schema)来构建数据仓库,这种模型非常适合OLAP分析。
1. 数据模型设计 (星型模型)
事实表 (Fact Table): FactPowerReadings
TimestampKey
(BIGINT/INTEGER): 外键,关联 DimTime
时间维度表,表示记录发生的时间点(代理键)。FTUKey
(BIGINT/INTEGER): 外键,关联 DimFTU
设备维度表,表示读数来自哪台FTU设备(代理键)。ReadingTimestamp
(TIMESTAMP/DATETIME): 实际的采集时间戳,用于精确分析或追溯。UAB_Voltage
(DECIMAL/FLOAT): 计量UAB电压UBC_Voltage
(DECIMAL/FLOAT): 计量UBC电压UCA_Voltage
(DECIMAL/FLOAT): 计量UCA电压UA_Voltage
(DECIMAL/FLOAT): 计量UA电压UB_Voltage
(DECIMAL/FLOAT): 计量UB电压UC_Voltage
(DECIMAL/FLOAT): 计量UC电压IA_Current
(DECIMAL/FLOAT): 计量IA电流IB_Current
(DECIMAL/FLOAT): 计量IB电流IC_Current
(DECIMAL/FLOAT): 计量IC电流I0_Current
(DECIMAL/FLOAT): 计量I0电流ActivePower_Total
(DECIMAL/FLOAT): 计量总有功功率ActivePower_A
(DECIMAL/FLOAT): 计量A相有功功率ActivePower_B
(DECIMAL/FLOAT): 计量B相有功功率ActivePower_C
(DECIMAL/FLOAT): 计量C相有功功率ReactivePower_Total
(DECIMAL/FLOAT): 计量总无功功率ReactivePower_A
(DECIMAL/FLOAT): 计量A相无功功率ReactivePower_B
(DECIMAL/FLOAT): 计量B相无功功率ReactivePower_C
(DECIMAL/FLOAT): 计量C相无功功率ApparentPower_Total
(DECIMAL/FLOAT): 计量总视在功率ApparentPower_A
(DECIMAL/FLOAT): 计量A相视在功率ApparentPower_B
(DECIMAL/FLOAT): 计量B相视在功率ApparentPower_C
(DECIMAL/FLOAT): 计量C相视在功率LoadTimestamp
(TIMESTAMP): 数据加载到数仓的时间戳(可选,用于审计)。维度表 (Dimension Tables):
DimTime
(时间维度表)
TimestampKey
(BIGINT/INTEGER): 主键(代理键)。FullDateTime
(DATETIME/TIMESTAMP): 完整日期时间 (例如: ‘2025-04-21 19:30:00’)。Date
(DATE): 日期 (例如: ‘2025-04-21’)。Year
(INTEGER): 年份 (例如: 2025)。Quarter
(INTEGER): 季度 (例如: 2)。Month
(INTEGER): 月份 (例如: 4)。DayOfMonth
(INTEGER): 日 (例如: 21)。DayOfWeek
(INTEGER): 星期几 (例如: 1 表示周一)。WeekOfYear
(INTEGER): 年中的第几周。Hour
(INTEGER): 小时 (0-23)。Minute
(INTEGER): 分钟 (0, 15, 30, 45)。TimeOfDay
(VARCHAR): 时间段描述 (例如: ‘凌晨’, ‘上午’, ‘下午’, ‘晚上’)。IsWeekend
(BOOLEAN/TINYINT): 是否周末。DimFTU
(FTU设备维度表)
FTUKey
(BIGINT/INTEGER): 主键(代理键)。FTU_ID
(VARCHAR/BIGINT): FTU设备的业务ID/编号(自然键)。XTUKey
(BIGINT/INTEGER): 外键,关联 DimXTU
表。FTU_Model
(VARCHAR): FTU设备型号。InstallationDate
(DATE): 安装日期。LocationDescription
(VARCHAR): 位置描述 (例如: ‘XX小区XX栋配电箱’, ‘XX路XX号杆’)。Latitude
(DECIMAL): 纬度。Longitude
(DECIMAL): 经度。Status
(VARCHAR): 设备状态 (例如: ‘Active’, ‘Inactive’, ‘Maintenance’)。EffectiveStartDate
(DATE): 生效开始日期 (用于处理缓慢变化维度 SCD Type 2)。EffectiveEndDate
(DATE): 生效结束日期 (用于处理缓慢变化维度 SCD Type 2)。IsCurrent
(BOOLEAN/TINYINT): 是否当前有效记录 (用于处理缓慢变化维度 SCD Type 2)。DimXTU
(XTU设备维度表)
XTUKey
(BIGINT/INTEGER): 主键(代理键)。XTU_ID
(VARCHAR/BIGINT): XTU设备的业务ID/编号(自然键)。XTU_Model
(VARCHAR): XTU设备型号。Substation
(VARCHAR): 所属变电站/区域。IP_Address
(VARCHAR): IP地址 (如果需要)。InstallationDate
(DATE): 安装日期。Status
(VARCHAR): 设备状态。2. 数据仓库 (Data Warehouse) 选型
考虑到数据量、查询性能和可扩展性,以下是一些推荐的选型:
云数据仓库 (推荐):
本地/自建方案:
选型建议: 如果预算允许且希望减少运维负担并获得良好的弹性,强烈推荐云数据仓库 (BigQuery 或 Snowflake)。如果倾向于自建或已有PostgreSQL经验,PostgreSQL + TimescaleDB 是一个非常好的选择。
3. OLAP 引擎选型
OLAP引擎负责处理分析查询。
ROLAP (Relational OLAP): 直接在关系型数据仓库(如BigQuery, Snowflake, PostgreSQL)上执行SQL查询。
MOLAP (Multidimensional OLAP): 将数据预先聚合存储在多维立方体(Cube)中。
HOLAP (Hybrid OLAP): 结合ROLAP和MOLAP,低层细节数据存储在关系型数据库,高层聚合数据存储在Cube中。
选型建议: 鉴于现代数据仓库的性能,建议优先采用ROLAP方式。直接使用BI工具连接您选择的数据仓库进行查询和可视化。大多数情况下,这足以满足需求。如果未来遇到特定查询的性能瓶颈,可以考虑针对性地构建物化视图 (Materialized Views)(大多数现代数仓都支持)进行预聚合,或者在极端情况下引入MOLAP工具如 Apache Druid 或 Apache Kylin (但会增加系统复杂度)。
4. 数据处理流程 (ETL/ELT)
数据从采集端到数据仓库并支持查询的流程如下:
Code snippet
graph LR
subgraph Source [数据源]
FTU[FTU 设备 (7-8 per XTU)] --> XTU[XTU 终端 (5k-10k)];
end
subgraph Ingestion [数据接入]
XTU --> API{数据接收API / MQTT Broker};
end
subgraph Processing [数据处理与加载 (ETL/ELT)]
API --> Stage[Staging Area (e.g., Cloud Storage / Landing Zone)];
Stage --> Transform[数据转换/清洗 (Spark / Dataflow / Python / SQL)];
Transform --> DWH[(Data Warehouse)];
subgraph DWH [数据仓库 (e.g., BigQuery / Snowflake / PG+Timescale)]
DimTime[(DimTime)];
DimFTU[(DimFTU)];
DimXTU[(DimXTU)];
FactPowerReadings[(FactPowerReadings)];
end
Transform -- Lookup --> DimTime;
Transform -- Lookup/Update --> DimFTU;
Transform -- Lookup/Update --> DimXTU;
Transform -- Load --> FactPowerReadings;
end
subgraph Analysis [分析与展现]
DWH --> OLAP{OLAP Engine (ROLAP via DW)};
OLAP --> BI[BI / 可视化工具 (Superset / Metabase / Tableau)];
BI --> User[分析师 / 用户];
end
%% Optional Pre-aggregation
%% DWH --> Aggregation[预聚合/物化视图];
%% Aggregation --> OLAP;
流程说明:
TimestampKey
(关联DimTime
表)。DimFTU
和DimXTU
中的记录,获取对应的FTUKey
和XTUKey
(处理维度变化,如SCD Type 2)。FactPowerReadings
事实表和相应的维度表(如果维度有更新)。ETL/ELT工具选型:
5. OLAP 聚合查询案例
假设我们需要查询 2025年4月20日,每个XTU管理的FTU的平均总有功功率。
SQL
SELECT
dx.XTU_ID, -- XTU 设备ID
dt.Date, -- 日期
AVG(fpr.ActivePower_Total) AS Avg_TotalActivePower -- 平均总有功功率
FROM
FactPowerReadings fpr
JOIN
DimTime dt ON fpr.TimestampKey = dt.TimestampKey
JOIN
DimFTU df ON fpr.FTUKey = df.FTUKey
JOIN
DimXTU dx ON df.XTUKey = dx.XTUKey
WHERE
dt.Date = '2025-04-20' -- 筛选日期
AND df.IsCurrent = TRUE -- 确保使用FTU设备的当前有效记录 (如果使用SCD Type 2)
GROUP BY
dx.XTU_ID,
dt.Date
ORDER BY
dx.XTU_ID;
6. 星型模型 Schema Mermaid 图
erDiagram
DimTime ||--o{ FactPowerReadings : "has"
DimFTU ||--o{ FactPowerReadings : "measures for"
DimXTU ||--o{ DimFTU : "manages"
DimTime {
BIGINT TimestampKey PK "Timestamp Key (PK)"
DATETIME FullDateTime "Full Date Time"
DATE Date "Date"
INT Year "Year"
INT Quarter "Quarter"
INT Month "Month"
INT DayOfMonth "Day of Month"
INT DayOfWeek "Day of Week"
INT Hour "Hour"
INT Minute "Minute (0, 15, 30, 45)"
BOOLEAN IsWeekend "Is Weekend?"
VARCHAR TimeOfDay "Time of Day"
-- ... other time attributes
}
DimFTU {
BIGINT FTUKey PK "FTU Key (PK)"
VARCHAR FTU_ID UK "FTU Business ID (UK)"
BIGINT XTUKey FK "XTU Key (FK)"
VARCHAR FTU_Model "Model"
DATE InstallationDate "Installation Date"
VARCHAR LocationDescription "Location Description"
DECIMAL Latitude "Latitude"
DECIMAL Longitude "Longitude"
VARCHAR Status "Status"
DATE EffectiveStartDate "SCD Start Date"
DATE EffectiveEndDate "SCD End Date"
BOOLEAN IsCurrent "SCD Is Current Flag"
-- ... other FTU attributes
}
DimXTU {
BIGINT XTUKey PK "XTU Key (PK)"
VARCHAR XTU_ID UK "XTU Business ID (UK)"
VARCHAR XTU_Model "Model"
VARCHAR Substation "Substation/Area"
VARCHAR IP_Address "IP Address"
DATE InstallationDate "Installation Date"
VARCHAR Status "Status"
-- ... other XTU attributes
}
FactPowerReadings {
BIGINT TimestampKey FK "Timestamp Key (FK)"
BIGINT FTUKey FK "FTU Key (FK)"
TIMESTAMP ReadingTimestamp "Actual Reading Time"
FLOAT UAB_Voltage "UAB Voltage"
FLOAT UBC_Voltage "UBC Voltage"
FLOAT UCA_Voltage "UCA Voltage"
FLOAT UA_Voltage "UA Voltage"
FLOAT UB_Voltage "UB Voltage"
FLOAT UC_Voltage "UC Voltage"
FLOAT IA_Current "IA Current"
FLOAT IB_Current "IB Current"
FLOAT IC_Current "IC Current"
FLOAT I0_Current "I0 Current"
FLOAT ActivePower_Total "Total Active Power"
FLOAT ActivePower_A "A-Phase Active Power"
FLOAT ActivePower_B "B-Phase Active Power"
FLOAT ActivePower_C "C-Phase Active Power"
FLOAT ReactivePower_Total "Total Reactive Power"
FLOAT ReactivePower_A "A-Phase Reactive Power"
FLOAT ReactivePower_B "B-Phase Reactive Power"
FLOAT ReactivePower_C "C-Phase Reactive Power"
FLOAT ApparentPower_Total "Total Apparent Power"
FLOAT ApparentPower_A "A-Phase Apparent Power"
FLOAT ApparentPower_B "B-Phase Apparent Power"
FLOAT ApparentPower_C "C-Phase Apparent Power"
TIMESTAMP LoadTimestamp "DW Load Time"
}
总结与考虑
FactPowerReadings
上按时间(例如,按月或按天分区)和/或设备ID进行分区,可以极大提高查询性能和数据管理效率。这个方案为您提供了一个结构清晰、可扩展且支持OLAP分析的数据仓库基础。您可以根据具体的技术栈偏好和预算进一步细化选型。