[mysql] 소수점 이하 8 자리의 위도 / 경도로 어떤 MySQL 데이터 유형을 사용해야합니까?

지도 데이터로 작업하고 있으며 Latitude/Longitude소수점 이하 8 자리까지 확장됩니다. 예를 들면 다음과 같습니다.

Latitude 40.71727401
Longitude -74.00898606

나는
다음을 사용 하는 Google 문서 에서 보았습니다 .

lat FLOAT( 10, 6 ) NOT NULL,
lng FLOAT( 10, 6 ) NOT NULL

그러나, 자신의 소수점은 6로 이동
합니다 I 사용 FLOAT(10, 8)하거나 정확한 그래서이 데이터를 저장하기 위해 고려해야 할 다른 방법이있다. 지도 계산에 사용됩니다. 감사!



답변

DECIMAL은 정확한 산술을위한 MySQL 데이터 유형입니다. FLOAT와 달리 정밀도는 모든 크기의 크기에 대해 고정되므로 FLOAT 대신 FLOAT를 사용하면 일부 계산을 수행 할 때 정밀도 오류를 피할 수 있습니다. 계산하지 않고 숫자를 저장하고 검색하는 경우 실제로는 DECIMAL을 사용하는 데 아무런 해가 없지만 FLOAT는 안전합니다. 계산으로 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이 부동 소수점 데이터 유형과 작동하는 방식을 설명합니다.

UPDATE : MySQL이 지원하는 공간 데이터 유형Point사용될 수있는 단일 값 유형이다. 예:

CREATE TABLE `buildings` (
  `coordinate` POINT NOT NULL,
  /* Even from v5.7.5 you can define an index for it */
  SPATIAL INDEX `SPATIAL` (`coordinate`)
) ENGINE=InnoDB;

/* then for insertion you can */
INSERT INTO `buildings`
(`coordinate`)
VALUES
(POINT(40.71727401 -74.00898606));


답변

또한 float값이 반올림 되었음을 알 수 있습니다.

// 예 : 주어진 값 41.0473112,29.0077011

플로트 (11,7) | 십진수 (11,7)
---------------------------
41.0473099 | 41.0473112
29.0077019 | 29.0077011


답변

laravel 에서 마이그레이션에 십진 열 유형을 사용했습니다.

$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);

자세한 내용 사용 가능한 열 유형을 참조하십시오.


답변

데이터 유형을 부호있는 정수로 설정할 수 있습니다. 좌표를 SQL에 저장하면 lat * 10000000 및 long * 10000000으로 설정할 수 있습니다. 그리고 거리 / 반경으로 선택할 때 저장 좌표를 10000000으로 나눕니다. 300K 행으로 테스트했는데 쿼리 응답 시간이 좋습니다. (2 x 2.67GHz CPU, 2GB RAM, MySQL 5.5.49)


답변

float를 사용하지 마십시오. 좌표가 둥글게되어 이상한 결과가 발생합니다.

십진수 사용


답변

MySQL은 이제이 질문이 제기 된 이후 공간 데이터 유형을 지원합니다. 따라서 현재 허용되는 대답은 틀리지 않지만 주어진 다각형 내의 모든 점을 찾는 것과 같은 추가 기능을 찾고 있다면 POINT 데이터 유형을 사용하십시오.

지형 공간 데이터 유형공간 분석 기능 에 대한 MySQL의 문서 확인


답변

Lat / Lng을 MySQL에 저장하는 가장 좋은 방법은 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));