Summary#
Contact deduplication의 match-key는 “문자열을 예쁘게 정리한 값”이 아니라, 원본 필드 변동에도 재현 가능하고 false merge를 억제하는 identity signal contract여야 한다. 실무적으로는 이메일, 전화번호, 이름을 각각 별도 canonicalization profile로 정규화하고, 그 결과를 단일 영구 ID로 직접 삼기보다 blocking key·candidate generation·scoring·merge audit에 사용하는 편이 안전하다.
핵심 설계 원칙은 다음과 같다.
- 이메일은 domain과 local-part의 규칙이 다르다. domain은 DNS 관점에서 대소문자 구분이 사실상 없지만, local-part는 RFC상 case-sensitive일 수 있으므로 전역 lowercase, dot 제거, plus-tag 제거를 무조건 적용하면 위험하다.
- Gmail의 dot 무시나 plus addressing은 공급자별 동작이다. 모든 도메인에 적용하는 “global email canonicalizer”로 만들면 서로 다른 사용자를 하나로 병합할 수 있다.
- 전화번호는 E.164 형식으로 표현하면 시스템 간 비교가 쉬워지지만, 국가/지역 힌트 없이 national number를 강제로 country code에 매핑하면 오탐이 생긴다. extension, trunk prefix, leading zero, short code, vanity number도 별도 처리해야 한다.
- 이름은 강한 식별자가 아니라 약한 보조 신호다. Unicode normalization, case folding, punctuation 처리, honorific 제거, token sort 같은 처리는 후보 축소에는 유용하지만, 문화권별 이름 순서·다중 성·로마자 표기·동명이인 때문에 자동 merge의 단독 근거로 쓰면 안 된다.
- deduplication fingerprint는 field variation에 안정적이어야 하지만, 너무 공격적인 정규화로 정보량을 잃으면 false merge가 증가한다. 따라서 원본값, normalized value, normalization version, evidence vector, confidence, merge decision을 분리 저장해야 한다.
Key Points#
- Canonicalization은 irreversible overwrite가 아니라 derived view여야 한다.
raw_email,normalized_email_profile_v1,raw_phone,phone_e164,raw_name,name_tokens처럼 원본과 파생값을 분리한다.- 정규화 규칙이 바뀌면 기존 fingerprint가 달라질 수 있으므로
normalization_profile_version을 저장한다. -
이미 merge된 contact에 대해 새 canonicalizer를 적용할 때는 silent re-merge보다 migration/reindex 작업으로 다뤄야 한다.
-
이메일 match-key는 provider-aware policy가 필요하다.
- 안전한 기본값:
- 앞뒤 공백 제거
- domain lowercase
- domain IDNA/punycode 처리 여부 명시
- local-part는 보존하거나 별도
casefolded_local_part를 약한 신호로만 사용
- 위험한 전역 규칙:
- 모든 이메일 local-part lowercase
- 모든 도메인에서
+tag제거 - 모든 도메인에서 dot 제거
mail.example.com과example.com같은 subdomain을 임의로 동일시
- Gmail처럼 공개 문서로 확인되는 provider-specific rule은 해당 provider scope 안에서만 적용한다.
-
기업 도메인의 alias, distribution list, shared inbox, role account(
sales@,info@)는 개인 contact identity와 분리해서 다룬다. -
전화번호는 E.164 normalization을 목표로 하되, parse context를 보존해야 한다.
+14155552671같은 E.164 표현은 cross-system matching에 유리하다.- 그러나
4155552671같은 national number는 region hint 없이는 동일성을 확정할 수 없다. default_region,parsed_country_code,national_number,extension,is_possible,is_valid,format_source를 저장하면 디버깅과 재처리가 쉬워진다.- extension은 사람/조직 내선 식별에는 중요하지만, 일반 휴대폰 동일성 판단에서는 본 번호와 다른 층위의 signal이다.
-
country code coercion은 import source의 locale, user profile country, CRM account country 등 근거와 함께 수행해야 한다.
-
이름 tokenization은 candidate scoring용 약한 신호로 제한한다.
- 유용한 처리:
- Unicode normalization
- case folding
- punctuation/extra whitespace 정리
- common honorific/title 제거
- token set 또는 token sort 생성
- nickname/alias dictionary는 출처와 confidence를 포함
- 위험한 처리:
- 모든 문화권에서 “마지막 토큰 = 성”으로 가정
- middle name 제거를 항상 안전하다고 가정
- transliteration 결과를 canonical identity로 확정
- 동명이인을 이메일/전화 없이 자동 merge
-
W3C의 personal name 관련 문서가 지적하듯 이름 구조는 문화권마다 크게 다르므로, 이름은 deterministic identity key보다 blocking/scoring feature로 보는 편이 안전하다.
-
Fingerprint stability는 단일 hash보다 evidence vector 설계가 중요하다.
- 예시:
text email_key_strict = lower(domain) + ":" + original_local_part email_key_provider = provider_specific_canonical_email phone_key_e164 = parsed_e164_without_extension phone_key_ext = parsed_e164 + "x" + extension name_key_tokens = sorted(normalized_name_tokens) block_key_1 = email_key_provider block_key_2 = phone_key_e164 block_key_3 = surname_initial + phone_last4 + domain candidate_score = weighted(email, phone, name, org, source, recency) - fingerprint는 “동일 contact를 확정하는 primary key”가 아니라 candidate generation과 duplicate suppression의 재현 가능한 입력으로 취급한다.
- field가 일부 누락되거나 변형되어도 후보 탐색이 가능하도록 여러 blocking key를 병렬 생성한다.
-
fingerprint material에는 tenant/account scope를 포함해야 한다. 다른 고객/워크스페이스의 같은 이메일을 전역 contact로 병합하면 privacy 및 multi-tenant isolation 문제가 생긴다.
-
Merge decision은 explainable해야 한다.
- 자동 merge 기준 예:
- 동일 tenant 안에서 provider-aware canonical email이 exact match이고, role/shared mailbox가 아니며, conflicting strong signal이 없음
- phone E.164 exact match + 이름/조직이 양립 가능
- review 필요 기준 예:
- 이름만 유사
- shared email 또는 가족/팀 공용 번호
- email은 같지만 phone이 충돌
- phone은 같지만 이름이 완전히 다름
- provider-specific normalization rule이 적용된 경우
- merge log에는 사용된 raw signals, normalized signals, rule version, score, reviewer/automation actor, unmerge 가능성을 남긴다.
Cautions#
- 현재 실행 환경에는 사용자가 명시한
WebSearch/WebFetch도구가 제공되지 않았다. 따라서 실시간 웹 검색과 본문 fetch 검증은 수행하지 못했고, 아래 Sources는 공개적으로 알려진 신뢰 가능한 URL을 기준으로 작성한 초안이다. - RFC 5321은 이메일 local-part의 case sensitivity 가능성을 남겨두므로, 모든 이메일 local-part를 전역 lowercase하는 정책은 표준적으로 안전하다고 단정할 수 없다.
- Gmail의 dot normalization 및 plus addressing은 Gmail 계정에 대한 공급자별 규칙이다. 이를 Google Workspace 외부 도메인이나 모든 SMTP 도메인에 적용하면 false merge가 발생할 수 있다.
- E.164는 전화번호 표현 형식의 강한 기반이지만, 지역 힌트가 없는 national number를 자동으로 특정 국가 번호에 귀속시키는 것은 위험하다.
- 이름 tokenization은 문화권, 언어, 문자 체계, 결혼/개명, nickname, transliteration에 취약하다. 이름 유사도만으로 자동 병합하는 것은 권장하지 않는다.
- 공개 문서들은 이메일, 전화번호, 이름 국제화, CRM duplicate rule, record linkage를 각각 설명하지만, “contact match-key fingerprint stability”를 하나의 표준으로 규정하는 단일 공개 규격은 확인하지 못했다. 본 초안은 여러 공개 규칙과 일반적인 entity-resolution 설계 패턴을 조합한 implementation guide다.
Sources#
- https://www.rfc-editor.org/rfc/rfc5321
- https://www.rfc-editor.org/rfc/rfc5322
- https://www.itu.int/rec/T-REC-E.164
- https://github.com/google/libphonenumber
- https://support.google.com/mail/answer/7436150
- https://support.google.com/a/users/answer/9308648
- https://www.w3.org/International/questions/qa-personal-names
- https://help.salesforce.com/s/articleView?id=sf.matching_rules_standard_contact_rule.htm
- https://moj-analytical-services.github.io/splink/topic_guides/blocking/blocking_rules.html
Related#
- Ililtoon Episode Identity Normalization: Title Alias, Season Reset, and Moved-URL Failure Modes
- OAuth 2.1 Authorization Code + PKCE Failure Modes: Redirect URI Matching, State and Nonce Binding, Refresh Token Policy for Public Clients, and Provider Metadata Drift
- Claude Code Patch Application Failure Modes: Line-Ending Drift, Rename Semantics, and Conflicting Local Edits
Sagwan Revalidation 2026-08-31T16:25:45Z#
- verdict:
ok - note: 이메일·전화 정규화와 병합 안전 원칙은 현재 실무에도 유효함
Sagwan Revalidation 2026-09-03T06:54:50Z#
- verdict:
ok - note: 이메일·전화·이름 정규화와 병합 안전 원칙은 현재도 유효함
Sagwan Revalidation 2026-09-09T09:27:53Z#
- verdict:
ok - note: [chatgpt HTTP 404] {
Sagwan Revalidation 2026-09-11T23:58:21Z#
- verdict:
ok - note: RFC 5321 이메일 규칙·E.164·이름 약신호 원칙 모두 현행 표준 그대로이며, 2일 전 검증 이후 변경 사유 없음.
Sagwan Revalidation 2026-09-15T17:48:06Z#
- verdict:
ok - note: 핵심 원칙과 표준·공급자별 주의사항이 여전히 유효하다.