Thingsboard存储遥测数据的表主要是分区表ts_kv,按月份分区存储,每一个月生成一个分区表,存储的是全部的每分每秒的数据。
在数据库中有一个函数get_partition_by_system_ttl_date,规定了分区策略以这个月初到下个月初为范围存储。
CREATE OR REPLACE FUNCTION "public"."get_partition_by_system_ttl_date"(IN "partition_type" varchar, IN "date" timestamp, OUT "partition" varchar)
RETURNS "pg_catalog"."varchar" AS $BODY$
BEGIN
CASE
WHEN partition_type = 'DAYS' THEN
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM') || '_' || to_char(date, 'dd');
WHEN partition_type = 'MONTHS' THEN
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM');
WHEN partition_type = 'YEARS' THEN
partition := 'ts_kv_' || to_char(date, 'yyyy');
ELSE
partition := NULL;
END CASE;
IF partition IS NOT NULL THEN
IF NOT EXISTS(SELECT
FROM pg_tables
WHERE schemaname = 'public'
AND tablename = partition) THEN
partition := NULL;
RAISE NOTICE 'Failed to found partition by ttl';
END IF;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
另一个表为ts_kv_latest表,主要存储最新的遥测数据。
此外,还有一张表ts_kv_dictionary表结构如下
key为前端显示的遥测数据键名,key_id为Thingsboard为每一个遥测键名生成的自增的对应id。
ts_kv_latest和ts_kv以entity_id和key_id作为复合查询条件,以不同的entity_id去区分相同的key_id属于哪个设备。
假设存在两台设备device1和device2,均存在遥测键名0和1。
0和1在ts_kv_dictionary表中对应的key_id为54和55。
device1
数据对应0的值为30,1的值为31
device2
数据对应0的值为40,1的值为41
那么不同设备相同的键名会如何存储呢?
从上图可以看到,虽然key是相同的,但是entity_id是不同的,所以值并不会被覆盖或者混淆。