用户业务中,通常是以轨迹点的形式写入,而分析时却会分析整条轨迹,因此,需要将轨迹点聚合成为轨迹。
将轨迹点聚合成为轨迹的方法如下:
- 手动同步:每隔一段时间,用户手动或自动将点表新插入的轨迹点同步到轨迹表中。但点表和轨迹表不能实时同步。
- 自动同步:通过触发器,在插入点表时,自动将点同步到轨迹表中。点表和轨迹表可以实时同步,但会影响点表的写入性能。
手动同步SQL示例:
说明 手动同步时,需要在点表上增加一列以标记此点是否已经同步到轨迹表。
-- 在点表增加一列标记是否同步,并建立索引
ALTER TABLE sample_points ADD COLUMN sync bool DEFAULT false;
CREATE INDEX ON sample_points USING btree(sync);
-- 创建函数,将未同步的轨迹点同步到轨迹表中
CREATE OR REPLACE FUNCTION trajectory_cast_append()
RETURNS void
AS $$
BEGIN
INSERT INTO trajectory_table
SELECT userid, ST_Sort(ST_MakeTrajectory(pnts.tjraw, true, '{"intensity"}'::cstring[]))
FROM
(SELECT sample_points.userid, array_agg(ROW(sample_points.sample_time, sample_points.x, sample_points.y, sample_points.z, sample_points.intensity)) as tjraw FROM sample_points WHERE sync = false GROUP BY userid) pnts
ON CONFLICT(userid) DO UPDATE
SET traj = ST_Append(trajectory_table.traj, excluded.traj);
UPDATE sample_points
SET sync = true WHERE sync = false;
END;
$$ LANGUAGE plpgsql STRICT PARALLEL SAFE;
--手动执行同步任务
SELECT trajectory_cast_append();
自动同步SQL示例:
-- 创建Trigger函数
CREATE OR REPLACE FUNCTION trajectory_sync_point() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO trajectory_table
SELECT NEW.userid, ST_MakeTrajectory(array_agg(ROW(NEW.sample_time, NEW.x, NEW.y, NEW.z, NEW.intensity)), true, '{"intensity"}'::cstring[])
ON CONFLICT(userid) DO UPDATE
SET traj = ST_Append(trajectory_table.traj, excluded.traj);
RETURN NULL;
END;
$$
LANGUAGE plpgsql STRICT PARALLEL SAFE;
-- 创建同步Trigger
CREATE TRIGGER point_trigger AFTER INSERT ON sample_points
FOR EACH ROW EXECUTE PROCEDURE trajectory_sync_point();