참고: 이 내용은 2022. 6. 6에 게시된 컨텐츠(Getting Started with GEOGRAPHY Data—Why Don’t Planes Fly in a Straight Line?)에서 번역되었습니다.

Snowflake는 지난 6월 지리 데이터 유형을 이용한 지리 공간 데이터를 공식 출시했습니다. 그리고 그 이후 지리 공간 쿼리의 수가 크게 증가하는 것을 볼 수 있었습니다. 그러나 해당 데이터가 유명해짐에 따라 Snowflake 사용자들로부터 지리 공간 데이터를 이용해 더 많은 비즈니스 인사이트를 얻어내는 방법에 대한 많은 질문을 받게 되었습니다. 이 블로그 게시물은 지리 공간 데이터를 처음 접하는 모든 사람이 기본 사항을 이해하고 Snowflake를 시작하는 데 도움이 될 것입니다. 또한 이 지리 공간 중심의 빠른 시작 가이드를 따라 발을 담그고자 하는 사람들이 미리 읽어보기에 좋은 내용으로 구성돼 있습니다.

지리학 기초(다른 말로, 왜 비행기는 직선으로 똑바르게 날지 않는 걸까?)

우리는 모두 지구에 관한 시각 자료를 본 적이 있습니다. 나이에 따라서는 교실 벽에 장식된 평평한 포스터 지도를 기억하실지도 모르지요. 역사 선생님이 책상에 지구본을 뒀을 수도 있습니다. 아니면 아주 오래전에 자동차 여행을 위해 차량에 지도책을 넣어둔 적이 있을지도 모릅니다. 오늘날 아직도 대부분의 사람이 자신이 세계의 어느 곳에 있으며 어디로 가는지와 관련된 정보를 확인하기 위해서 휴대폰을 보는 것을 익숙하게 여깁니다.

잠시 선생님의 책상에 놓여 있는 지구본에 집중해 봅시다. 어린이였던 여러분은(성인도 마찬가지입니다!) 그 지구본을 돌려 보며 구형 물체가 둥글게 돌아감에 따라 매끄러운 표면 위로 손가락을 굴려 보기도 했을 것입니다. 현재 위치를 지구본에서 찾아보고 다른 흥미로운 국가나 대륙으로 어떻게 여행할지 상상해 보기도 했겠지요. 현재 위치에서 다른 장소로 가는 경로를 따라 손가락을 움직이기도 했을 것입니다. 그랬다면 최단 경로를 따라가지 않았을 가능성이 크답니다!

위의 이미지를 살펴보세요. 예를 들어 항공사에서 베를린에서 샌프란시스코행 비행편의 경로가 아이슬란드, 그린란드, 캐나다를 거쳐서 간다는 사실을 알려주었다고 합시다. 항공사가 제정신이 아니라고 생각하시겠지요. 분명 그 둥근 모양의 경로는 베를린에서 샌프란시스코까지 직선을 그린 것보다 더 긴 경로이니까요. 이렇게 말입니다.

훨씬 짧아 보이네요! 아, 사실은 그렇지 않답니다. 이것이 바로 Snowflake의 지리학 데이터 유형을 이해해야 하는 핵심적인 이유입니다. 이는 바로 측지유클리드식 측량의 차이입니다. 간단하게 말해 측지 측량은 3D 구 모양에 기초해 곡률 위로 거리를 측량하는 반면, 유클리드식 측량은 우리 대부분이 자주 본 위의 이미지와 같은 평평한 2D 모양에 기초하고 있습니다. 그렇지만 첫 번째 이미지의 선을 구 모양의 관점에서 바라보면 비행기가 왜 그러한 경로를 따라가야 하는지를 알 수 있습니다.

Snowflake의 지리 데이터 유형은 최신 World Geodetic System, WGS 84를 사용하여 이 3D 곡률을 설명하며, 해당 시스템은 위도 및 경도를 기반으로 한 좌표 시스템을 이용해 지구를 구형 오브젝트로 표현하는 표준입니다. 지리 데이터 유형의 지원에 대해 더 자세히 살피도록 합시다(유클리드식 2D에 익숙하신 분이시라도 걱정하지 마세요. 2부에서 해당 방식을 사용하는 방법도 살펴볼 예정입니다).

지리 공간 형식, 기능 및 오브젝트 유형

지리학 데이터의 유형을 이해하기 위해서는 다음의 기본적인 세 가지 개념을 먼저 이해하는 게 도움이 됩니다.

  • 지리 공간 데이터 형식
  • 지리 공간 오브젝트 유형(‘차원’이라고도 함)
  • 지리 공간의 기능과 이를 적용하는 방법

지리 공간 데이터 형식부터 시작해 봅시다. 이러한 형식을 입력 형식(GEOGRAPHY 데이터 형식으로 데이터 로드)과 출력 형식(GEOGRAPHY 형식 열에서 쿼리 시 데이터 표시 방식)으로 생각할 수 있습니다. Snowflake는 세 가지 기본 형식을 지원합니다. (E)WKT – (확장) Well-Known Text, (E)WKB – (확장) Well-Known Binary 및 GeoJSON. 아래 테이블은 세 가지 형식과 그에 해당되는 확장된 변형 형태를 보여줍니다. 또한 다음과 같이 벨라지오 분수의 경도와 위도에 대한 쿼리 출력 표현도 표시하고 있지요(올해 라스베이거스에서 Snowflake Summit 2022가 열리기 때문입니다).

또한 위 테이블에서 언로드 작업 후 GEOGRAPHY 출력이 Snowflake나 파일에 표시되는 방식을 제어하는 세션 매개변수 ‘GEOGRAPHY_OUTPUT_FORMAT’의 사용에 유의해야 한다는 점을 유념해 주세요.

위의 Bellagio Fountains 출력 표현에서 출력은 특정 오브젝트 유형이나 지리 공간 차원 유형인 POINT를 표시해 줍니다. 여러 다양한 오브젝트 유형이 있으며, 다음 표에 나와 있는 것과 같이 그중 일부는 단일 오브젝트이고 기타 항목은 여러 가지 오브젝트의 모음입니다.

학교에서 지리 수업을 들을 때처럼 악몽 같은 기분이 드신다고 해도 조바심 내지 마세요. Snowflake에서 모든 영역과 매개 변수, 교차 계산 방법에 대한 지원을 제공합니다. 지리 공간 기능은 GEOGRAPHY 유형의 오브젝트를 작동시키는 방법을 알고 있으며, 이로 인해 계산이 쉬워집니다. 지리 공간 기능의 여러 유형과 더불어 각 유형의 예시 몇 가지를 알아보고 난 다음, 이를 SQL에서 사용하는 방법에 대한 일부 예시를 알아보겠습니다. 기능이 나열된 전체 목록이 필요하시다면 이곳에서 찾아보실 수 있습니다.

사용할 수 있는 여러 가지 유형의 함수 외에도 SELECT 구문, 쿼리 조건 및 JOIN 구문에서 이러한 기능을 사용할 수 있는 다양한 방법이 있습니다. 각 인스턴스에서 사용되는 여러 기능과 함께 각 사용법의 몇 가지 예를 살펴보겠습니다.

쿼리 예시

SELECT의 변환

이 예제는 이전에 형식 섹션에서 살펴보았으나 SELECT 구문에서 TO_GEOGRAPHY를 사용하는 경우를 다시 살펴보겠습니다. 여기서는 조금 후에 살펴볼 것과 같이 지리 정보 데이터로 적절하게 형식이 지정된 문자열(‘POINT (-115.174016 36.112650)’)을 전달하고 이를 지리 정보 함수와 함께 사용할 수 있는 참 지리 정보 데이터 유형 오브젝트로 변환합니다. TO_GEOGRAPHY 함수에서 해당 문자열을 래핑하지 않으면 Snowflake에서는 해당 문자열이 지리 공간 데이터라는 것을 인식하지 못합니다. 그리고 우리가 WKT 문자열을 단순히 반복하는 것이 아니므로, 이 예제의 목적을 위하여 이 쿼리의 출력이 실제로 GeoJSON의 지리 공간 데이터임을 표시하면 변환 지점이 보다 홈으로 이동합니다.

문자열에 대한 간단한 참고 사항을 말씀드리겠습니다. 좌표 -115.174016 36.112650은 상호작용형 지도에서 한 지점을 클릭할 때 경도와 위도 좌표를 출력해 주는 인터넷의 여러 웹사이트 중 한 곳을 이용해 찾아낸 것입니다. 나중에 확인하게 되겠지만 표에 POLYGON 모양의 Bellagio Fountains도 있습니다. 쿼리할 준비가 된 고품질 지리 공간 데이터가 필요하신 경우 Snowflake Marketplace에는 Snowflake 계정 내에서 아주 빠르게 액세스할 수 있는 많은 지리 공간 중심 목록이 마련되어 있습니다.

SELECT의 변환 및 측량

위의 첫 번째 쿼리는 테이블 쿼리도 없을 정도로 꽤 간단했습니다. 4번째 줄의 설명에서 나온 내용과 같이 우리는 분수에서 테이블의 모든 행 사이의 거리를 측정하고 거리를 오름차순으로 분류하여 벨라지오 분수 POINT에 가장 가까운 건물 테이블의 행을 찾을 것입니다. 그리고 나서 결과를 가장 가까운 첫 번째 행으로 제한합니다. 스포일러 주의: 벨라지오 호텔은 벨라지오 분수에서 가장 가까운 건물입니다!

일이 어떻게 돌아가는지에 대한 일부 참고 사항:

  • ST_MAKEPOINT는 TO_GEOGRAPHY와 같지만, 특히 POINT 구문을 위한 항목입니다. 주변에 텍스트를 추가하지 않고도 경도와 위도의 값을 순서대로 입력할 수 있다는 점에서 조금 다른 구문이지만 결과는 동일하게 나옵니다.
  • ST_DISTANCE는 다음 두 가지 오브젝트 사이의 거리를 미터로 계산합니다. 바로 위 글머리 기호에서 생성된 분수 POINT와 GEOGRAPHY 유형의 열인 건물 테이블의 모양 열입니다.
  • Snowflake의 다른 숫자와 마찬가지로, 위의 글머리 기호에서 계산된 숫자에 대해 분류를 수행할 수 있다는 점을 참조해 주세요.

WHERE 구문의 관계 비교

무언가의 측정을 계산하는 것 대신 우리는 이제 여러 오브젝트가 서로 어떻게 관계가 있는지 살펴보는 함수를 사용할 것입니다. 위 쿼리는 방금 한 것과 같이 거리 계산과 비슷하지만, 두 가지 오브젝트 사이의 가장 짧은 거리를 찾아내는 것 대신에 서로 공간을 공유하거나 교차하는 오브젝트가 있는지 확인하게 됩니다. 이는 교차 여부와 관계없이 WHERE 구문으로 평가할 수 있습니다.

일이 어떻게 돌아가는지에 대한 일부 참고 사항:

  • 이 쿼리는 이전과 동일한 건물 테이블을 이용하지만 두 번째 테이블인 all_objects를 도입합니다. 전자가 특정 관심사의 유형인 경우, 후자는 모든 관심사에 대한 폴리곤을 포함합니다. 또한 마침 벨라지오 분수에는 폴리곤이 있으며, 이는 way_id=22971030이다. 이 특정 행을 찾기 위해 조사를 멈추었습니다.
  • 그 이후로 ST_INTERSECTS에서 건물의 각 모양을 보고 all_objects에 대한 하위 쿼리를 실행하여 찾은 모양과 교차하는지 그 여부를 살펴보게 됩니다. 답이 TRUE인 경우 행이 반환됩니다. FALSE라면 행이 반환되지 않습니다. 의미하는 대로 TRUE 결과를 검색할 때 조건에 =TRUE를 지정할 필요는 없지만, 교차하지 않는 행을 반환하려면 =FALSE를 포함해야 합니다.

JOIN 구문의 관계 비교

이전 관계 쿼리에서는 특정 오브젝트의 모양을 반환하기 위해 하위 쿼리를 실행하고 해당 오브젝트를 지정된 테이블의 모든 행과 비교했습니다. 그러나 한 테이블의 여러 행을 다른 테이블의 여러 행과 비교하려면 어떻게 해야 할까요? 이 쿼리의 역할은 단순한 t1.column = t2.column 조건을 사용하지 않고 두 테이블 간의 join 조건으로 지리 공간 함수를 사용하여 수행하는 것이며 이는 두 가지 방식으로 작성할 수 있습니다.

일이 어떻게 돌아가는지에 대한 일부 참고 사항:

  • ST_DWITHIN은 두 오브젝트가 서로 특정 미터의 거리 내에 있는지 살펴봅니다. 이는 ST_DISTANCE() <= [meters]를 작성하는 것과 비슷합니다. 이러한 경우 두 가지 오브젝트는 스포츠묘지 테이블 내의 모양에 해당합니다.(이러한 두 가지 테이블이 선택된 것에 대해 너무 깊이 생각하지 마세요. 우연에 불과하니까요!).
  • 18행에서 시작하는 쿼리는 WHERE 구문에 표현된 join 조건으로 작성되며 23행에서 시작하는 쿼리는 ANSI SQL JOIN 구문을 사용하여 작성된 것입니다. 두 가지 전부 똑같이 정확하며 훌륭한 성능을 지니고 있습니다. 그렇지만 이러한 예시의 JOIN은 완전한 데카르트 곱인 CROSS JOIN이라는 생각이 드실지도 모르며, 실제로 그러한 생각이 맞습니다. 그러나 Snowflake는 이러한 특성의 지리 공간 JOIN에서 느린 CROSS JOIN을 사용하지 않아 Snowflake의 지리 공간 JOIN에서 CROSS JOIN을 지정해서는 안 됩니다. 대신 당사는 이러한 유형의 쿼리에 더 최적화된 JOIN 기술을 보유하고 있습니다.

이 블로그 게시물에서 보셨던 예제 쿼리는 어떤 일을 할 수 있는지를 맛보신 것에 불과합니다. 빠른 시작 가이드에서는 여기서 다룬 내용보다 더 많은 지리 공간 함수를 사용하는 방법을 잘 배울 수 있지만, 이 게시물을 읽으며 괜찮은 기초를 쌓으셨기를 바랍니다.

2부를 놓치지 마세요

요약하면, Snowflake는 지리 공간 GEOGRAPHY 데이터 유형 함수 기능을 도입했습니다. 이 기능으로 사용자는 공통 지리 공간 형식을 사용하여 데이터를 나타낼 수 있으며 해당 데이터를 쿼리하기 위해 특수 함수를 사용할 수 있습니다. GEOGRAPHY에서는 지구를 구처럼 취급하며 2차원의 직선 대신 곡선을 따라 측지 호를 사용하여 측량값을 계산하는 WGS84 표준을 이용합니다. 2부에서는 Snowflake가 이 기능을 확장 이용해 더 많은 유형의 지리 공간 데이터에 대한 쿼리를 받는 방법을 살펴보겠습니다.