用戶業務中,通常是以軌跡點的形式寫入,而分析時卻會分析整條軌跡,因此,需要將軌跡點聚合成為軌跡。

將軌跡點聚合成為軌跡的方法如下:
  • 手動同步:每隔一段時間,用戶手動或自動將點表新插入的軌跡點同步到軌跡表中。但點表和軌跡表不能實時同步。
  • 自動同步:通過觸發器,在插入點表時,自動將點同步到軌跡表中。點表和軌跡表可以實時同步,但會影響點表的寫入性能。
手動同步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();