공간 데이터
공간 데이터는 포인트(Point), 선(Line), 폴리곤(Polygon) 과 같은 엔티티의 표현을 포함한다.
이러한 데이터 타입은 JDBC 사양의 일부가 아니므로 JTS (JTS Topology Suite) 가 공간 데이터 타입을 나타내는 표준이 되었다.
JTS 외에도 하이버네이트 스페이셜은 최근의 라이브러리인 Geolatte-geom 을 지원하며, JTS에서 사용할 수 없는 몇 가지 기능을 제공한다.
두 라이브러리는 모두 하이버네이트-스페이셜 프로젝트에 이미 포함되어 있다. 어느 라이브러리를 사용할지는 단순히 데이터 타입을 어느 jar 파일에서 가져오는가의 문제이다.
JTS( JTS Topology Suite)
JTS 토폴로지 스위트는 벡터 지형을 생성하고 조작하기 위한 Java 라이브러리이다. 또한, 포괄적인 지형 테스트 케이스 세트와 지형 및 JTS 기능을 작업하고 시각화하기 위한 TestBuilder GUI 애플리케이션을 제공한다.
현재 JTS는 Java 1.8 이상을 대상으로 한다.
- 지형 객체: JTS는 포인트, 선, 폴리곤 및 이 객체들의 컬렉션을 포함한 다양한 지형 모양을 지원한다.
- 정밀도 처리: 공간 계산에서 흔히 발생하는 정밀도 및 반올림 문제를 처리하기 위한 견고한 알고리즘을 제공한다.
- 공간 연산: 유니온(union), 교차(intersection), 차이(difference), 버퍼(buffer) 등 다양한 연산을 포함한다.
- 공간 분석: 지형 간의 포함(containment), 교차(intersection), 거리(distance)와 같은 공간 관계를 계산하는 기능을 제공한다.
- 데이터 구조: Quadtrees 및 STRtrees와 같은 공간 데이터를 저장하고 관리하기 위한 효율적인 데이터 구조를 제공한다.
- 좌표 시스템: 다양한 좌표 참조 시스템(CRS)을 지원하고 그들 간의 변환을 제공한다.
- 지형 알고리즘: 지형 처리에 대한 견고하고 효율적인 알고리즘을 제공하며, 여기에는 Douglas-Peucker 간소화, Delaunay 삼각측량, Voronoi 다이어그램 등이 포함된다.
Geolatte-geom
Geolatte-geom은 Open Geospatial Consortium (OGC) 표준을 준수하는 방식으로 지형 데이터를 처리하기 위해 설계된 Java 라이브러리이다. 이는 지리 정보 시스템(GIS), 공간 데이터베이스 및 다양한 공간 데이터 조작을 요구하는 애플리케이션에서 일반적으로 사용된다. 다음은 그 기능, 적용 사례 및 사용법에 대한 개요이다.
- 지형 프리미티브: 포인트, 선, 폴리곤 및 멀티 지형과 같은 표준 지형 객체를 지원한다.
- 지형 연산: 교차(intersection), 유니온(union), 차이(difference), 버퍼(buffer)와 같은 연산을 포함한다.
- 공간 관계: 겹침(overlap), 포함(containment), 근접성(proximity)과 같은 공간 관계를 결정하는 기능을 제공한다.
- 정밀도 처리: 공간 계산에서 흔히 발생하는 정밀도 문제를 관리한다.
- 직렬화: 지형 직렬화 및 역직렬화를 위한 well-known text (WKT), well-known binary (WKB), GeoJSON 형식을 지원한다.
- 좌표 참조 시스템(CRS): 다양한 CRS를 처리하고 그들 간의 변환을 제공한다.
- 검증: OGC 표준에 대해 지형 객체를 검증하는 도구를 제공한다.
MySQL 공간 데이터 유형
지형 유형
- Point:
- 좌표 시스템(위도 및 경도)에서 단일 위치를 나타낸다.
- LineString:
- 직선 구간으로 연결된 점들의 연속을 나타낸다.
- Polygon:
- 닫힌 점들의 연속으로 정의된 경계로 형성된 모양을 나타낸다.
- MultiPoint:
- 여러 점들의 집합을 나타낸다.
- MultiLineString:
- 여러 LineString의 집합을 나타낸다.
- MultiPolygon:
- 여러 Polygon의 집합을 나타낸다.
- GeometryCollection:
- 서로 다른 지형 유형(Point, LineString, Polygon 등)의 집합을 나타낸다.
MySQL에서는 공간 데이터 유형이 테이블 열에 지형 및 지리 값을 저장한다. 단일 지형 및 다중 지형 유형 모두를 지원한다. 단일 지형 값에는 GEOMETRY, POINT, LINESTRING, POLYGON이 포함된다. 동일한 유형의 여러 객체를 나타내는 다중 지형 유형에는 MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION**이 포함된다.
유형 설명 예시
GEOMETRY | 모든 유형의 지형 값을 저장한다. 이는 인스턴스화할 수 없는 클래스이지만 모든 지형 값에 공통된 여러 속성을 가진다. | 문서 링크 |
POINT | MySQL 단일 X 및 Y 좌표 값을 저장한다. | POINT(-74.044514 40.689244) |
LINESTRING | 곡선을 형성하는 점 집합을 저장한다. 가장자리로 연결된 점의 순서 있는 목록이다. | LINESTRING(0 0, 0 1, 1 1) |
POLYGON | 다변형 지형에서 점 집합을 저장한다. linestring과 유사하지만 닫혀 있으며(최소 세 개의 고유한 점이 있어야 하며 첫 번째와 마지막 점 쌍이 동일해야 한다) | POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)). 각 링은 점 집합으로 나타낸다. |
MULTIPOINT | 여러 점 값을 저장한다. | MULTIPOINT(0 0, 20 20, 60 60) |
MULTILINESTRING | 여러 LINESTRING 값을 저장한다. | MULTILINESTRING((10 10, 20 20), (15 15, 30 15)) |
MULTIPOLYGON | 여러 POLYGON 값을 저장한다. | MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5))) |
GEOMETRYCOLLECTION | 여러 GEOMETRY 값을 저장한다. MySQL은 단일 GeometryCollection 객체 자체를 제외하고 빈 GeometryCollection을 지원하지 않는다. | GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20)) |
SRID(공간 참조 시스템 식별자)
공간 참조 식별자(SRID)는 특정 좌표 시스템, 허용 오차 및 해상도와 연관된 고유 식별자이다.
SRID는 공간 데이터에 대한 좌표 시스템 및 투영 정보를 정의한다. 다음은 일반적으로 사용되는 SRID이다:
- 4326 (WGS 84):
- GPS 및 많은 글로벌 매핑 애플리케이션에서 사용되는 표준 좌표 시스템이다. 위도 및 경도 좌표를 사용한다.
- 3857 (Web Mercator):
- Google Maps와 같은 웹 매핑 애플리케이션에서 일반적으로 사용된다. 미터를 단위로 사용하며 웹 매핑에 적합한 투영을 제공한다.
- 326xx (UTM):
- Universal Transverse Mercator (UTM)는 세계를 여러 구역으로 나누고, 각 구역은 고유한 SRID를 가진다. 예를 들어, 32633은 UTM 구역 33N에 해당한다.
- 27700 (OSGB 1936 / British National Grid):
- OSGB 1936 기준으로 한 영국에서 사용되는 좌표 시스템이다.
- 25832 (ETRS89 / UTM zone 32N):
- ETRS89 기준으로 한 UTM 좌표 시스템으로, 유럽에서 일반적으로 사용된다.
지형 유형과 SRID 결합
공간 데이터를 위한 열을 정의할 때 지형 유형과 SRID를 결합하여 데이터가 저장되고 해석되는 방식을 지정한다. 다음은 몇 가지 예이다:
- WGS 84를 사용하는 Point:
- javaCopy code @Type(type = "org.hibernate.spatial.GeometryType") @Column(columnDefinition = "geometry(Point, 4326)") private Point location;
- Web Mercator를 사용하는 LineString:
- javaCopy code @Type(type = "org.hibernate.spatial.GeometryType") @Column(columnDefinition = "geometry(LineString, 3857)") private LineString path;
- UTM 구역 33N을 사용하는 Polygon:
- javaCopy code @Type(type = "org.hibernate.spatial.GeometryType") @Column(columnDefinition = "geometry(Polygon, 32633)") private Polygon area;
- British National Grid를 사용하는 MultiPoint:
- javaCopy code @Type(type = "org.hibernate.spatial.GeometryType") @Column(columnDefinition = "geometry(MultiPoint, 27700)") private MultiPoint points;
- ETRS89 / UTM 구역 32N을 사용하는 GeometryCollection:
- javaCopy code @Type(type = "org.hibernate.spatial.GeometryType") @Column(columnDefinition = "geometry(GeometryCollection, 25832)") private GeometryCollection geometries;
일반적으로 인덱싱은 R-트리 또는 R+-트리를 사용하지만, 공간 인덱스에는 R-트리가 사용된다.
왜 B+ 트리와 B-트리가 인덱싱에 사용되는가
B+ 트리
B+ 트리는 여러 가지 중요한 장점으로 인해 데이터베이스 인덱싱 및 파일 시스템에서 널리 사용된다:
- 효율적인 디스크 액세스:
- B+ 트리는 디스크 I/O 작업을 최소화하도록 설계되었다. 내부 노드는 실제 데이터를 저장하지 않고 키만 저장하므로 한 디스크 페이지에 더 많은 키를 담을 수 있다. 이는 검색 시 디스크 액세스 횟수를 줄여준다.
- 범위 쿼리:
- B+ 트리는 범위 쿼리에 특히 효율적이다. 리프 노드들이 연결 리스트로 연결되어 있어, 트리 상단으로 다시 올라가지 않고도 키의 범위를 순차적으로 액세스할 수 있다.
- 균형 잡힌 구조:
- B+ 트리는 모든 리프 노드가 동일한 깊이에 있는 균형 잡힌 구조를 가진다. 이는 검색, 삽입, 삭제 작업의 시간 복잡도가 O(log n)임을 보장하여 일관되고 예측 가능한 성능을 제공한다.
- 순차적 접근:
- 리프 노드의 연결 리스트는 순차적 접근을 효율적으로 할 수 있게 해준다. 이는 데이터베이스 테이블 스캔과 같이 데이터의 큰 부분을 스캔해야 하는 작업에 유리하다.
B-트리
B-트리도 유사한 이유로 인덱싱에 사용되며, 몇 가지 차별화된 특징이 있다:
- 효율적인 디스크 활용:
- B+ 트리처럼 B-트리도 디스크 액세스를 최적화하도록 설계되었다. 각 노드에 여러 키와 포인터를 저장함으로써 트리를 순회할 때 필요한 I/O 작업의 수를 줄인다.
- 균형 잡힌 트리 구조:
- B-트리는 균형 잡힌 구조를 유지하여 루트에서 리프까지의 모든 경로가 동일한 길이임을 보장한다. 이는 검색, 삽입, 삭제 작업에 대해 O(log n) 성능을 보장한다.
- 동적 업데이트:
- B-트리는 전체 트리의 재구성이 필요 없이 삽입 및 삭제와 같은 동적 업데이트를 효율적으로 처리한다. 이는 데이터가 자주 업데이트되는 환경에 적합하다.
- 일반적인 사용 사례:
- B+ 트리와 달리 B-트리는 내부 노드와 리프 노드 모두에 키와 데이터를 저장한다. 이는 내부 노드에서 키와 연관된 데이터에 빠르게 접근해야 하는 일부 응용 프로그램에 유리할 수 있다.
왜 R-트리가 공간 인덱싱에 효율적인가
R-트리는 지리 정보 시스템(GIS), 컴퓨터 지원 설계(CAD), 공간 데이터베이스 등과 같은 다차원 공간 데이터를 인덱싱하기 위해 설계된 트리 데이터 구조이다. R-트리가 공간 인덱싱에 효율적인 이유는 다음과 같다:
- MBR(최소 경계 사각형)의 사용:
- R-트리의 각 노드는 그 노드 내의 모든 공간 객체를 포함하는 MBR을 가지고 있다.
- MBR은 공간 객체가 겹치는지를 빠르게 결정할 수 있게 하여 검색 성능을 향상시킨다.
- 계층적 구조:
- R-트리의 계층적 구조는 루트에서 리프 노드까지 내려가면서 검색 영역을 좁힐 수 있게 한다.
- 이는 관련 없는 객체를 검사할 필요를 줄여 쿼리 성능을 최적화한다.
- 동적 삽입 및 삭제:
- R-트리는 데이터 세트가 변경될 때 효율성을 유지하면서 공간 객체의 동적 삽입 및 삭제를 지원한다.
- 삽입 시 적절한 리프 노드를 찾아 객체의 MBR을 삽입하며, 노드가 꽉 차면 노드를 분할하여 트리 구조를 조정한다.
- 삭제 시 트리를 재구조화하여 균형과 효율성을 유지할 수 있다.
- 효율적인 공간 분할:
- R-트리는 각 MBR의 면적을 최소화하여 공간을 효율적으로 분할하며, 이는 겹침을 줄이고 쿼리 성능을 향상시킨다.
- 이러한 공간 분할은 공간 객체의 밀도를 고려하여 트리 높이를 최소화하고 검색 효율성을 최적화한다.
R-트리
R-트리는 디스크 기반 인덱스 구조로, 다차원 공간에서 B-트리(단일 차원)의 자연스러운 확장이다. 이는 Oracle, SQL Server 등 현재의 데이터베이스 시스템에 통합하기 편리하며, 다양한 공간 쿼리 작업을 지원한다. 실제로 널리 사용되고 있으며, 가장 인기 있는 공간 인덱스 중 하나이다.
R-트리 공간 인덱스는 지형 객체를 포함하는 여러 사각형을 정의한다. 즉, 사각형은 가까운 공간 위치를 가진 몇몇 객체를 포함한다. 따라서 사각형은 지형 객체의 포인터를 포함하는 공간 인덱스로 간주된다. 예를 들어, A라는 사각형은 D, E, F와 같은 지형 객체를 포함한다. B라는 사각형은 H, I, J, K와 같은 지형 객체를 포함한다. C라는 사각형은 M, L과 같은 지형 객체를 포함한다. 아래 그림은 R-트리 공간 인덱스의 예시이다.
R-트리의 작동 방식
- 계층적 구조: R-트리는 리프 노드가 실제 공간 객체를 포함하고 비리프 노드는 자식 노드를 둘러싸는 경계 상자를 포함하는 계층적 구조를 사용한다.
- 경계 상자: R-트리의 각 노드는 자식 노드의 모든 사각형을 포함하는 최소 경계 사각형(MBR)을 가진다. 이 계층적 경계는 검색 시 관련 없는 객체를 빠르게 제거할 수 있게 해준다.
최소 경계 사각형 (MBR)
최소 경계 사각형(MBR)은 R-트리의 중요한 구성 요소이다. MBR은 공간 객체나 공간 객체 집합을 완전히 둘러싸는 가장 작은 사각형이다. MBR은 R-트리의 모든 레벨에서 사용된다:
- 리프 노드: 각 리프 노드는 단일 공간 객체의 MBR을 포함한다.
- 비리프 노드: 각 비리프 노드는 자식 노드의 모든 MBR을 둘러싸는 MBR을 포함한다.
MBR은 쿼리 효율성을 높이기 위해 R-트리가 쿼리 영역과 교차하지 않는 트리의 큰 부분을 신속하게 무시할 수 있게 해준다. 쿼리가 수행될 때, R-트리 알고리즘은 개별 객체가 아닌 MBR만 검사하여 잠재적인 일치를 찾는다.
동적 삽입 및 삭제
- 삽입: 새로운 공간 객체를 추가할 때 객체의 MBR을 삽입할 적절한 리프 노드를 결정한다. 트리 구조는 효율성을 유지하기 위해 조정되며, 때로는 MBR이 너무 커지면 노드가 분할될 수 있다.
- 삭제: 객체를 삭제할 때 리프 노드에서 해당 MBR을 찾아 제거한다. 트리 구조는 균형과 효율성을 유지하기 위해 조정될 수 있으며, 필요한 경우 노드를 병합할 수 있다.
주요 작업
- 검색: 쿼리 영역과 교차하는 모든 객체를 찾기 위해 트리를 순회하며 MBR을 검사한다.
- 삽입: 새로운 공간 객체를 추가하고, 트리 구조를 조정하여 효율성을 유지한다.
- 삭제: 객체를 제거하고, 필요한 경우 트리 구조를 조정한다.
'Job Interview Prep' 카테고리의 다른 글
네트워크란? (0) | 2024.10.28 |
---|---|
SQL이란 무엇인가 (0) | 2024.08.01 |
ktlint 자동적용 안 되는 경우 해결법 (0) | 2024.06.02 |
String과 StringBuilder, StringBuffer의 차이 (0) | 2024.05.31 |
제네릭(Generic)이란 (0) | 2024.05.31 |