What is the ideal data type to use when storing latitude / longitude in a MySQL database?

前端 未结 21 2902
梦如初夏
梦如初夏 2020-11-22 09:40

Bearing in mind that I\'ll be performing calculations on lat / long pairs, what datatype is best suited for use with a MySQL database?

21条回答
  •  再見小時候
    2020-11-22 10:23

    TL;DR

    Use FLOAT(8,5) if you're not working in NASA / military and not making aircrafts navi systems.


    To answer your question fully, you'd need to consider several things:

    Format

    • degrees minutes seconds: 40° 26′ 46″ N 79° 58′ 56″ W
    • degrees decimal minutes: 40° 26.767′ N 79° 58.933′ W
    • decimal degrees 1: 40.446° N 79.982° W
    • decimal degrees 2: -32.60875, 21.27812
    • Some other home-made format? Noone forbids you from making your own home-centric coordinates system and store it as heading and distance from your home. This could make sense for some specific problems you're working on.

    So the first part of the answer would be - you can store the coordinates in the format your application uses to avoid constant conversions back and forth and make simpler SQL queries.

    Most probably you use Google Maps or OSM to display your data, and GMaps are using "decimal degrees 2" format. So it will be easier to store coordinates in the same format.

    Precision

    Then, you'd like to define precision you need. Of course you can store coordinates like "-32.608697550570334,21.278081997935146", but have you ever cared about millimeters while navigation to the point? If you're not working in NASA and not doing satellites or rockets or planes trajectories, you should be fine with several meters accuracy.

    Commonly used format is 5 digits after dots which gives you 50cm accuracy.

    Example: there is 1cm distance between X,21.2780818 and X,21.2780819. So 7 digits after dot give you 1/2cm precision and 5 digits after dot will give you 1/2 meters precision (because minimal distance between distinct points is 1m, so rounding error cannot be more than half of it). For most civil purposes it should be enough.

    degrees decimal minutes format (40° 26.767′ N 79° 58.933′ W) gives you exactly the same precision as 5 digits after dot

    Space-efficient storage

    If you've selected decimal format, then your coordinate is a pair (-32.60875, 21.27812). Obviously, 2 x (1 bit for sign, 2 digits for degrees and 5 digits for exponent) will be enough.

    So here I'd like to support Alix Axel from comments saying that Google suggestion to store it in FLOAT(10,6) is really extra, because you don't need 4 digits for main part (since sign is separated and latitude is limited to 90 and longitude is limited to 180). You can easily use FLOAT(8,5) for 1/2m precision or FLOAT(9,6) for 50/2cm precision. Or you can even store lat and long in separated types, because FLOAT(7,5) is enough for lat. See MySQL float types reference. Any of them will be like normal FLOAT and equal to 4 bytes anyway.

    Usually space is not an issue nowadays, but if you want to really optimize the storage for some reason (Disclaimer: don't do pre-optimization), you may compress lat(no more than 91 000 values + sign) + long(no more than 181 000 values + sign) to 21 bits which is significantly less than 2xFLOAT (8 bytes == 64 bits)

提交回复
热议问题