위도 및 경도 데이터를 SQL 데이터베이스에 저장할 때 어떤 데이터 유형을 사용해야합니까? [복제]
이 질문에는 이미 답변이 있습니다.
위도 또는 경도 데이터를 ANSI SQL 호환 데이터베이스에 저장할 때 가장 적합한 데이터 유형은 무엇입니까? float
또는 decimal
, 또는 ...을 사용해야합니까 ?
Oracle, MySql 및 SQL Server는 지리 데이터 처리를 위해 특별히 특수한 데이터 유형을 추가했지만 정보를 "일반 바닐라"SQL 데이터베이스에 저장하는 방법에 관심이 있습니다.
Decimal(9,6)
매개 변수를 정밀하게 조정하고 스케일링하는 데 익숙하지 않은 경우 다음과 같은 형식 문자열이 표시됩니다.
###.######
우리는 float를 사용하지만 소수점 6 자리의 숫자 맛도 작동합니다.
글쎄, 위도 / 경도를 저장하는 방법을 물었고 내 대답은 다음과 같습니다.하지 마십시오. WGS 84 (유럽 ETRS 89 )를 Geo 참조의 표준으로 사용하는 것을 고려할 수 있습니다 .
그러나 그 세부 사항 외에도 SQL 2008이 지리적 지원을 포함하기 전 며칠 동안 사용자 정의 유형을 사용했습니다.
바닐라 오라클에서 LOCATOR (공간이 주름 져있는 버전)라는 기능은 NUMBER (정밀도 아님) 데이터 유형을 사용하여 좌표 데이터를 저장해야합니다. 공간 쿼리를 지원하기 위해 함수 기반 인덱스를 만들려고 시도하면 그렇지 않습니다.
위도 / 경도 십진수를 정수 및 소수 부분으로 나누고 다음 변환 알고리즘을 사용하여 여기에 다소 제안 된대로 별도로 저장하는 대신 부호없는 정수 필드에 쉽게 저장할 수 있습니다.
저장된 mysql 함수로 :
CREATE DEFINER=`r`@`l` FUNCTION `PositionSmallToFloat`(s INT)
RETURNS decimal(10,7)
DETERMINISTIC
RETURN if( ((s > 0) && (s >> 31)) , (-(0x7FFFFFFF -
(s & 0x7FFFFFFF))) / 600000, s / 600000)
그리고 다시
CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7))
RETURNS int(10)
DETERMINISTIC
RETURN s * 600000
서명되지 않은 int (10)에 저장해야합니다 . 이것은 유형이없는 sqlite뿐만 아니라 mysql에서도 작동합니다.
경험을 통해 좌표를 저장하고 수학을 수행하기 위해 좌표를 검색하는 것만으로도 이것이 빠르게 작동한다는 것을 알았습니다.
PHP에서 그 두 함수는 다음과 같습니다
function LatitudeSmallToFloat($LatitudeSmall){
if(($LatitudeSmall>0)&&($LatitudeSmall>>31))
$LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1;
return (float)$LatitudeSmall/(float)600000;
}
그리고 다시 :
function LatitudeFloatToSmall($LatitudeFloat){
$Latitude=round((float)$LatitudeFloat*(float)600000);
if($Latitude<0) $Latitude+=0xFFFFFFFF;
return $Latitude;
}
이것은 예를 들어 정수를 가진 memcached 고유 키를 생성하는 측면에서 이점이 있습니다. (예 : 지오 코드 결과를 캐시하기 위해). 이것이 토론에 가치를 더해주기를 바랍니다.
다른 응용 프로그램은 GIS 확장이없고 단순히 수백만 개의 위도 / 경도 쌍을 유지하려는 경우 mysql의 해당 필드에서 파티션을 사용하여 정수라는 사실의 이점을 얻을 수 있습니다.
Create Table: CREATE TABLE `Locations` (
`lat` int(10) unsigned NOT NULL,
`lon` int(10) unsigned NOT NULL,
`location` text,
PRIMARY KEY (`lat`,`lon`) USING BTREE,
KEY `index_location` (`locationText`(30))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY ()
PARTITIONS 100 */
귀하의 데이터에 적절한 정밀도로 10 진수를 사용합니다.
가장 자주 수행해야 할 작업에 달려 있다고 생각합니다.
10 진수로 전체 값이 필요한 경우 적절한 정밀도와 스케일로 10 진수를 사용하십시오. 플로트는 당신의 요구를 넘어선 방법이라고 생각합니다.
자주 degºmin'sec "분수 표기법으로 변환하거나 변환하는 경우 각 값을 정수 유형 (smallint, tinyint, tinyint, smallint?)으로 저장하는 것이 좋습니다.
SQL Server 2008에 도입 된 새로운 Spatial 데이터 형식을 살펴보십시오. 이러한 유형의 작업을 특별히 설계하여 데이터를보다 쉽고 효율적으로 인덱싱하고 쿼리 할 수 있습니다.
http://msdn.microsoft.com/en-us/library/bb933876(v=sql.105).aspx
http://blogs.technet.com/andrew/archive/2007/11/26/sql-server-2008-spatial-data-types.aspx
'Programing' 카테고리의 다른 글
반환 값과 Promise.resolve의 차이점은 then ()에서 (0) | 2020.03.19 |
---|---|
Windows의 Node.js에서 hello.js 파일을 실행하는 방법은 무엇입니까? (0) | 2020.03.19 |
html 요소에 여러 개의 ID가있을 수 있습니까? (0) | 2020.03.19 |
Haskell / GHC의`forall` 키워드는 무엇을합니까? (0) | 2020.03.19 |
인수가없는 Python Argparse 명령 행 플래그 (0) | 2020.03.19 |