Ask HN: Storing spatial data in SQL
What's the best way to store spatial data in SQL in a way where the query "find all points within x miles of point a" can be performed efficiently.
My initial approach is to store latitude and longitude, and create an index on both longitude and latitude. However, since I'd be querying both longitude and latitude with a range, only one of the indexes would be useful. Basically, the index could narrow down the search to one vertical bar of the entire earth, and then a table scan to find the locations within that bar. (Of course, clustering on latitude first would have the opposite effect: one horizontal band of the earth, and then within the band would be a table scan).
I know there are spatial data types in some of the SQL implementations, but can anything really ever be more efficient than that when doing a "find all points within x miles" type query? If so, how's this possible?
11 comments
[ 3.1 ms ] story [ 30.8 ms ] threadThey also let you perform spatial operations/queries. You can even store GPS 'polygons' and perform queries such as find ones that overlap, find the polygon which covers a specific point, etc. The spatial query support is amazing.
Indexing the Geography datatype is also supported.
http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.a...
Heroku supports it -> http://www.mail-archive.com/heroku@googlegroups.com/msg04556...
But a spatial index will probably do something reasonably close to this.
One big thing to watch out for: The spatial index or z-value index should be clustering, so that the points you retrieve are packed tightly into pages. If the index is not clustering, your index lookup will be fast but you'll pay a lot of IO to bring in all the pages containing the qualifying points.
"PostgreSQL provides several index types: B-tree, R-tree, Hash, and GiST. R-tree indexes are suited for queries on two-dimensional spatial data."
PostGIS: http://postgis.refractions.net/ :
"PostGIS adds support for geographic objects to the PostgreSQL object-relational database. In effect, PostGIS "spatially enables" the PostgreSQL server, allowing it to be used as a backend spatial database for geographic information systems (GIS)"
Also see "Programming the K-means Clustering Algorithm in SQL": http://pdf.cx/6gc9a
Setting up was a small PITA, but a bounding box query looks like this:
If you're interested, check it out: http://finelocalwine.com/If you're using ruby, be sure to have a look at thinking_sphinx which provides a great dsl to configure the index and query it.
Also MongoDB has a built-in geographical index.
I would not personnally roll my own here.