무엇인가에 이상적인 데이터 입력을 사용할 때 저장하기 위도/경도 MySQL 데이터베이스에?

StackOverflow https://stackoverflow.com/questions/159255

문제

베어링 마음에서는 계산을 수행하에 위도/경도 쌍,어떤 데이터 유형에 가장 적합한 사용할 MySQL 데이터베이스?

도움이 되었습니까?

해결책

MySQL을 사용하십시오 공간 확장 GIS와 함께.

다른 팁

Google은 Google지도를 사용하여 "저장 로케이터"애플리케이션을 위해 PHP/MySQL 솔루션을 마치기 시작합니다. 이 예에서는 LAT/LNG 값을 "10,6"의 길이로 "float"로 저장합니다.

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

기본적으로 위치에 필요한 정밀도에 따라 다릅니다. Double을 사용하면 3.5nm 정밀도가 있습니다. 10 진수 (8,6)/(9,6)는 16cm로 내려갑니다. 플로트는 1.7m입니다 ...

이 매우 흥미로운 테이블에는 더 완전한 목록이 있습니다. http://mysql.rjweb.org/doc.php/latlng :

Datatype               Bytes            Resolution

Deg*100 (SMALLINT)     4      1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5      1570 m    1.0 mi  Cities
SMALLINT scaled        4       682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6        16 m     52 ft  Houses/Businesses
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
Deg*10000000 (INT)     8        16mm    5/8 in  Marbles
DOUBLE                16       3.5nm     ...    Fleas on a dog

도움이 되었기를 바랍니다.

MySQL 의 공간의 확장자는 최선의 선택을 가지고 있기 때문에 전체 목록의 공간 연산자와 인덱스에서 당신의 처분에 있습니다.공간 인덱스를 수행할 수 있는 거리-기준으로 계산을 매우 빠르게 합니다.음을 유의하시기 바랍로 6.0,공간 연장은 아직 끝나지 않았음을 의미합니다.나는 내려 놓 MySQL 공간만 당신이 알려주의 함정을 하기 전에 당신은 너무 멀리와 함께합니다.

는 경우 다루고 엄격하게 포인트로만 거리는 기능이다.당신이해야 할 모든 계산을 가진 다각형,라인,또는 버퍼 포인트 공간 연산자를 제공하지 않은 정확한 결과를 사용하지 않는 경우에는"관련"연산자입니다.시의 상단에 경고 21.5.6.의 관계 등을 포함,이내에,또는 교차를 사용하는 경우,지 않는 정확한 기하학 형상(예:타원을 취급한 사각형).

또한 거리에서 MySQL 공간에 같은 단위의 첫번째 형상입니다.이미 사용하는 경우에는 Decimal Degrees,다음의 거리 측정에 Decimal Degrees.이것은 매우 어려운 것입한 정확한 결과를 얻을 수으로 당신을 얻을 furthur 적도에서.

ARINC424에서 구축 된 내비게이션 데이터베이스를 위해이 작업을 수행했을 때 상당한 양의 테스트를 수행하고 코드를 되돌아 보면 소수점 (18,12) (실제로 숫자 (18,12)가 파이어 버드이기 때문에)를 사용했습니다.

플로트와 복식은 정확하지 않으며 반올림 오류가 발생하여 매우 나쁜 일이 될 수 있습니다. 문제가있는 실제 데이터를 찾았다면 기억이 나지 않지만 플로트 나 이중으로 정확하게 저장할 수 없다는 것이 문제를 일으킬 수 있다고 확신합니다.

요점은 정도 또는 라디안을 사용할 때 값의 범위를 알고 있으며, 분수 부품은 가장 많은 숫자가 필요하다는 것입니다.

그만큼 MySQL 공간 확장 그들이 따르는 좋은 대안입니다 OpenGIS 형상 모델. 데이터베이스를 휴대용으로 유지해야했기 때문에 사용하지 않았습니다.

필요한 정밀도에 따라 다릅니다.

Datatype           Bytes       resolution
------------------ -----  --------------------------------
Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
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
Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
DOUBLE                16   3.5nm     ...    Fleas on a dog

에서: http://mysql.rjweb.org/doc.php/latlng

요약하려면 :

  • 가장 정확한 옵션은입니다 DOUBLE.
  • 가장 일반적인 유형은 사용됩니다 DECIMAL(8,6)/(9,6).

현재 MySQL 5.7, 사용 고려하십시오 공간 데이터 유형 (SDT), 특히 POINT 단일 좌표를 저장합니다. 5.7 이전에는 SDT가 인덱스를 지원하지 않습니다 (테이블 유형이 MyISAM 인 경우 5.6을 제외하고).

메모:

  • 사용할 때 POINT 클래스, 좌표 저장에 대한 인수의 순서는 POINT(latitude, longitude).
  • 특별한 구문이 있습니다 공간 색인 생성.
  • SDT를 사용하면 가장 큰 이점은 귀하가 액세스 할 수 있다는 것입니다. 공간 분석 기능, 예를 들어 두 지점 사이의 거리를 계산합니다 (ST_Distance) 및 한 지점이 다른 영역 내에 포함되어 있는지 여부를 결정합니다 (ST_Contains).

이 위키 기사를 기반으로합니다http://en.wikipedia.org/wiki/decimal_degrees#accuracyMySQL의 적절한 데이터 유형은 별도의 필드에 경도와 위도를 저장하기위한 10 진수 (9,6)입니다.

사용 DECIMAL(8,6) 위도 (90 ~ -90도) 및 DECIMAL(9,6) 경도 (180 ~ -180도). 6 진수 자리는 대부분의 응용 분야에서 괜찮습니다. 음수 값을 허용하기 위해 둘 다 "서명"해야합니다.

Google지도에 따르면, LAT 및 LNG의 경우 최고 (10,6)입니다.

우리는 Oracle 데이터베이스에 위도/경도 x 1,000,000을 두 배로 반올림 오류를 피하기 위해 숫자로 저장합니다.

6 번째 소수점까지의 위도/경도가 10cm 정확도 였다는 점을 감안할 때 우리가 필요한 모든 것이 었습니다. 다른 많은 데이터베이스도 LAT/Long을 6 번째 소수점으로 저장합니다.

완전히 다르고 간단한 관점에서 :

이렇게하면 인덱싱 번호 및 좌표를 망칠 수있는 데이터 유형과 관련된 다른 모든 문제에 대해 걱정할 필요가 없습니다.

응용 프로그램에 따라 Float (9,6)를 사용하는 것이 좋습니다.

공간 키는 더 많은 기능을 제공하지만 프로덕션 벤치 마크에서 플로트는 공간 키보다 훨씬 빠릅니다. (AVG에서 0,01 대 0,001)

MySQL은 모든 플로트에 더블을 사용하므로 유형을 사용하십시오. float를 사용하면 대부분의 상황에서 예측할 수없는 둥근 값으로 이어집니다.

모든 작업에 적합하지는 않지만, 맵 타일을 만들거나 하나의 투영 (예 : Google지도 및 기타 많은 슬립 맵 프레임 워크와 같은 Mercator)만으로 많은 수의 마커 (점)로 작업하는 경우, 나는 무엇을 찾았습니다. 나는 "광대 한 좌표계"를 정말로, 정말 편리하다고 부릅니다. 기본적으로 X 및 Y Pixel 좌표를 어떤 방식으로 저장 한 상태로 저장합니다. Zoom 레벨 23을 사용합니다. 여기에는 몇 가지 이점이 있습니다.

  • 요점을 처리 할 때마다 Mercator Pixel Transformation에 비싼 LAT/LNG를 수행합니다.
  • 줌 레벨이 주어진 레코드에서 타일 좌표를 얻는 데는 한 번의 올바른 변화가 필요합니다.
  • 레코드에서 픽셀 좌표를 얻는 데는 한 번의 올바른 변화가 필요합니다.
  • 교대 근무는 너무 가벼워서 SQL로 수행하는 것이 실용적이므로 픽셀 위치 당 하나의 레코드 만 반환하기 위해 별개의 작업을 수행 할 수 있습니다. 즉, 백엔드에서 반환 된 번호 레코드를 줄이면 처리가 줄어 듭니다. 프론트 엔드.

나는 최근 블로그 게시물 에서이 모든 것에 대해 이야기했습니다. http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/

나는 몇 가지 답변/의견에 매우 놀랐습니다.

왜 지구상에서 누군가가 자발적으로 정밀도를 "사전 철거"하고 나중에 더 나쁜 숫자에 대한 계산을 수행 할 의향이 있습니까? 궁극적으로 바보 같은 소리.

소스가 64 비트 정밀도를 가지고 있다면, 확실히 스케일을 자발적으로 수정하는 것은 바보 일 것입니다. 6 데시 말 및 정밀도를 최대 9 개의 중요한 파기 (일반적으로 제안되는 10 진수 9.6 형식에서 발생)로 제한하십시오.

당연히 소스 자료가 보유한 정밀도로 데이터를 저장합니다. 정밀도를 줄이는 유일한 이유는 저장 공간이 제한되어 있기 때문입니다.

  • 원래 정확도로 소스 수치를 저장하십시오
  • 정밀도의 소스에서 계산 된 저장 수치는 계산이 발생합니다 (예 : 험력 코드가 복식을 사용하는 경우 결과를 두 배로 저장하십시오)

10 진수 9.6- 형식은 스냅-로드 현상을 유발합니다. 그것이 일어날 경우 그것은 마지막 단계가되어야합니다.

나는 둥지에 누적 된 오류를 초대하지 않을 것입니다.

PostGIS의 공간 함수는 MySQL 공간 함수보다 훨씬 기능적입니다 (즉, Bbox 작업에 제한되지 않음). 확인 해봐: 링크 텍스트

tl; dr

NASA / 군사에서 일하지 않고 항공기 NAVI 시스템을 만들지 않는 경우 float (8,5)를 사용하십시오.


질문에 전적으로 답하려면 몇 가지를 고려해야합니다.

체재

  • 몇 분 초: 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ W
  • 10 분의 1도: 40 ° 26.767 ′ N 79 ° 58.933 ′ W
  • 십진도 1: 40.446 ° N 79.982 ° W
  • 십진도 2: -32.60875, 21.27812
  • 다른 집에서 만든 형식? 아무도 자신의 가정 중심 좌표 시스템을 만드는 것을 금지하고 집에서 제목 및 거리로 보관하지 않습니다. 이것은 당신이 일하는 특정 문제에 대해 의미가있을 수 있습니다.

따라서 답의 첫 번째 부분은 좌표를 다음에 저장할 수 있습니다. 응용 프로그램이 사용하는 형식 일정한 변환을 앞뒤로 피하고 더 간단한 SQL 쿼리를 만들려면.

아마도 Google지도 또는 OSM을 사용하여 데이터를 표시하며 GMAPS는 "Decimal Degrees 2"형식을 사용하고 있습니다. 따라서 동일한 형식으로 좌표를 저장하는 것이 더 쉽습니다.

정도

그런 다음 필요한 정밀도를 정의하고 싶습니다. 물론 "-32.608697550570570334,21.278081997935146"과 같은 좌표를 저장할 수 있지만, 그 시점까지 내비게이션 중에 밀리미터에 대한 약을 돌 보은 적이 있습니까? NASA에서 일하지 않고 위성이나 로켓 또는 비행기 궤적을하지 않는 경우 몇 미터 정확도로 괜찮습니다.

일반적으로 사용되는 형식은 도트 후 5 자리로 50cm 정확도를 제공합니다.

예시: x, 21.278081 사이에는 1cm 거리가 있습니다8 및 X, 21.2780819. 따라서 DOT 후 7 자리는 1/2cm 정밀도를 제공하고 DOT 후 5 자리는 1/2 미터 정밀도를 제공합니다 (별도의 지점 사이의 최소 거리는 1m이므로 반올림 오차가 절반 이상이 될 수 없기 때문입니다). 대부분의 민사 목적을 위해서는 충분해야합니다.

10 진수 분 형식 (40 ° 26.767 ′ N 79 ° 58.933 ′ W) DOT 이후 5 자리와 정확히 동일한 정밀도를 제공합니다.

공간 효율적인 저장

십진 형식을 선택한 경우 좌표는 쌍 (-32.60875, 21.27812)입니다. 분명히, 2 x (부호의 경우 1 비트, 2 자리 숫자, 지수의 경우 5 자리)로 충분합니다.

그래서 여기서 나는 지원하고 싶습니다 Alix Axel 주석에서 플로트 (10,6)에 저장하려는 Google 제안은 주요 부품을 위해 4 자리가 필요하지 않기 때문에 실제로는 추가입니다 (부호가 분리되고 위도가 90으로 제한되고 경도는 180으로 제한되어 있기 때문에). 1/2m 정밀도에 Float (8,5)를 쉽게 사용할 수 있습니다. 또는 Float (7,5)가 LAT에 충분하기 때문에 LAT와 긴 유형의 유형으로 저장할 수도 있습니다. MySQL 플로트 유형을 참조하십시오 참조. 그들 중 어느 누구도 평범한 플로트와 같으며 어쨌든 4 바이트와 같습니다.

일반적으로 공간은 요즘 문제가되지 않지만 어떤 이유로 스토리지를 최적화하려면 (면책 조항 : 사전 최적화하지 마십시오) LAT (91 000 이하 + 부호) + 긴 (없음)를 압축 할 수 있습니다. 181 000 이상의 값 + 부호) ~ 21 비트 상당히 적습니다 2xfloat보다 (8 바이트 == 64 비트)

  1. 위도의 범위는 -90에서 +90 (도)이므로 소수점 (10, 8)은 괜찮습니다.

  2. 경도의 범위는 -180에서 +180 (도)입니다. 소수점 (11, 8)이 필요합니다.

참고 : 첫 번째 숫자는 저장된 총 숫자 수이고 두 번째 숫자는 소수점 이후의 숫자입니다.

요컨대 : lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

LAT Long 계산에는 정밀도가 필요하므로 일부 유형의 소수점 유형을 사용하고 수학 계산을 수행하기 위해 저장할 숫자보다 최소 2 개를 높이십시오. 나는 내 SQL 데이터 타입에 대해 잘 모르지만 SQL Server에서는 종종 소수점 대신 float 또는 real을 사용하여 실제 숫자가 아닌 추정 숫자이기 때문에 문제가 발생합니다. 따라서 사용하는 데이터 유형이 플로팅 10 진수 유형이 아닌 진정한 소수점 유형인지 확인하십시오.

뜨다 필요한 모든 정밀도를 제공하고 각 좌표를 문자열 등으로 저장하는 것보다 비교 기능을 더 잘해야합니다.

MySQL 버전이 5.0.3보다 빠른 경우 부동 소수점 비교 오류 하지만.

MySQL 5.0.3 이전에 소수 열은 현으로 표시되기 때문에 정확한 정밀한 값을 저장하지만 소수점 값에 대한 계산은 부동 소수점 작업을 사용하여 수행됩니다. 5.0.3 기준으로 MySQL은 64 자리의 정밀도로 10 진수 작업을 수행하며, 이는 10 진수 기둥과 관련하여 가장 일반적인 부정확성 문제를 해결해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top