文章目录
- 每日一句正能量
- 一、前言:模型改造是迁移的核心
- 二、模型差异分析
- 2.1 InfluxDB模型特点
- 2.2 KaiwuDB模型特点
- 2.3 模型对比
- 三、表结构设计
- 3.1 单表设计
- 3.2 多表设计
- 3.3 分区表设计
- 四、标签设计优化
- 4.1 主标签设计
- 4.2 普通标签设计
- 4.3 字段列设计
- 五、模型改造实战
- 5.1 改造前分析
- 5.2 改造方案
- 5.3 改造后优势
- 六、性能优化
- 6.1 索引优化
- 6.2 分区优化
- 6.3 查询优化
- 七、常见问题
- 7.1 高基数问题
- 7.2 数据类型问题
- 7.3 时间精度问题
- 八、总结
每日一句正能量
你走的每一步都算数,即使现在看不见回报,时间会在未来的某个转角给你惊喜。
所有经历都有价值,回报可能延迟,但一定会以某种形式出现。你读的书、熬的夜、练习的技能,都在默默为那个“转角惊喜”编织底色。
一、前言:模型改造是迁移的核心
前面十四篇文章,我分享了MySQL和InfluxDB迁移KaiwuDB的完整经验。有读者问:“迁移完成后,发现原有的模型设计在KaiwuDB上并不合适,查询性能不理想,怎么办?”
这是个好问题。InfluxDB和KaiwuDB虽然都是时序数据库,但数据模型设计理念不同。InfluxDB的tag/field模型灵活但查询受限,KaiwuDB的主标签/普通标签/字段列模型更规范但需要合理设计。
本文就把InfluxDB到KaiwuDB时序数据模型设计改造的完整经验分享出来,包括模型差异分析、表结构设计、标签设计优化。
二、模型差异分析
2.1 InfluxDB模型特点
InfluxDB采用measurement + tag + field模型:
Measurement: sensor_data Tags: device_id, location, status Fields: temperature, humidity, pressure Time: timestamp特点:
- 灵活:tag和field可以动态添加
- 自动索引:tag自动创建索引
- 无模式:不需要预先定义表结构
- 高写入:适合高频写入场景
问题:
- 高基数:tag值过多导致性能下降
- 查询受限:不支持复杂SQL查询
- 数据膨胀:tag变化导致数据冗余
2.2 KaiwuDB模型特点
KaiwuDB时序引擎采用主标签 + 普通标签 + 字段列模型:
CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签statusSTRING,-- 普通标签temperatureFLOAT,-- 字段列humidityFLOAT,-- 字段列pressureFLOAT-- 字段列);特点:
- 规范:需要预先定义表结构
- 强类型:字段类型明确
- SQL支持:支持标准SQL查询
- 可扩展:支持水平扩展
优势:
- 查询灵活:支持复杂SQL查询
- 性能稳定:不会因为高基数导致性能下降
- 数据一致:强类型保证数据一致性
2.3 模型对比
| 维度 | InfluxDB | KaiwuDB | 说明 |
|---|---|---|---|
| 数据模型 | measurement + tag + field | 主标签 + 普通标签 + 字段列 | 概念对应 |
| 模式定义 | 无模式 | 强模式 | KaiwuDB需要预先定义 |
| 索引 | tag自动索引 | 主标签自动索引 | 都需要设计标签 |
| 查询语言 | InfluxQL | SQL | KaiwuDB更标准 |
| 高基数 | 性能下降 | 性能稳定 | KaiwuDB更优 |
| 扩展性 | 垂直扩展 | 水平扩展 | KaiwuDB更优 |
三、表结构设计
3.1 单表设计
InfluxDB单表:
Measurement: sensor_data Tags: device_id, location Fields: temperature, humidityKaiwuDB单表:
CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签temperatureFLOAT,-- 字段列humidityFLOAT-- 字段列);3.2 多表设计
InfluxDB多表:
Measurement: temperature_data Tags: device_id, location Fields: temperature Measurement: humidity_data Tags: device_id, location Fields: humidityKaiwuDB多表:
-- 温度表CREATETABLEtemperature_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签temperatureFLOAT-- 字段列);-- 湿度表CREATETABLEhumidity_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签humidityFLOAT-- 字段列);3.3 分区表设计
InfluxDB分区:
InfluxDB自动按时间分区,不需要手动设计。
KaiwuDB分区:
-- 按时间分区CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,location STRING,temperatureFLOAT,humidityFLOAT,PRIMARYKEY(time,device_id))PARTITIONBYRANGE(time);-- 创建分区CREATETABLEsensor_data_2023_q1PARTITIONOFsensor_dataFORVALUESFROM('2023-01-01')TO('2023-04-01');CREATETABLEsensor_data_2023_q2PARTITIONOFsensor_dataFORVALUESFROM('2023-04-01')TO('2023-07-01');CREATETABLEsensor_data_2023_q3PARTITIONOFsensor_dataFORVALUESFROM('2023-07-01')TO('2023-10-01');CREATETABLEsensor_data_2023_q4PARTITIONOFsensor_dataFORVALUESFROM('2023-10-01')TO('2024-01-01');四、标签设计优化
4.1 主标签设计
主标签选择原则:
- 高选择性:值分布均匀,避免热点
- 稳定性:值不会频繁变化
- 查询常用:经常用于WHERE条件
InfluxDB tag:
tags: device_id, location, statusKaiwuDB主标签:
-- device_id作为主标签CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签statusSTRING,-- 普通标签temperatureFLOAT,humidityFLOAT);4.2 普通标签设计
普通标签选择原则:
- 辅助查询:用于过滤和分组
- 低基数:值数量不会太多
- 可变性:值可以变化
InfluxDB tag:
tags: device_id, location, statusKaiwuDB普通标签:
-- location和status作为普通标签CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签location STRING,-- 普通标签statusSTRING,-- 普通标签temperatureFLOAT,humidityFLOAT);4.3 字段列设计
字段列选择原则:
- 数值型:温度、湿度、压力等
- 变化频繁:值会随时间变化
- 聚合需求:需要计算平均值、最大值等
InfluxDB field:
fields: temperature, humidity, pressureKaiwuDB字段列:
-- temperature, humidity, pressure作为字段列CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,location STRING,temperatureFLOAT,-- 字段列humidityFLOAT,-- 字段列pressureFLOAT-- 字段列);五、模型改造实战
5.1 改造前分析
InfluxDB模型:
Measurement: sensor_data Tags: device_id, location, status, firmware_version Fields: temperature, humidity, pressure, voltage, current问题分析:
- 高基数:firmware_version值变化频繁,导致高基数
- 数据膨胀:tag变化导致数据冗余
- 查询受限:不支持复杂SQL查询
5.2 改造方案
KaiwuDB模型:
-- 主表:设备基本信息CREATETABLEdevice_info(device_id STRINGPRIMARYKEY,location STRING,statusSTRING,firmware_version STRING,created_atTIMESTAMP);-- 时序表:传感器数据CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签temperatureFLOAT,-- 字段列humidityFLOAT,-- 字段列pressureFLOAT,-- 字段列voltageFLOAT,-- 字段列currentFLOAT-- 字段列);-- 时序表:设备状态CREATETABLEdevice_status(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,-- 主标签statusSTRING,-- 普通标签firmware_version STRING-- 普通标签);5.3 改造后优势
优势1:降低高基数
-- 改造前:firmware_version作为tag,导致高基数-- 改造后:firmware_version作为普通标签,降低高基数-- 查询设备信息SELECT*FROMdevice_infoWHEREdevice_id='device_001';-- 查询传感器数据SELECT*FROMsensor_dataWHEREdevice_id='device_001'ANDtime>now()-INTERVAL'1 hour';优势2:支持复杂查询
-- 改造前:InfluxQL不支持JOIN-- 改造后:SQL支持JOIN-- 查询设备最新状态和传感器数据SELECTd.device_id,d.location,d.status,s.temperature,s.humidity,s.pressureFROMdevice_info dJOINsensor_data sONd.device_id=s.device_idWHEREs.time>now()-INTERVAL'1 hour'ORDERBYs.timeDESC;优势3:数据一致性
-- 改造前:tag变化导致数据冗余-- 改造后:强类型保证数据一致性-- 更新设备信息UPDATEdevice_infoSETfirmware_version='v2.0'WHEREdevice_id='device_001';-- 查询设备信息SELECT*FROMdevice_infoWHEREdevice_id='device_001';六、性能优化
6.1 索引优化
-- 创建主标签索引(自动创建)-- device_id已经是主标签,自动索引-- 创建普通标签索引CREATEINDEXidx_locationONsensor_data(location);CREATEINDEXidx_statusONdevice_status(status);-- 创建时间索引(自动创建)-- time已经是主键的一部分,自动索引6.2 分区优化
-- 按时间分区CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,temperatureFLOAT,humidityFLOAT,PRIMARYKEY(time,device_id))PARTITIONBYRANGE(time);-- 创建分区CREATETABLEsensor_data_2023_q1PARTITIONOFsensor_dataFORVALUESFROM('2023-01-01')TO('2023-04-01');6.3 查询优化
-- 使用索引查询EXPLAINANALYZESELECT*FROMsensor_dataWHEREdevice_id='device_001'ANDtime>now()-INTERVAL'1 hour';-- 使用分区查询EXPLAINANALYZESELECT*FROMsensor_data_2023_q1WHEREdevice_id='device_001';七、常见问题
7.1 高基数问题
问题:device_id数量过多,导致主标签高基数
解决方案:
-- 使用哈希分区CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,temperatureFLOAT,humidityFLOAT,PRIMARYKEY(time,device_id))PARTITIONBYHASH(device_id);-- 创建分区CREATETABLEsensor_data_p0PARTITIONOFsensor_dataFORVALUESWITH(MODULUS4,REMAINDER0);CREATETABLEsensor_data_p1PARTITIONOFsensor_dataFORVALUESWITH(MODULUS4,REMAINDER1);CREATETABLEsensor_data_p2PARTITIONOFsensor_dataFORVALUESWITH(MODULUS4,REMAINDER2);CREATETABLEsensor_data_p3PARTITIONOFsensor_dataFORVALUESWITH(MODULUS4,REMAINDER3);7.2 数据类型问题
问题:InfluxDB的float类型在KaiwuDB中映射为DOUBLE
解决方案:
-- 明确指定类型CREATETABLEsensor_data(timeTIMESTAMPNOTNULL,device_id STRINGNOTNULL,temperatureFLOAT,-- 明确使用FLOAThumidityFLOAT);7.3 时间精度问题
问题:InfluxDB默认使用纳秒精度,KaiwuDB默认使用微秒精度
解决方案:
-- 使用TIMESTAMPTZ保留时区信息CREATETABLEsensor_data(timeTIMESTAMPTZNOTNULL,device_id STRINGNOTNULL,temperatureFLOAT,humidityFLOAT);八、总结
InfluxDB到KaiwuDB时序数据模型设计改造,是迁移成功的关键。
核心改造点:
- 主标签设计:选择高选择性、稳定性、查询常用的字段
- 普通标签设计:选择辅助查询、低基数、可变性的字段
- 字段列设计:选择数值型、变化频繁、有聚合需求的字段
- 表结构设计:合理分区,降低高基数影响
关键经验:
- 理解模型差异:InfluxDB和KaiwuDB的数据模型不同
- 合理设计标签:主标签和普通标签的选择很重要
- 处理数据类型:注意类型映射和精度问题
- 优化查询性能:利用KaiwuDB的SQL优势
- 做好数据校验:确保数据一致性
如果你正在考虑InfluxDB迁移KaiwuDB,建议先做好模型设计,确保迁移后性能满足业务需求。
转载自:https://blog.csdn.net/u014727709/article/details/164125627
欢迎 👍点赞✍评论⭐收藏,欢迎指正