400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
400-800-0824
info@ymatrix.cn
YMatrix 文档
关于 YMatrix
标准集群部署
数据写入
数据迁移
数据查询
运维监控
参考指南
工具指南
数据类型
存储引擎
执行引擎
系统配置参数
SQL 参考
常见问题(FAQ)
新架构 FAQ
集群部署 FAQ
SQL 查询 FAQ
MatrixGate FAQ
运维 FAQ
监控告警 FAQ
PXF FAQ
PLPython FAQ
性能 FAQ
本文档为“时序数据建模”章节的第三篇。YMatrix 认为,数据模型的设计会直接影响到数据消费与使用的价值。因此,除技术介绍外,我们尝试通过整个章节使你对时序数据模型(Time-series Data Model)的概念、应用及发展都有清晰的理解。
注意!
此篇仅为参考示例,正式设计建模前建议至少完整详读 YMatrix 架构及组件原理。组件原理见“参考指南”章节。
车联网是物联网(IoT,Internet of Things)的典型应用场景之一。 据中国香港应用科技研究院所述,车联网技术是指车辆与车辆、车辆与行人、车辆与道路基建以及车辆与云端之间的低时延通讯系统。通过车联网系统中的实时信息传递,实现人、车与道路基建互相协调配合,即时对道路使用者进行路况汇报与警示,藉以加强道路安全和辅助驾驶。同时,车联网技术可应用在实时交通监察、事故管理,和行车路线规划等方面以提高交通效率。长远而言,车联网能配合自动驾驶技术的发展,协助自动驾驶判断隐藏风险,提升道路安全。
车联网的主要分类如下表:
通信端 | 技术实现 | 应用场景 |
---|---|---|
车辆与车辆 | 车辆与车辆之间实现信息交流与信息共享,包括车辆位置、行驶速度等车辆状态信息 | 判断道路车流状况 |
车辆与行人 | 用户可以通过Wi-Fi、蓝牙、蜂窝等无线通信手段与车辆进行信息沟通 | 使用户能通过对应的移动终端设备监测并控制车辆 |
车辆与道路基建 | 借助地面道路固定通信设施实现车辆与道路间的信息交流 | 监测道路路面状况,引导车辆选择最佳行驶路径 |
车辆与云端 | 车辆通过卫星无线通信或移动蜂窝等无线通信技术实现与车联网服务平台的信息传输 | 车辆接受平台下达的控制指令;云端实时共享车辆数据 |
车内设备之间 | 车辆内部各设备间的信息数据传输 | 对车内设备状态进行实时检测与运行控制,建立数字化的车内控制系统 |
可以设想一下,假如你是一个车端应用研发人员,负责管理、维护你就职企业的车辆指标平台 A。现在,你想要就此平台的业务在 YMatrix 中进行建模设计,可能的思路如下:
序号 | 步骤 |
---|---|
1 | 需求调研 |
2 | 建模设计与实施 |
3 | 模型测试 |
车辆指标平台 A 的数据特征:
车辆指标平台 A 的查询特点:
注意!
此场景的“设备”语义指每辆车辆上的不同传感器,每一个传感器称作一个“设备”。
车端预计算完毕的传感器数据 / 埋点数据 -> 云端 -> YMatrix -> 监控页面
结论
经过仔细、全面的前期调研,我们认为在 YMatrix 中,车辆指标平台 A 的指标确定性较高,但仍需要创建一个动态列,以备动态容纳新增或变化的指标。数据规模、设备数量大,应使用结构化+半结构化的宽表变式模型,选择压缩性能良好的 MARS2 存储引擎为基础建表。
据需求调研结果,表结构设计示例如下:
动态列可以选用 MXKV 数据类型,使用此类型需要首先创建扩展。
=# CREATE EXTENSION matrixts;
=# CREATE TABLE V2X (
ts timestamp with time zone,
device_id text,
vehicle_type text,
longitude float,
latitude float,
altitude float,
speed float,
left_turn_signal boolean,
right_turn_signal boolean,
emergency_flashers boolean,
power int,
gas int,
windshield_wiper boolean,
mileage float,
signal_strength text,
power_mode text,
control_mode text,
charging_status text,
mxkv mxkv_int4
)
USING MARS2
DISTRIBUTED BY (device_id,vehicle_type)
PARTITION BY range(ts)
(
START ('2023-01-15') INCLUSIVE
END ('2023-01-30') EXCLUSIVE
EVERY (interval '1 day'),
DEFAULT PARTITION default_p
);
=# CREATE INDEX ON V2X USING mars2_btree (device_id,ts,vehicle_type);
此示例中:
2023-01-15
至 2023-01-30
每一天为一个分区。序号 | 测试计划 | SQL 语句 |
---|---|---|
1 | 查看最新 10 条数据 | SELECT * FROM <表名> ORDER BY ts DESC LIMIT 10 |
2 | 查询总行数 | SELECT COUNT(*) FROM <表名> |
3 | 查询某一设备最新上报的全部指标 | SELECT * FROM <表名> WHERE <设备标签列名> = '<设备标签值>' ORDER BY <时间戳列名> DESC LIMIT 1 |
... |
为结构化指标插入 100 条测试语句。
=# INSERT INTO V2X (ts, device_id, vehicle_type, longitude, latitude, altitude, speed, left_turn_signal, right_turn_signal, emergency_flashers, power, gas, windshield_wiper, mileage, signal_strength, power_mode, control_mode, charging_status)
SELECT
timestamp '2023-01-15 00:00:00+00' + (random() * (timestamp '2023-01-30 00:00:00+00' - timestamp '2023-01-15 00:00:00+00')) AS ts,
'device_' || (random() * 100 + 1)::int AS device_id,
CASE (random() * 3)::int
WHEN 0 THEN 'car'
WHEN 1 THEN 'truck'
WHEN 2 THEN 'motorcycle'
ELSE 'others'
END AS vehicle_type,
-180 + random() * 360 AS longitude,
-90 + random() * 180 AS latitude,
random() * 500 AS altitude,
random() * 100 AS speed,
random() < 0.5 AS left_turn_signal,
random() < 0.5 AS right_turn_signal,
random() < 0.5 AS emergency_flashers,
random() * 100 AS power,
random() * 100 AS gas,
random() < 0.5 AS windshield_wiper,
random() * 10000 AS mileage,
CASE (random() * 3)::int
WHEN 0 THEN 'low'
WHEN 1 THEN 'medium'
WHEN 2 THEN 'high'
ELSE 'others'
END AS signal_strength,
CASE (random() * 3)::int
WHEN 0 THEN 'normal'
WHEN 1 THEN 'eco'
WHEN 2 THEN 'sport'
ELSE 'others'
END AS power_mode,
CASE (random() * 3)::int
WHEN 0 THEN 'auto'
WHEN 1 THEN 'manual'
ELSE 'others'
END AS control_mode,
CASE (random() * 3)::int
WHEN 0 THEN 'not_charging'
WHEN 1 THEN 'charging'
WHEN 2 THEN 'charged'
ELSE 'others'
END AS charging_status
FROM generate_series(1, 100);
测试结果:
=# SELECT * FROM V2X ORDER BY ts DESC LIMIT 10;
ts | device_id | vehicle_type | longitude | latitude | altitude | speed | left_turn_signal | right_turn_signal | emergency_flashers | power | gas | w
indshield_wiper | mileage | signal_strength | power_mode | control_mode | charging_status | mxkv
-------------------------------+-----------+--------------+---------------------+--------------------+--------------------+--------------------+------------------+-------------------+--------------------+-------+-----+--
----------------+--------------------+-----------------+------------+--------------+-----------------+------
2023-01-29 21:53:27.754744+00 | device_58 | motorcycle | -140.79258522765215 | 89.35868408629588 | 209.74325842947826 | 7.559001139516397 | t | t | t | 93 | 65 | f
| 5882.489034161899 | others | sport | others | charging |
2023-01-29 16:50:34.199873+00 | device_81 | car | 81.53072026224788 | 68.19305944227892 | 148.1462308308661 | 13.198297428062489 | t | f | t | 46 | 61 | t
| 4511.35947286371 | medium | sport | others | charging |
2023-01-29 12:55:46.399362+00 | device_64 | truck | -44.714334671379135 | -25.70332357303201 | 467.8799151243442 | 10.891007142353715 | f | t | f | 84 | 35 | t
| 2560.9704263982635 | high | sport | others | charged |
2023-01-28 20:57:47.338926+00 | device_76 | motorcycle | 154.27746736812526 | 62.690265649507495 | 259.82523744619533 | 83.50521685533465 | f | f | t | 89 | 8 | f
| 1532.3430683284655 | high | normal | auto | charged |
2023-01-28 18:05:20.571742+00 | device_92 | car | 83.76965429529218 | 8.049747667089093 | 143.73997285467334 | 12.555222600038718 | t | f | f | 14 | 45 | f
| 9997.57813287939 | medium | eco | others | others |
2023-01-28 08:45:11.965559+00 | device_31 | others | 99.77044288198567 | 12.903015903288804 | 363.75041248912333 | 36.47226613770371 | f | f | t | 69 | 3 | f
| 3691.816009071509 | high | others | manual | not_charging |
2023-01-28 06:18:43.954116+00 | device_46 | motorcycle | -47.38049551213621 | -79.18208378659074 | 175.75280982307186 | 66.30605691081897 | t | f | f | 45 | 54 | t
| 9393.80450096177 | high | others | others | others |
2023-01-28 02:37:52.616967+00 | device_93 | truck | 85.90194913335677 | 40.30649225935946 | 391.81388120428375 | 82.57330803350484 | f | f | f | 26 | 75 | f
| 3785.2133153634427 | medium | eco | others | not_charging |
2023-01-27 22:45:29.482177+00 | device_97 | truck | -84.89970873408637 | 44.363184540463294 | 194.22710732897565 | 75.3934265851349 | t | f | f | 66 | 20 | t
| 778.0037705985521 | medium | eco | manual | charged |
2023-01-27 21:58:16.378729+00 | device_86 | truck | -160.41993080977775 | 29.832974328175652 | 481.3241481940853 | 29.14603485833851 | t | t | f | 27 | 15 | t
| 975.3916463929002 | high | eco | others | charged |
(10 rows)
=# SELECT COUNT(*) FROM V2X;
count
-------
100
(1 row)
查询设备 10
的最新车速。
=# SELECT last_not_null(speed,ts) AS last_speed FROM V2X WHERE device_id = 'device_86' LIMIT 1;
last_speed
-------------------------------------------------------
["29.14603485833851","2023-01-27 21:58:16.378729+00"]
(1 row)
在动态扩展列 mxkv
新增一个 MXKV 类型的指标 car_length
,数据类型为 mxkv_int4
,数据值为 350
(单位 cm)。新增指标前,为了压缩与查询性能优化,需要首先利用 UDF mxkv_import_keys()
定义键值,来提前确定数据中包含的键值集合。
=# SELECT mxkv_import_keys('{"car_length": 350}');
mxkv_import_keys
------------------
car_length
(1 row)
插入这条数据。
=# INSERT INTO V2X(mxkv) values('{"car_length":350}');
INSERT 0 1
查询插入的此条键值。
=# SELECT mxkv->'car_length' as car_length FROM V2X;
注意!
MXKV 使用方法详见扩展数据类型。
注意!
在此只给出了简单的测试示例,更多场景测试示例见图形化界面 轻松上手板块。在实际环境中,请根据具体的查询需求设计具体的测试语句。