Нормализация адресов и телефонов: чек-лист перед продакшеном
Одинаковые на вид телефоны и адреса могут скрывать разные данные, а разные записи — указывать на один объект. Перед запуском нормализации сохраните оригиналы, определите правила по странам и проверьте, что ошибки не превращаются в ложные совпадения.

Перед запуском очистки данных проверьте не только, превращается ли телефон в единый формат, но и не склеивает ли алгоритм разные номера и адреса. Ошибка здесь быстро расходится по CRM, доставке и отчётам: клиент получает чужую посылку, а команда поддержки не может восстановить исходную запись. Ниже — чек-лист для пайплайна обработки; технический контекст примеров — PostgreSQL 16 и Python 3.12, но рекомендации не зависят от конкретного API.
Сначала определите, что считать нормализацией
Нормализация — не попытка сделать строки красивыми. Это создание согласованного представления данных для сравнения и обработки. У неё две отдельные задачи: привести эквивалентные записи к общему виду и не объявить эквивалентными записи, которые лишь похожи.
Телефон обычно можно привести к формату международного набора, если известна страна и номер прошёл проверку. С адресом сложнее: состав частей и правила записи зависят от страны, а в одной стране встречаются разные схемы адресации. Поэтому общий набор регулярных выражений не заменит страновую логику и справочные данные.
Нормализованное значение — это производное поле, а не новая версия истины. Исходную запись нужно сохранить так, чтобы её можно было восстановить.
До реализации зафиксируйте назначение нормализованных полей: поиск дублей, отправка SMS, расчёт доставки или аналитика. Для этих задач могут понадобиться разные представления. Например, формат для набора номера не обязан быть удобным для отображения человеку.
Выберите стратегию до того, как чистить базу
Самая рискованная схема — перезаписать исходные строки «очищенными» значениями. После этого трудно отличить ошибку ввода от ошибки преобразования, а спорную запись нельзя проверить без копии из резервной системы.
| Подход | Что даёт | Цена и риск | Когда уместен |
|---|---|---|---|
| Заменять исходное значение нормализованным | Простая схема и меньше полей | Теряется ввод пользователя; ошибку преобразования трудно расследовать | Почти никогда, если данные нужны для поддержки, аудита или повторной обработки |
| Хранить оригинал и производное значение отдельно | Можно повторно обработать запись и сравнить результат с вводом | Нужно поддерживать поля, версии правил и статусы обработки | Основной выбор для продакшен-пайплайна |
| Нормализовать только при чтении | Не нужно сразу менять хранилище и мигрировать данные | Одна и та же запись может обрабатываться по-разному в разных сервисах; растут задержка и число повторных вычислений | Временный этап или редкий запрос, пока объём и требования невелики |
Для второго подхода предусмотрите как минимум исходное значение, нормализованное значение, страну или регион, статус результата и версию правил обработки. Для адреса полезны отдельные компоненты, если ваша система умеет получать их надёжно. Не заполняйте недостающие части догадками.
Чек-лист перед запуском
- Сохраните исходные данные. Не удаляйте пробелы, пунктуацию и исходную раскладку из единственной копии значения. Запишите, откуда пришла запись и когда её обработали. Проверка: на тестовом наборе исходное поле после обработки совпадает с входом побайтно или по заранее оговорённому правилу хранения.
- Зафиксируйте страны и локали. Для телефона укажите источник страны по каждому потоку данных: явное поле, профиль клиента или другое проверяемое основание. Не выводите страну автоматически из языка интерфейса или IP-адреса. Для адресов ведите правила по странам, а не один международный шаблон. Проверка: для каждого потока в документации есть ответ, откуда берётся страна и что происходит, если её нет.
- Разведите форматирование и проверку. Удаление пробелов и скобок не доказывает, что номер существует или доступен. Аналогично, приведённая к одному регистру строка адреса не подтверждает существование адреса. Проверка: результат обработки отдельно сообщает, удалось ли разобрать запись и прошла ли она нужные проверки.
- Не теряйте значимые детали телефона. Международный префикс, начальные нули и добавочный номер нельзя безусловно удалять. Добавочный номер храните отдельно от основного; не считайте его частью международного номера. Не дописывайте код страны, если правило выбора страны неоднозначно. Проверка: набор номеров с национальным и международным префиксами, а также с добавочными, сохраняет ожидаемый смысл.
- Не делайте адрес из догадок. Разделяйте страну, регион, населённый пункт, улицу, дом и другие компоненты только при достаточной уверенности. Не подменяйте отсутствующий индекс «ближайшим», а сокращение — предположительно равнозначным названием. Проверка: неполный или неоднозначный адрес получает статус «нужно уточнение», а не уверенно собранную фиктивную структуру.
- Проверьте Unicode и пробелы. Визуально одинаковые символы могут иметь разные представления в Unicode; последовательности пробелов тоже различаются. Выберите и задокументируйте правила Unicode-нормализации и обработки пробелов. Не удаляйте диакритические знаки и не меняйте буквы ради удобства сравнения без требований конкретной страны. Проверка: эквивалентные формы обрабатываются предсказуемо, а исходное написание остаётся доступным.
- Добейтесь идемпотентности. Повторная обработка уже нормализованной записи не должна менять её результат. Если обновилась библиотека или справочник, повторный пересчёт должен быть управляемым, а не происходить незаметно при чтении. Проверка: прогон одного набора дважды даёт те же нормализованные поля и статусы.
- Задайте безопасное поведение при ошибке. Не заменяйте неразобранное значение пустой строкой и не отправляйте его дальше как корректное. Сохраняйте исходник, код причины и возможность повторной обработки. Проверка: для ошибочной записи можно определить причину, не читая необработанные логи и не восстанавливая данные из резервной копии.
- Сравните результат с размеченной выборкой. Подготовьте примеры реальных стран, форматов, опечаток, неполных данных и граничных случаев; ожидаемый результат проверьте вручную. Измеряйте долю разобранных и отклонённых записей, число ложных совпадений и расхождения с предыдущей версией правил. Проверка: до релиза есть базовые значения метрик и порог, при котором запуск останавливается.
- Выпустите изменение постепенно. Сначала обработайте копию данных или небольшую долю потока, сравните старые и новые значения и проверьте downstream-системы. Подготовьте способ отката и повторного пересчёта. Проверка: команда может отключить новую обработку, не теряя исходные данные и не оставляя часть систем на несовместимом формате.
Что чаще всего ломается в продакшене
Телефон кажется корректным, но страна выбрана неверно
Один и тот же набор цифр может интерпретироваться по-разному в зависимости от региона. Если источник страны отсутствует, не угадывайте её молча: оставьте результат неопределённым и отправьте запись на уточнение. Для проверки используйте библиотеку, которая знает национальные планы нумерации, а не только удаляет знаки пунктуации. Например, Google libphonenumber — отдельный проект; конкретную версию зависимости закрепите в lock-файле и проверяйте при обновлении.
Адреса сравниваются после слишком агрессивной очистки
Удаление всех знаков препинания и сокращение слов до первых букв помогает получить совпадения, но одновременно увеличивает число ложных пар. Это опасно для дедупликации: совпадение строки — не доказательство, что речь об одном доме или человеке. Сначала задайте отдельные правила сопоставления по стране и назначению, затем проверьте их на размеченных парах. Не используйте нормализованную строку как единственное основание для объединения записей.
Новая версия меняет результаты без видимого сбоя
Обновление библиотеки, национальных правил или адресного справочника может изменить разбор. Сервис при этом продолжит работать, но часть записей получит новое значение. Храните версию обработчика и дату пересчёта; перед обновлением сравнивайте результаты на фиксированной выборке и отдельно проверяйте записи, где изменился статус или нормализованное значение.
Что измерять: долю записей, прошедших разбор; долю неоднозначных и ошибочных значений; число изменённых результатов при обновлении правил; количество дублей, подтверждённых вручную. Скорость тоже важна, но она не компенсирует тихую порчу данных.
Следующий шаг: пилот на данных, которые отражают реальность
Соберите выборку из нескольких источников и стран, добавьте в неё неполные и спорные записи, а затем вручную зафиксируйте ожидаемые исходы. Прогоните старую и новую обработку параллельно, сравните поля и причины отказа. Только после этого выбирайте пороги для автоматической обработки: какие записи можно принять, какие отправить на проверку и какие нельзя использовать для объединения клиентов или доставки.
Не запускайте массовую перезапись до проверки повторного пересчёта и отката. Зафиксируйте используемые версии PostgreSQL 16, Python 3.12 и зависимостей в окружении проекта; при другой версии проверьте поведение конкретных библиотек и компонентов по их документации. Детали дедупликации адресов — отдельная задача: здесь важно, чтобы нормализация не выдавала предположение за подтверждённый факт.
* Идемпотентность — свойство обработки, при котором повторное применение тех же правил к уже обработанной записи не меняет результат.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: Google libphonenumber — репозиторий и документация проекта, Unicode Standard Annex #15: Unicode Normalization Forms
Частые вопросы
Можно ли хранить телефон только в международном формате?
Как нормализовать телефон, если страна неизвестна?
Нужно ли удалять из адреса сокращения и знаки препинания?
Можно ли объединять клиентов по совпавшим нормализованным адресам?
Что делать, если новая версия библиотеки изменила результат разбора?
Подойдут ли эти рекомендации для другой версии PostgreSQL или Python?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.