1

我正在使用一小部分网络爬虫来获取各种设备的当前 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。更新这两个的函数做了两件事:首先它执行一个INSERTon gps_log,然后它执行一个UPDATE OR INSERT(用户定义的函数) on gps。但是,这导致在我看来,除了轻松SELECT访问当前数据之外,出于其他目的进行双重存储是毫无意义的。

有没有一种简单的方法只使用gps_log一个函数并且只为每个函数选择最新的条目vehicle?请记住,gps_log当前有 1397150 行增加,大约每 15 分钟增加 150 行,因此性能可能是一个问题。

通过 Perl DBI 使用 PostgreSQL 8.4。

4

1 回答 1

1

如果SELECT性能是最重要的,那么您当前的冗余存储解决方案可能不是一个坏主意。

如果您摆脱了冗余表,则可以使用多列索引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多行或所有行的最后一个条目,请使用此相关技术

但是,总存储大小可能会增长,因为如果每辆车有很多行,则索引将大于冗余表(+ 索引)。

将串行列添加为代理主键而不是vehicle. 特别是如果您有指向它的外键。

另外:不要time用作列名。它是 PostgreSQL 中的类型名称和每个 SQL 标准中的保留字timestamp命名列也是一种误导time

于 2012-11-28T09:07:54.743 回答