“교동의 약국을 찾아줘.”

사람에게는 자연스러운 문장이다.

하지만 시스템이 교동을 단순 문자열로 검색하면 문제가 시작된다.

WHERE address LIKE '%교동%'

이 검색은 “교동이라는 지역”을 찾는 것이 아니라 “교동이라는 글자가 들어간 문자열”을 찾는다.

둘은 완전히 다르다.

1. 같은 지역명이 여러 곳에 있을 수 있다

“동명동”은 광주광역시에도, 속초시에도, 목포시에도 있습니다. 셋 다 법정동입니다.

법정동 이름은 전국에서 중복될 수 있다.

사용자가 교동이라고 말했을 때 시스템이 먼저 해야 할 일은 검색이 아니다.

어느 교동인가?

를 해결해야 한다.

2. substring은 false positive를 만든다

%교동%에는 다음이 같이 잡힐 수 있다.

  • 법정동명이 교동
  • 도로명에 교동 포함
  • 건물명에 교동 포함
  • 옛 주소 문자열
  • 다른 지역의 문자열 조각

검색 대상 필드를 바꾸면 결과 수까지 달라질 수 있다.

3. 지역명은 String이 아니라 Entity

더 안전한 처리 흐름은 다음이다.

"교동"
↓
region resolver
↓
후보 목록
↓
ambiguous?
  yes → 사용자 확인
  no  → canonical region id
↓
공간 검색

핵심은 resolve first, search second다.

Ambiguity는 실패가 아니다

동일한 지역명이 여러 개 나온다고 해서 시스템 오류는 아니다. 오히려 현실의 지리 데이터가 가진 정상적인 특성이다.

이 경우 좋은 UX는 임의로 첫 번째 지역을 선택하는 것이 아니라 사용자에게 다시 묻는 것이다.

"동일한 이름의 지역이 여러 곳 있습니다. 어느 지역을 의미하나요?"

이 동작은 실패가 아니라 의미 보존을 위한 정상적인 handoff다.

Canonical identifier를 써야 하는 이유

지역명을 resolve한 뒤에는 문자열 대신 다음과 같은 식별자를 사용한다.

region_id
legal_code
admin_code
geometry_id

문자열은 표현이고 식별자는 의미다. 검색과 공간 연산은 식별자를 기준으로 수행하는 편이 안전하다.

Fallback도 의미를 보존해야 한다

상위 계층이 ambiguity를 감지했는데 fallback이 단순 substring 검색으로 내려가면 겉으로는 결과가 나온다. 하지만 의미는 이미 깨졌다.

Availability ↑
Semantic correctness ↓

Fallback은 단순히 “무언가 결과를 반환하는 것”이 아니라 원래 의미를 최대한 보존하는 것이어야 한다.

지역명을 다룰 때의 기본 규칙

1. 문자열에서 지역 후보 추출
2. region resolver 실행
3. 중복성 판단
4. canonical region id 확정
5. 그 다음 데이터 검색

이 순서를 지키면 substring 기반의 false positive를 크게 줄일 수 있다.

내 데이터에 이 문제가 있는지 점검하는 절차

전국 동명 중복이 총 몇 건인지는 공식 통계로 공개돼 있지 않습니다. 대신 내가 다루는 데이터에서 직접 세면 됩니다.

  1. 공공데이터포털의 전국 법정동 목록을 받는다
  2. 읍면동 이름만 뽑아 같은 이름이 몇 개 시군구에 나타나는지 센다
  3. 그 목록을 서비스의 검색 로그와 대조해, 사용자가 실제로 치는 이름 중 중복인 것을 고른다
SELECT dong_name, COUNT(DISTINCT sgg_code) AS places
FROM legal_dong
GROUP BY dong_name
HAVING COUNT(DISTINCT sgg_code) > 1
ORDER BY places DESC;

판정 기준은 이렇습니다.

  • places가 2 이상인 이름이 하나라도 검색 로그에 있으면 substring 검색은 이미 틀린 결과를 내고 있습니다
  • 상위 몇 개가 사용자가 자주 치는 이름이라면 그것부터 resolver에 태웁니다
  • 한 건도 없다면 이 글의 문제는 당신 데이터에 없습니다. 다음 단계로 넘어가세요

resolve first가 통하지 않는 경우

지역명을 먼저 해석하고 나서 검색하는 순서가 항상 나은 것은 아닙니다.

  • 사전이 최신이 아니면 resolver의 “못 찾음”이 substring보다 나쁩니다. 행정구역은 통합·분동으로 바뀌고, 사전이 뒤처지면 실재하는 지역을 없다고 답합니다
  • 되묻기는 대화형 UI에서만 됩니다. 배치 처리나 API 호출에는 물을 상대가 없습니다. 그때는 후보를 전부 돌려주고 호출자가 고르게 하는 계약이 필요합니다
  • canonical id도 시점을 답니다. 행정구역이 개편되면 코드가 바뀝니다. 과거 데이터와 맞추려면 코드에 기준 시점이 함께 있어야 합니다
  • 지역명이 주소의 일부로만 들어오는 경우(자유 입력 주소록 같은 것)는 resolve 전에 주소 파싱이 먼저입니다

정리하면

GIS에서 지역명은 문자열이 아니다.

지역은 식별 가능한 entity다.

따라서 지역명을 다룰 때는 검색보다 먼저 식별해야 한다.

📦추천 상품🔒 개인정보 수집 없음

쿠팡 로켓배송 특가 & 가성비 추천 제품 확인

이 글에서 소개하거나 추천하는 IT 기기, 가공식품, 가성비 필수 꿀템을 쿠팡 로켓배송 최저가로 빠르게 만나보세요.

쿠팡 최저가 확인하기 →