存储对称数据矩阵的最佳方法nxn = 26亿

时间:2014-05-06 11:41:24

标签: sql postgresql postgis

我安装了postgis扩展程序的postgresql和带lat / long作为点字段的zipcodes数据表。我希望在一些拉链的可变距离内返回拉链,如

返回拉链12345 x英里内的所有拉链

大约有51,000个邮政编码。预计算所有将允许查找而无需计算。现在我正在进行动作。计算出的数据可以排列在对称矩阵中。

我正在考虑这个解决方案:

如果我们接受zip自身的距离隐含为零,那么我可以加载一个n ^ 2/2-n行(约13亿行)的表,列z1 z2 d,然后在z1 + d上执行复合索引以返回包含z2列表的查询集。

我的问题是你如何处理它以便即时有效地返回。所有距离计算后可能放弃sql?请问我如何在查询时进行comps?我不太关心完整的距离计算时间或索引时间。我每年都会这样做,或者最多每季度一次。存储可能也是一个问题?

3 个答案:

答案 0 :(得分:1)

这是一个有趣的问题。我认为rdbms非常适合这项任务。不需要放弃它。

至于存储预先计算的距离:我只会在真正需要的情况下执行此操作,即如果您遇到性能问题。毕竟它必须维护的冗余数据。如果你决定这样一张桌子,我同意Vesper;存储所有n ^ 2行,否则您将始终必须组合两个查询;一个在z1中查找您的邮政编码,一个在z2中查找。

但也许你可以加快现有的查询速度。我不知道你是怎么做到的。我记得距离的公式非常复杂。所以我要做的是首先计算在所需范围内的极端纬度和经度(即如果我保持在同一纬度,那个范围内的最小和最大经度是多少;如果我保持相同的经度,那么是最小和最大纬度)。使用计算出的值,您可以使用BETWEEN选择该矩形中的所有邮政编码(因此经度和纬度上的索引可能会派上用场),然后只对所找到的记录使用确切的公式。

编辑:我已经考虑过了。如果此数据库仅存在于您描述的任务中,那么为什么不为此特定目的使用另一个表。你提到存储是对的。这个表需要几GB,索引也会占用很多空间。但是如果有足够的硬盘空间,这应该没问题。

答案 1 :(得分:1)

你考虑过使用EarthDistance吗?在其中,您可以索引"框"这些领域基本上是"平方和#34;你的搜索区域不是圆形的,所以它可以更容易索引..然后,在你的查询中,你还包括一个" radius"类型查询,消除使用box方法返回的额外结果。

http://www.postgresql.org/docs/9.2/static/earthdistance.html

答案 2 :(得分:1)

Postgres / PostGIS空间索引旨在完成这种搜索。它们基于R树,http://en.wikipedia.org/wiki/R_tree,它基本上将您的空间数据细分为方框,即它是一个二维的。有一个函数ST_DWithin,它将返回距离x内的一些其他几何体的所有几何形状。因此,给定一个代表纬度/经度位置的邮政编码和点(称为geom)表,您可以编写查询,例如,

select zip, geom from zipcodes z, 
  (select geom from zipcodes where zip=12345) s 
where ST_DWithin(s.geom, z.geom, 10000)
  order by ST_Distance(s.geom, z.geom) limit 5;

将在邮政编码12345的10公里内返回最近的5个邮政编码。

由于您可以非常有效地索引邮政编码和几何字段,因此存储所有可能距离的矩阵将是不必要的,因为空间索引在数千万行中表现良好。

在Posgis中创建空间索引非常简单;

create index ix_spatial_zips on zipcodes using gist(geom);

我意识到这并不能完全回答你的原始问题,但这意味着你只需要存储51,000行,而不是那个数字的笛卡尔积,而且性能也会更好。