我正在使用一小部分网络划分器来获取各种设备的当前GPS位置。我也想保留历史记录。如果不将数据存储两次,最好的方法是什么?现在我有两张桌子,看起来像这样:
Column | Type | Modifiers | Storage | Description
---------+-----------------------------+---------------+----------+-------------
vehicle | character varying(20) | | extended |
course | real | | plain |
speed | real | | plain |
fix | smallint | | plain |
lat | real | | plain |
lon | real | | plain |
time | timestamp without time zone | default now() | plain |
一个名为gps
,另一个名为gps_log
。更新这两者的功能有两个作用:首先它在INSERT
上执行gps_log
,然后在UPDATE OR INSERT
上执行gps
(用户定义的函数)。然而,这导致我认为除了容易SELECT
能够访问当前数据之外,用于其他目的的双重存储的无意义情况。
是否有一种简单的方法只使用gps_log
并且只有一个函数选择每个vehicle
的最新条目?请注意,gps_log
目前有1397150行每15分钟增加约150行,因此性能可能会成为一个问题。
通过Perl DBI使用PostgreSQL 8.4。
答案 0 :(得分:1)
如果SELECT
性能至关重要,那么您当前使用冗余存储的解决方案可能不是一个坏主意。
如果你摆脱了冗余表,你可以使用multi-column index来帮助SELECT
表现:
CREATE INDEX gps_log_vehicle_time ON gps_log (vehicle, time DESC);
假设vehicle
是您的主键
会使这个相应的查询非常快:
SELECT *
FROM gps_log
WHERE vehicle = 'foo'
ORDER BY time DESC
LIMIT 1;
SELECT
多个或所有行的最后一个条目use this related technique。
总存储大小可能增长,因为如果每辆车有很多行,索引将比冗余表(+索引)大。
将串行列添加为代理主键而不是vehicle
可能有助于存储和性能。特别是如果你有外键指向它。
除此之外:不要使用time
作为列名。它是PostgreSQL中的类型名称,并且在每个SQL标准中都是reserved word。为timestamp
列time
命名也是误导。