保留历史记录以及当前概述

时间:2012-11-28 09:00:11

标签: performance postgresql database-design indexing

我正在使用一小部分网络划分器来获取各种设备的当前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。

1 个答案:

答案 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。为timestamptime命名也是误导。