什么MySQL数据类型应该用于纬度/经度8位小数?

Edw*_*ard 227 mysql floating-point types

我正在使用地图数据,并Latitude/Longitude扩展到8位小数.例如:

Latitude 40.71727401
Longitude -74.00898606
Run Code Online (Sandbox Code Playgroud)

我在Google文档中看到 它使用:

lat FLOAT( 10, 6 ) NOT NULL,  
lng FLOAT( 10, 6 ) NOT NULL
Run Code Online (Sandbox Code Playgroud)

但是,它们的小数位只有6个.
我应该使用FLOAT(10, 8)还是有另一种方法来考虑存储这些数据,这样才能准确.它将与地图计算一起使用.谢谢!

gan*_*ter 548

DECIMAL是用于精确算术的MySQL数据类型.与FLOAT不同,它的精度对于任何数量的大小都是固定的,因此通过使用它而不是FLOAT,可以避免在进行某些计算时出现精度误差.如果您只是在不计算的情况下存储和检索数字,那么在实践中FLOAT是安全的,尽管使用DECIMAL没有任何害处.通过计算FLOAT仍然大部分没问题,但绝对确定8d.p. 精度你应该使用DECIMAL.

纬度范围从-90到+90(度),因此DECIMAL(10,8)就可以了,但经度范围从-180到+180(度),所以你需要DECIMAL(11,8).第一个数字是存储的总位数,第二个数字是小数点后面的数字.

简而言之: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

解释了MySQL如何使用浮点数据类型.

  • 也许我的回答误用了"精确"这个词,因为DECIMAL仍然只能提供精确度.我的观点是它*是*那么准确.当然,一些计算会扩大错误.如果我有一个DECMIAL x那么sin(x ^ 100)将会离开.但是如果(使用DECIMAL(10,8)或FLOAT(10,8))我计算0.3/3然后DECIMAL给出0.100000000000(正确),而浮点数给出0.100000003974(正确到8dp,但如果乘以则会错误).我理解主要区别在于如何存储数字.DECIMAL存储十进制数字,其中FLOAT存储二进制近似值. (9认同)
  • 8 位小数为 1.1 毫米(小于 1/16 英寸)精度。为什么你需要纬度和经度? (2认同)
  • 这个问题的答案(http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude)给出了有关不同数量的精度的信息.纬度和经度的小数位. (2认同)

Jig*_*sar 40

在 Laravel 中使用十进制列类型进行迁移

$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);
Run Code Online (Sandbox Code Playgroud)

有关更多信息, 请参阅可用的列类型

  • laravel 也有其道理。为什么使用浮点数或为什么使用点? (5认同)

K-G*_*Gun 14

此外,您将看到float四舍五入的值.

// e.g: given values 41.0473112,29.0077011

float(11,7) | decimal(11,7)
---------------------------
41.0473099  | 41.0473112
29.0077019  | 29.0077011

  • 给我看一张可以区分这两个点的有用地图。我声称这两种表示都是“不必要的精确”。 (4认同)
  • 您可以使用具有所需精度的“double”数据类型。 (2认同)

小智 9

不要使用浮动...它会四舍五入你的坐标,导致一些奇怪的事件。

使用十进制


小智 9

小数点后 6 位的精度约为 16 厘米,这意味着如果两个物体之间的距离小于 16 厘米,则它们具有相同的纬度和经度。

另外,在 mariadb/mysql 中,如果我们有大量数据用于索引,那么使用 float/double 并不理想,并且 Point 数据类型对于数据大小来说是开销。最好使用十进制或将 lat long 转换为 INT。

使用小数点后 6 位是一个不错的选择,因为我们可以忽略转换,而且我们只有 16 厘米的误差,经度在 -180 到 180 之间,因此需要比纬度多 1 位,纬度在 -90 到 90 度之间:

Lat DECIMAL(8,6)
Lng DECIMAL(9,6) 
Run Code Online (Sandbox Code Playgroud)

我们可以扩展到小数点后 8 位:

Lat DECIMAL(10,8)
Lng DECIMAL(11,8) 
Run Code Online (Sandbox Code Playgroud)

MySQL 参考

Mariadb 参考


ΔO *_*ro' 8

我相信在 MySQL 中存储 Lat/Lng 的最佳方法是拥有一个带有 SPATIAL 索引的 POINT 列(2D 数据类型)。

CREATE TABLE `cities` (
  `zip` varchar(8) NOT NULL,
  `country` varchar (2) GENERATED ALWAYS AS (SUBSTRING(`zip`, 1, 2)) STORED,
  `city` varchar(30) NOT NULL,
  `centre` point NOT NULL,
  PRIMARY KEY (`zip`),
  KEY `country` (`country`),
  KEY `city` (`city`),
  SPATIAL KEY `centre` (`centre`)
) ENGINE=InnoDB;


INSERT INTO `cities` (`zip`, `city`, `centre`) VALUES
('CZ-10000', 'Prague', POINT(50.0755381, 14.4378005));
Run Code Online (Sandbox Code Playgroud)


Bil*_*l-- 7

自从提出这个问题以来,MySQL 现在支持空间数据类型。因此,当前接受的答案并没有错,但是如果您正在寻找其他功能,例如查找给定多边形内的所有点,请使用 POINT 数据类型。

查看有关地理空间数据类型空间分析功能的 Mysql Docs


小智 6

您可以将数据类型设置为有符号整数.将坐标存储到SQL时,可以设置为lat*10000000和long*10000000.当您选择距离/半径时,您将存储坐标划分为10000000.我用300K行测试它,查询响应时间很好.(2 x 2.67GHz CPU,2 GB RAM,MySQL 5.5.49)