기술

주소는 매장의 것인 줄 알았습니다 — 같은 자리에 새 브랜드가 들어오자 주소가 둘이 됐습니다

2026.09.117분 읽기

프랜차이즈 ERP의 매장 정보 화면에는 입점 층수, 상권, 배후 세대수, 부동산 점유 형태, 그리고 주소가 나란히 있었습니다. 매장을 등록하는 담당자 입장에서는 자연스러운 배치입니다. 매장을 보러 들어온 화면이니 매장에 관한 값이 거기 있는 것으로 읽힙니다.

그런데 같은 자리에서 브랜드가 바뀌어 매장이 새로 등록될 때마다, 담당자는 같은 건물의 주소와 층수와 상권을 처음부터 다시 입력했습니다. 건물은 그대로인데 입력만 매번 새로 일어났습니다. 처음에는 이것을 입력 편의의 문제로 봤습니다. 몇 달치를 놓고 보니 데이터 구조가 보내는 신호였습니다.


같은 건물인데 주소가 두 개가 됐습니다

한 자리에 있던 매장이 빠지고 다른 브랜드 매장이 들어오면 시스템에는 새 매장 레코드가 생깁니다. 주소가 매장에 매달려 있으니 새 레코드의 주소 칸도 비어 있고, 담당자가 그 칸을 채웁니다. 문제는 두 번째 입력이 첫 번째와 글자 단위로 같을 이유가 전혀 없다는 점입니다.

한쪽은 도로명으로 적히고 다른 쪽은 지번으로 적힙니다. 한쪽에는 층수가 붙고 다른 쪽에는 안 붙습니다. 사람 눈에는 같은 건물이지만 시스템에는 서로 다른 두 주소입니다. 한 사실이 두 곳에 복제되는 순간부터 두 값은 조용히 갈라집니다.

먼저 티가 난 곳은 화면이었습니다. 매장 목록에서 같은 건물의 두 매장이 다른 주소로 노출됐습니다. 그 다음은 주소를 입력값으로 쓰던 기능들이었습니다. 지역 날씨를 매장에 매칭하는 로직이 한쪽 매장만 제대로 잡았습니다.

운영자 입장에서 더 아픈 쪽은 따로 있었습니다. 같은 자리의 이력을 이어서 보려는 순간, 매장이 교체될 때마다 흐름이 끊겼습니다. 그 자리에서 지난 3년간 어떤 브랜드가 들어오고 나갔는지를 물으면, 답을 매장 레코드 여러 개를 사람이 눈으로 이어 붙여 만들어야 했습니다.

136-1.jpg


이 속성은 누구와 함께 변하는가

속성을 어디에 둘지 정할 때 쓴 질문은 하나였습니다. 매장 운영 주체가 바뀌거나 매장이 승계·교체될 때 이 값이 함께 바뀌는지, 아니면 그 자리에 고정으로 남는지입니다. 함께 바뀌면 매장의 속성이고, 매장이 바뀌어도 그대로면 그 값은 매장이 아닌 다른 무언가에 매달려 있습니다.

여기서 그 다른 무언가는 매장이 들어선 임대 물건이었습니다. 건물의 몇 층인지, 어떤 상권에 있는지, 배후 세대가 몇인지는 간판이 바뀌어도 그대로입니다. 주소는 더 분명합니다. 주소가 바뀌었다면 그것은 같은 물건이 아니라 이미 다른 물건입니다.

속성

매장이 교체되면

귀속

입점 층수·상권·배후 세대수

그대로

임대 물건

주소

그대로

임대 물건

부동산 점유 형태(건물주·상가주·임대 등)

그대로

임대 물건

브랜드·운영 주체·영업 상태

함께 바뀜

매장

매장 화면에 주소가 보여야 편하다는 요구 자체는 여전히 맞습니다. 다만 그것은 화면 배치의 문제이고, 값이 저장되는 자리는 다른 질문입니다. 화면은 물건의 주소를 끌어와 보여주면 그만입니다. 이 둘을 붙여서 생각하는 동안 값이 계속 매장 쪽에 남아 있었습니다.

136-2.jpg


매장에 있던 값을 물건으로 옮겼습니다

입지 속성과 점유 형태와 주소를 매장에서 임대 물건으로 옮기고, 물건을 그 값들의 단일 진실 원천으로 뒀습니다. 매장은 물건을 참조합니다. 같은 물건에 매장이 세 번 들어와도 주소는 한 번만 관리되고, 새 매장을 등록할 때 다시 채울 주소 칸이 없습니다.

옮기는 작업보다 손이 많이 간 쪽은 그 값을 읽고 있던 곳들이었습니다. 매장 주소를 읽는 지점이 네 곳 있었습니다.

지역 날씨 데이터를 매장에 매칭하는 로직

관리자 화면의 매장 목록 표시

매출이 끊긴 매장을 영업 종료 의심으로 판정하는 배치

POS 데이터가 아직 매장과 연결되지 않았을 때의 미매핑 등록 처리

네 곳을 모두 물건 주소 기준으로 다시 연결했습니다. 한 값의 거처를 옮기는 일은 사실상 그 값을 읽던 경로를 전부 찾아내는 일과 같습니다. 컬럼을 옮기는 것 자체는 짧게 끝나고, 읽던 곳을 빠짐없이 찾는 데 나머지 시간이 들어갑니다.

매장을 어떤 단위로 볼 것인가는 이 시스템에서 반복해서 다시 물었던 질문입니다. 한 자리에 브랜드가 하나라는 가정이 깨졌을 때도 같은 종류의 재정의가 필요했습니다.


이력은 부분 필드가 아니라 시점 전체로 남깁니다

값이 물건으로 모이면 다음 질문은 변경 이력입니다. 주소도, 권리금도, 입지도, 점유 형태도 시간에 따라 바뀝니다. 여기서 흔히 택하는 방식은 바뀐 필드만 골라 기록하는 쪽입니다.

물건 이력에는 주소·권리금·입지·점유 형태를 한 번에 담은 스냅샷으로 남겼습니다. 바뀐 필드만 남기면 특정 시점의 상태를 재구성할 때 이력 행 여러 개를 시간순으로 겹쳐 읽어야 하고, 중간에 한 행이라도 누락되면 그 시점이 통째로 복원되지 않습니다. 스냅샷 방식은 행 하나가 그 시점의 전체 상태입니다.

덕분에 매장이 몇 번 교체됐든 그 자리에서 무슨 일이 있었는지를 물건 하나로 따라갈 수 있습니다. 매장 기준으로는 끊겨 보이던 흐름이 물건 기준으로는 이어집니다.

136-3.jpg


참조가 맞을 때와 박제가 맞을 때

한 사실은 한 곳에 두는 것이 기본이지만 예외가 있습니다. 계약서에 박힌 주소가 그렇습니다. 계약 시점의 주소는 이후 도로명 체계가 바뀌어도 그 문서 안에서는 그대로여야 합니다. 이런 값은 참조가 아니라 그 시점 값을 복사해 동결하는 쪽이 맞습니다.

조회 성능을 위해 의도적으로 값을 복제할 수도 있습니다. 다만 그때는 원본이 어디인지가 분명해야 하고, 복제본은 캐시로만 취급합니다. 원본이 정해지지 않은 복제는 캐시가 아니라 또 하나의 진실이 됩니다.

소유 엔티티가 끝까지 애매한 속성도 남습니다. 매장명이 매장의 것인지, 물건의 것인지, 브랜드의 것인지는 판별 질문 하나로 갈리지 않습니다. 이런 값은 주 사용 맥락과 변경 빈도를 같이 놓고 정했습니다.


속성의 거처를 정하기 전에 확인한 것

이 값은 상위 엔티티가 교체될 때 함께 바뀌는가, 그 자리에 남는가

같은 값을 두 번 이상 사람이 입력하게 만드는 화면이 있는가

지금 이 값을 읽고 있는 코드·배치·화면을 전부 목록으로 뽑았는가

이 값의 변경 이력이 필요한가, 필요하다면 부분 필드가 아니라 시점 전체를 남기는가

계약·정산 문서처럼 값을 동결해야 하는 자리가 따로 있는가


매장이 아니라 물건이 기준이 되고 나서

재귀속 뒤에는 같은 자리의 정보가 한 곳에서만 관리됩니다. 매장은 그 정보를 참조하고, 물건 이력은 시점별 스냅샷으로 남습니다. 새 브랜드가 들어와도 담당자가 주소를 다시 입력할 칸이 없습니다.

속성이 어느 엔티티에 있어야 하는지는 화면에서 어디가 편한가로 정하지 않습니다. 무엇과 함께 변하는가로 정합니다. 이 기준 하나면 귀속을 두고 벌어지는 논쟁 대부분은 짧게 끝납니다. 남는 것은 애매한 몇 개인데, 그건 애초에 사람이 판단할 몫입니다.

#도메인모델링#단일진실원천#정규화#데이터정합성#변경이력#스냅샷