sayu.day
Database

PostGIS와 GeoJSON을 활용한 공간 데이터 관리

PostGIS에서 GeoJSON을 저장하고 조회할 때 필요한 함수와 성능 기준을 정리합니다.

발행 2025년 12월 30일2267

같은 주제에서 이어 읽기

PostgreSQL 인덱스 Deep Dive: B-Tree부터 GiST까지

Database 안에서 이어지는 글

1) 기본 스키마

CREATE EXTENSION IF NOT EXISTS postgis;

CREATE TABLE regions (
  id BIGSERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  geom GEOMETRY(MultiPolygon, 4326) NOT NULL
);

CREATE INDEX idx_regions_geom_gist ON regions USING GIST (geom);

핵심 원칙:

  • GeoJSON 표준 호환을 위해 보통 SRID 4326을 기본으로 둡니다.
  • 공간 조회 성능은 거의 항상 GIST 인덱스 유무로 갈립니다.

2) GeoJSON 입력

INSERT INTO regions (name, geom)
VALUES (
  'seoul-sample',
  ST_SetSRID(
    ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[126.9,37.5],[127.1,37.5],[127.1,37.6],[126.9,37.6],[126.9,37.5]]]}'),
    4326
  )
);

배치 입력에서는 jsonb_array_elements를 써서 한 번에 넣는 편이 효율적입니다.

3) GeoJSON 출력

SELECT
  id,
  name,
  ST_AsGeoJSON(geom, 6)::json AS geometry
FROM regions;

6자리 정밀도는 대부분의 웹 지도에서 충분합니다. 불필요한 자릿수를 줄이면 응답 크기가 줄어듭니다.

4) 자주 쓰는 공간 쿼리

점 포함 여부

SELECT name
FROM regions
WHERE ST_Contains(geom, ST_SetSRID(ST_Point(127.0, 37.55), 4326));

반경 검색(거리 계산)

SELECT
  name,
  ST_Distance(geom::geography, ST_SetSRID(ST_Point(127.0, 37.55), 4326)::geography) AS distance_m
FROM regions
WHERE ST_DWithin(
  geom::geography,
  ST_SetSRID(ST_Point(127.0, 37.55), 4326)::geography,
  10000
)
ORDER BY distance_m;

거리 기반 기능은 geometry보다 geography 캐스팅이 실수를 줄입니다.

5) 유효성 검증

SELECT id, ST_IsValid(geom), ST_IsValidReason(geom)
FROM regions
WHERE NOT ST_IsValid(geom);

문제가 있으면 ST_MakeValid로 교정하되, 원본 보존 컬럼을 두는 것이 안전합니다.

6) 성능 체크리스트

  • EXPLAIN (ANALYZE, BUFFERS)로 인덱스 사용 여부 확인.
  • 같은 좌표계를 강제해 런타임 변환 비용 축소.
  • 대형 폴리곤은 저장 전 단순화(ST_SimplifyPreserveTopology) 검토.
  • API 응답은 꼭 필요한 속성만 반환.

요약

PostGIS + GeoJSON 운영의 핵심은 세 가지입니다.

  • SRID 일관성
  • GIST 인덱스
  • 입력 유효성 검증

이 세 가지를 먼저 고정하면 공간 기능의 성능과 안정성이 크게 올라갑니다.

다음 읽기

이 생각이 이어지는 방향

Database 더 보기
공유

읽은 뒤의 대화

읽은 뒤의 생각을 이어갑니다

질문, 반론, 조용한 후속 메모를 이 글 아래에 남길 수 있습니다.

sayu.day는 생각과 작업의 흔적을 천천히 정리하는 개인 출판물입니다.
직접 겪고 검토한 내용, 다시 읽을 만한 아이디어, 작업하며 남긴 메모를 모읍니다.
시간이 지난 글은 현재의 판단과 다를 수 있어 업데이트 맥락을 함께 남깁니다.

© 2026 sayu.day