Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimal column type for latitude and longitude on Rails and MySQL

I'm wondering what's the best column type to store latitude/longitude on MySQL + Rails.

  • Precision must be enough to store every bit of lat/lng degrees obtained from mobile devices and/or geocoders.
  • Storage requirement should be minimal for the best query performance.

From Google's official document:

http://code.google.com/apis/maps/articles/phpsqlajax_v3.html

With the current zoom capabilities of Google Maps, you should only need 6 digits of precision after the decimal. To keep the storage space required for your table at a minimum, you can specify that the lat and lng attributes are floats of size (10,6). That will let the fields store 6 digits after the decimal, plus up to 4 digits before the decimal, e.g. -123.456789 degrees.

So, actually FLOAT(10,6) is recommended by Google.

However, with Rails 3, there seems no easy way to define FLOAT column type with precision after the decimal point. For instance, you could write a migration with raw SQL as follows:

def self.up
  execute <<-SQL
  ALTER TABLE places
    ADD `lat` FLOAT(10,6),
    ADD `lng` FLOAT(10,6)
  SQL
  add_index :places, [ :lat, :lng ]
end

But the schema.rb as a consequence will look like this:

t.float "lat", :limit => 10
t.float "lng", :limit => 10

which is missing the precision for the fractional part.

Here I can see several options:

  • Use FLOAT(10,6) for optimal production performance, and don't dump schema (e.g. rake db:test:load) on development.
  • Use DECIMAL(10,6), which is supported by Rails, but it takes 6 bytes, 1.5 times larger than FLOAT (see: http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html). Maybe this would be a good compromise?
  • Use DOUBLE, which is much roomier than Google's requirement, and takes 8 bytes, 2 times larger than FLOAT. It's simple as well.

What's your recommendation?

like image 201
kenn Avatar asked Jun 15 '11 00:06

kenn


People also ask

What should be the data type for latitude and longitude?

Latitude and Longitude should use DECIMAL datatype instead of FLOAT #4923.

What is the datatype for latitude and longitude in MySQL?

precision you should use DECIMAL . Latitudes range from -90 to +90 (degrees), so DECIMAL(10,8) is ok for that, but longitudes range from -180 to +180 (degrees) so you need DECIMAL(11,8) .

Which of the following is the best data type to store latitude and longitude coordinates that are in decimal degrees?

Use DECIMAL(8,6) for latitude (90 to -90 degrees) and DECIMAL(9,6) for longitude (180 to -180 degrees). 6 decimal places is fine for most applications. Both should be "signed" to allow for negative values. DECIMAL type is intended for financial calculations where no floor/ceil is accepted.

How do you store latitude and longitude in a database?

Storing Latitude & Longitude data as Floats or Decimal This is one of the most fundamental ways of storing geocoordinate data. Latitude & longitude values can be represented & stored in a SQL database using decimal points (Decimal degrees) rather than degrees (or Degrees Minutes Seconds).


2 Answers

KISS (i.e. submit to the framework), it's not a lot of bytes. It'll only matter more if you're using particular indexes.

like image 68
raggi Avatar answered Oct 26 '22 05:10

raggi


Depending on the type of query you want to do on your data, you might want to look into the geometry type:

http://dev.mysql.com/doc/refman/5.1/en/creating-a-spatially-enabled-mysql-database.html

I'm not familiar with RoR, but this line, in particular:

add_index :places, [ :lat, :lng ]

... seems to indicate that you're planning to run geospatial queries. If so, the index will be useless for all intents and purposes, because a btree index won't help for nearest-neighbor point searches.

like image 23
Denis de Bernardy Avatar answered Oct 26 '22 05:10

Denis de Bernardy