在性能方面,在 mysql 中存储 lon 和 lat GEO 数据的最佳方式是什么?

Performance wise, what's the optimal way to store lon and lat GEO data in mysql?

在自学如何优化设计和构建数据库的过程中,我偶然发现了以下问题:存储地址的 GEO 位置的最佳方式是什么?

经过一些研究,我发现有两种可能性。使用 MySQL geometry 函数并将它们存储为单个列中的 point(lon, lat)

或将它们存储在 2 个单独的列中,如 lon float(10,6)float(10,6)

不过,我发现很少有关于几何函数将使用多少字节来存储信息的信息。

示例创建 table 脚本

CREATE TABLE lonlatAsGeometry (
    ID INT,
    lonlat GEOMETRY
);

INSERT INTO lonlatAsGeometry VALUES (1, point(38.34886, -130.42156));

示例 #2

CREATE TABLE lonlatAsFloat (
    ID INT,
    lon FLOAT(10,6),
    lat FLOAT(10,6)
);

INSERT INTO lonlatAsFloat VALUES (1, 38.34886, -130.42156);

我发现 float 使用 4 个字节来存储数据,

point 根据其中值的长度最多使用 25 个字节。

来源=https://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html

永远不要使用 FLOAT(m,n)。它恰好对 lat/lng 没问题,但它对 inserting/fetching.

的数字做了一些不必要的事情

您需要多少分辨率?

Representation       bytes  Resolution      Use
------------------   ----- ---------------  ------
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6   2.7 m    8.8 ft
FLOAT                  8   1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
DOUBLE                16   3.5nm     ...    Fleas on a dog

-- http://mysql.rjweb.org/doc.php/latlng#representation_choices

回到你的问题...你说的"optimal"是什么意思?以上是在单独存储 lat/lng 时最小化使用 space 的一些选择。如前所述,POINT 占用 25 个字节。如果您的点数少于一百万,那么 space 可能不是什么大问题。但也许 "optimal" 与您 使用 的值有关。如果您正在使用 SPATIAL 功能,那么 POINT 可能是最佳选择。等等

底线:如果您使用 DECIMAL(6,4) 表示纬度 (-90..90) 和 DECIMAL(7,4) 表示经度 (-180..180),则 "addresses on a map" 需要 7 个字节。