polygon (POLYGON) 딕셔너리는 포인트-인-폴리곤 쿼리, 즉 본질적으로 "리버스 지오코딩" lookup에 최적화되어 있습니다.
좌표(위도/경도)가 주어지면, 해당 점을 포함하는 폴리곤/지역(국가 또는 지역 경계처럼 여러 폴리곤 집합 중 하나)을 효율적으로 찾습니다.
위치 좌표를 해당 좌표가 속한 지역에 매핑하는 데 적합합니다.
폴리곤 딕셔너리를 구성하는 예시는 다음과 같습니다.
CREATE DICTIONARY polygon_dict_name (
key Array(Array(Array(Array(Float64)))),
name String,
value UInt64
)
PRIMARY KEY key
LAYOUT(POLYGON(STORE_POLYGON_KEY_COLUMN 1))
...<dictionary>
<structure>
<key>
<attribute>
<name>key</name>
<type>Array(Array(Array(Array(Float64))))</type>
</attribute>
</key>
<attribute>
<name>name</name>
<type>String</type>
<null_value></null_value>
</attribute>
<attribute>
<name>value</name>
<type>UInt64</type>
<null_value>0</null_value>
</attribute>
</structure>
<layout>
<polygon>
<store_polygon_key_column>1</store_polygon_key_column>
</polygon>
</layout>
...
</dictionary>폴리곤 딕셔너리를 구성할 때 키는 다음 두 가지 타입 중 하나여야 합니다.
- 단순 폴리곤입니다. 점의 배열입니다.
- MultiPolygon입니다. 폴리곤의 배열입니다. 각 폴리곤은 점의 2차원 배열이며, 이 배열의 첫 번째 요소는 폴리곤의 외곽 경계이고 그 뒤 요소들은 내부에서 제외할 영역을 지정합니다.
점은 좌표 배열 또는 튜플로 지정할 수 있습니다. 현재 구현에서는 2차원 점만 지원됩니다.
사용자는 ClickHouse가 지원하는 모든 포맷으로 자체 데이터를 업로드할 수 있습니다.
사용 가능한 인메모리 저장소 타입은 3가지입니다.
| Layout | Description |
|---|---|
POLYGON_SIMPLE |
단순한 구현입니다. 각 쿼리마다 모든 폴리곤을 선형으로 순회하면서, 추가 인덱스 없이 포함 여부를 확인합니다. |
POLYGON_INDEX_EACH |
각 폴리곤에 대해 별도의 인덱스를 생성하므로 대부분의 경우 포함 여부를 빠르게 확인할 수 있습니다(지리적 영역에 최적화됨). 영역 위에 격자를 씌우고 셀을 재귀적으로 16개의 동일한 부분으로 나눕니다. 재귀 깊이가 MAX_DEPTH에 도달하거나 셀이 MIN_INTERSECTIONS개 이하의 폴리곤과만 교차하면 분할을 중지합니다. |
POLYGON_INDEX_CELL |
위에서 설명한 것과 동일한 옵션으로 격자를 생성합니다. 각 리프 셀에 대해 그 안에 속하는 모든 폴리곤 조각에 대한 인덱스를 생성하여 빠른 쿼리 응답을 가능하게 합니다. |
POLYGON |
POLYGON_INDEX_CELL의 동의어입니다. |
딕셔너리 쿼리는 딕셔너리를 다루는 표준 함수를 사용해 수행합니다. 중요한 차이점은 여기서 키가 폴리곤에 포함되는지 확인하려는 점이라는 것입니다.
예시
위에서 정의한 딕셔너리를 사용하는 예시는 다음과 같습니다.
CREATE TABLE points (
x Float64,
y Float64
)
...
SELECT tuple(x, y) AS key, dictGet(dict_name, 'name', key), dictGet(dict_name, 'value', key) FROM points ORDER BY x, y;'points' 테이블의 각 지점에 대해 마지막 명령을 실행하면, 해당 지점을 포함하는 최소 면적의 폴리곤을 찾아 요청된 속성을 출력합니다.
예시
SELECT 쿼리를 통해 폴리곤 딕셔너리의 컬럼을 읽을 수 있습니다. 딕셔너리 구성 또는 해당 DDL 쿼리에서 store_polygon_key_column = 1을 활성화하기만 하면 됩니다.
CREATE TABLE polygons_test_table
(
key Array(Array(Array(Tuple(Float64, Float64)))),
name String
) ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO polygons_test_table VALUES ([[[(3, 1), (0, 1), (0, -1), (3, -1)]]], 'Value');
CREATE DICTIONARY polygons_test_dictionary
(
key Array(Array(Array(Tuple(Float64, Float64)))),
name String
)
PRIMARY KEY key
SOURCE(CLICKHOUSE(TABLE 'polygons_test_table'))
LAYOUT(POLYGON(STORE_POLYGON_KEY_COLUMN 1))
LIFETIME(0);
SELECT * FROM polygons_test_dictionary;┌─key─────────────────────────────┬─name──┐
│ [[[(3,1),(0,1),(0,-1),(3,-1)]]] │ Value │
└─────────────────────────────────┴───────┘