Как международные географические адреса должны храниться в реляционной базе данных? - PullRequest
52 голосов
/ 21 июля 2009

Учитывая задачу сохранения международных географических адресов в реляционной таблице, какая схема является наиболее гибкой? Должна ли каждая часть адреса быть разбита на свои поля или она должна быть больше похожа на свободный текст?

Есть ли смысл разделять по-разному отформатированные адреса на разные таблицы? Например, есть таблица для USAAddress, CanadianAddress, UKAddress ...?

Ответы [ 9 ]

86 голосов
/ 21 июля 2009

Я обобщу свои мысли из моего блога - Урок по хранению адресов .

В моем текущем проекте [я работаю в логистической компании] мы храним международные адреса. Я провел исследование адресов во всем мире при разработке этой части базы данных. Там много разных форматов. В западном мире мы склонны использовать довольно унифицированный формат - несколько различий, но они в основном:

  • Номер улицы - Числовой
  • Название дома или здания - [VarChar - в Великобритании некоторые дома / здания идентифицируются по имени, а не по номеру]
  • Суффикс номера улицы [VarChar, хотя в большинстве случаев достаточно Char (1)]
    • A, B и т. Д.
  • Название улицы [VarChar]
  • Тип улицы [VarChar или Int, если у вас есть таблица StreetTypes]
    • До сих пор я нашел 262 уникальных типа в англоязычном мире, вероятно, их больше, и не забывайте другие языки, например, Штрассе, Рю и т.д.
  • Направление улицы [VarChar (2)]
    • N, E, S, W, NE, SE, NW, SW
  • Тип адреса [VarChar или Int, если у вас есть таблица AddressTypes]
    • PO Box
    • Квартира
    • Строительство
    • Пол
    • Office
    • Люкс
    • и т.д ...
  • Идентификатор типа адреса [VarChar]
    • т.е. Номер ящика, номер квартиры, номер этажа помните номера квартир и офисов, где иногда есть буквенно-цифровая информация - например, 1A
  • Местный муниципалитет [VarChar или Int, если у вас есть таблица муниципалитетов]
    • Например, если ваша деревня / деревня появляется в адресе перед городом.
  • Город / город [VarChar или Int, если у вас есть таблица городов]
  • Управляющий район [VarChar или Int, если у вас есть таблица районов]
    • Штат (США)
    • Провинция (Канада)
    • Федеральный округ (Мексика)
    • Округ (Великобритания)
    • и т.д ...
    1098 **
  • Почтовая площадь [VarChar]
    • Почтовый индекс (США)
    • Почтовый индекс (Канада, Мексика)
    • Почтовый индекс (Великобритания)
  • Страна [VarChar или Int, если у вас есть таблица стран]

Похоже, что это относится к большинству стран, но порядок полей может отображаться по-разному. Вы можете найти список форматов отображения на http://www.bitboost.com/ref/international-address-formats.html#Formats

Например, во многих странах почтовый индекс указывается перед названием города, а номер улицы - после названия улицы. В Канаде, США и Великобритании номер улицы предшествует названию улицы, а почтовый индекс (или почтовый индекс) - после названия города.

Отвечая на ваш вопрос о разделении адресов по разным странам, я не стал бы это предлагать, это просто усложнит жизнь в других областях - например, в отчетности. Формат, который я предоставил, охватывает все адреса в нашей базе данных логистики, которая охватывает США, Канаду, Мексику и Великобританию без каких-либо проблем. Он также охватывает все наши адреса в Европе, Китае, Японии и Малайзии. Я не могу говорить за другие страны, но мне еще не приходилось хранить адрес из страны, которую эти поля не будут поддерживать.

Я не предлагаю использовать формат Address1, Address2, Address3, предложенный другими и встречающийся во многих базах данных, потому что анализ информации об адресе из буквенно-цифровой строки не так прост, как может показаться на первый взгляд, особенно если данные не отображаются. введен правильно, из-за дезинформации, опечатки, орфографической ошибки и т. д. Если вы разделяете свои поля, вы можете использовать дистанционные алгоритмы для проверки на возможное значение, использовать вероятность для проверки названия улицы по почтовому индексу и номеру улицы или для проверки провинции и города по названию улицы и т. д. Попробуйте сделать что-нибудь из этого, когда у вас есть строка, обозначающая весь ваш уличный адрес. Это не тривиальный вопрос, если только вы не фантазируете.

QA в базе данных адресов - головная боль, точка. Самый простой способ упростить вашу жизнь в этой области - убедиться, что во всех полях содержится только один фрагмент информации, который можно автоматически проверить на правильность при входе. Вероятность, дистанционные алгоритмы и регулярные выражения могут проверять правильность ввода и обеспечивать обратную связь с пользователем в отношении их ошибки и предлагать подходящие исправления.

Одно предостережение, о котором следует помнить, - это дороги с названиями, которые также являются типами улиц. Если вы путешествуете по Канаде, вам нужно знать о «Авеню-роуд» в Торонто, которая вас сильно опередит, если вы используете Адрес1, 2, 3 формат. Это, вероятно, происходит и в других местах, хотя я не знаю о них - этого одного экземпляра мне хватило, чтобы кричать WTF?!

19 голосов
/ 23 июля 2009

Будьте осторожны, чтобы не переусердствовать с анализом форматов адресов. Когда вы это сделаете, вы, скорее всего, получите спецификацию, которую большинству пользователей потребуется работать вокруг , эффективно заставляя их использовать неправильные поля или только заполняя основные поля и игнорируя дополнительные поля.

Не усложняйте.

Уличный тип, упомянутый BenAlabaster, вызовет проблемы, когда вы начнете работать с языками, отличными от изолирующих языков, таких как английский или испанский.

Чтобы показать вам, как плохие вещи могут попасть в дикую природу: «Генриетта Ролана Холстстрата» в Амстердаме, построенная из «Генриетты» + «Ролана Холста» + «страата», которую можно обозначить как «Роланд Холстстраат» или "Roland Holststr.", или с ошибкой как "HRHolststr." или "Генриетта Роланд-Холст страат", в зависимости от погоды. Если у вас нет актуального реестра улиц для каждой страны на земле, вы никуда не денетесь.

И, наконец, будьте осторожны, что в некоторых многоязычных странах имена могут отличаться от одного языка к другому! Например, в Брюсселе, где многие улицы имеют французское и с голландским названием: "Avenu du Port" и "Havenlaan", в зависимости от предпочтительного языка получателя. (Карты Google показывают оба названия поочередно, просто чтобы быть в безопасности.)

Вы можете попытаться придумать здесь все виды хитрых уловок, но это торговые представители. поймете это?

8 голосов
/ 21 июля 2009

Это зависит от того, что вы хотите с ним делать.

Я обнаружил, что всегда проще использовать адреса для других целей (таких как проверка по данным USPS или получение тарифов доставки от UPS / FEDEX), если они разделены.

Вот что я обычно использую для адресов:

  • Адресная строка 1
  • Адресная строка 2
  • Адресная строка 3
  • Город
  • Регион
  • Почтовый индекс
  • Область
  • Страна

В ответ на редактирование: Для большинства ситуаций я не вижу смысла. В приведенной выше таблице достаточно полей (и достаточно общих) для адресов большинства стран.

5 голосов
/ 21 февраля 2014

Адрес

Как полярная противоположность превосходному ответу @BenAlabaster, вы можете просто получить:

address       TEXT(300)
postal_code   VARCHAR(15)
country_code  VARCHAR(2)

Макеты форм на стороне клиента могут быть настолько сложными, насколько вам удобно (или использовать многострочный ввод, где пользователь может вручную ввести свой адрес). Затем вы можете добавить разрывы строк в адресе, где это необходимо.

Страна

Ваша таблица стран будет выглядеть следующим образом:

country_code  VARCHAR(2)
country_name  VARCHAR(255)

Кроме того, вы можете иметь один из следующих:

postal_code_required  TINYINT(1)
postal_code_regex     VARCHAR(255) NULL DEFAULT NULL

Затем используйте следующие списки для составления таблицы вашей страны:

3 голосов
/ 01 июня 2017

Вот анекдот для всех, кто наткнулся на этот вопрос:

Я говорю как человек, который жил и работал на многих континентах (Европа, Азия, Северная Америка). По моему опыту и опыту людей, с которыми я работаю, нам было гораздо проще использовать системы, которые выполняют следующие функции:

  1. Укажите три строки, в которые я буду вводить один адрес. Передайте эти три строки в местную почтовую службу, как я наберу их, дословно. Позвольте мне использовать любой набор символов, который я хочу; используйте UTF-8 или что-то лучше.
  2. Если в вашей системе есть бизнес-требования, для которых мне необходимо указать конкретную информацию (например, почтовый индекс, префектура, штат и т. Д.), Запросите ее отдельно. Под бизнес-требованиями я имею в виду такие вещи, как аналитика; эти биты информации не должны передаваться вашей местной почтовой службе (если только мне не довелось написать эту же информацию в одной из трех строк из пункта 1 выше).
  3. У меня есть выпадающий список, в котором меня просят указать категорическое местоположение адреса, которое я указал в строках пункта 1 выше, возможно, Страна.
  4. Если вам необходимо проанализировать информацию, которую я предоставляю в строках пункта 1, используйте мой ответ для пункта 3, чтобы выбрать регулярное выражение. Запустите это регулярное выражение для информации в пункте 1, чтобы проанализировать его. Попробуйте заполнить элементы пользовательского интерфейса в точке 2, используя выходные данные вашего регулярного выражения. Если я исправлю эту автозаполненную информацию - используйте тот факт, что я изменил ее, чтобы улучшить ваше регулярное выражение. Точно так же, насколько это возможно, дайте мне возможность просмотреть и исправить вывод вашего регулярного выражения: никто не знает лучше, что я намеревался сообщить, чем я.

Системы, построенные так, я считаю, делают мою жизнь проще. Особенно когда я отправляю почту в почтовую систему, о которой ваша фирма практически не имеет внутренних внутренних знаний.

Если ваша фирма обладает внутренними знаниями о конкретных почтовых системах, используйте мой выбор в пункте 3, чтобы сообщить, какой вид вы мне показываете. Многие люди знают, что почтовая система США ожидает от упаковки; если я выберу США в пункте 3, не стесняйтесь, чтобы представление выглядело подходящим для адреса в США. Если я выберу страну, о которой ваша фирма ничего не знает, отобразите три общие строки и позвольте мне сделать все остальное; не заставляйте меня использовать ASCII.

И давайте будем здесь реальными - создание полной энциклопедической базы данных всех глобальных почтовых систем (государственных и частных) в лучшем случае является геркулесовой задачей, если не невозможной. Есть, например, почтовые системы, в которых только местный оператор последней мили действительно знает, где находится адрес. Иногда возможность передавать заметки тому перевозчику на упаковке чрезвычайно полезна. А сопоставление локальных знаний каждого оператора связи в вашей базе данных - действительно невыполнимая задача.

Просто спросите Геделя. (А затем спросите себя, пытаетесь ли вы использовать аксиоматическую систему для моделирования вселенной дискурса, дайте или возьмите какую-нибудь арифметику, такую ​​как теория множеств или реляционная алгебра.)

1 голос
/ 22 августа 2016

Я использую библиотеку https://github.com/commerceguys/addressing для форматирования международных адресов, и они используют следующие элементы:

Country
Administrative area
Locality (City)
Dependent Locality (in: BR, CN, IR, MY, MX, NZ, PH, KR, ZA, TH)
Postal code
Sorting code
Address line 1
Address line 2
Organization
Recipient

Это не поможет, если вы хотите разобрать улицу (название, номер дома, ...).

Btw. если вы ищете многоязычный список стран: https://github.com/umpirsky/country-list

1 голос
/ 23 июля 2009

Комментарий ответа Бена Алебастра: Чтобы форматировать адреса в зависимости от страны, вы можете использовать таблицу форматирования, в которой столбцы для каждой страны расположены в виде отдельных строк.

  • AddressFormat (CountryCode, FieldName, FieldOrder)

Порядок полей также может быть закодирован для использования сложных макетов сетки.

Нет смысла разделять адреса по странам. Это будет хаотично, так как число стран увеличивается, и вы попадете в беду, если вы хотите найти все адреса, скажем, международного клиента. Наличие типа адреса, предложенного Беном, может также привести к двусмысленности, если у вас есть адрес, в котором есть как номер здания, так и номер квартиры. Я мог бы быть в жилом комплексе, где каждое здание имеет другое название. Это очень распространено в Индии.

0 голосов
/ 08 сентября 2010

Я знаю, что это очень старая тема, на которую уже дан ответ, но я подумал, что я тоже добавлю свои два цента. Все зависит от того, какие цели вашего проекта и как вы ожидаете, что ваши целевые пользователи будут вводить адреса. Предложение Бена позволит вам точно анализировать адреса, но, с другой стороны, может привести к более длительному (и, возможно, более неприятному) процессу ввода пользовательских данных. Предложение Стивена Райтона более простое, и в результате пользователям будет проще вводить адреса.

Я также видел некоторые модели, в которых просто был столбец «Адрес», в котором указывался бы типичный номер улицы, тип, название улицы, номер квартиры / квартиры и т. Д., Все в одном столбце, сохраняя при этом город, страну, регион и т. д. в других столбцах. Аналогично модели Стивена, за исключением того, что Address1, Address2 и Address3 объединены в один столбец.

Мое мнение таково, что наиболее гибкими моделями, как правило, являются те, которые являются наименее ограничительными, в зависимости от вашей интерпретации гибкости.

0 голосов
/ 21 июля 2009

Единственный способ - разделить их на:

Name varchar,
Title varchar,
StreetAddress varchar,
StreetAddressLine2 varchar,
zipCode varchar,
City varchar,
Province varchar,
Country lookup

, поскольку почти в каждой стране есть свой собственный стандарт для получения адресных данных, а в каждой стране - свой формат почтовых индексов.
Вы можете получить небольшую выборку проблем в моем посте из похожего вопроса.

Это не имеет смысла разделять адреса для каждой страны, так как есть страны, в которых у вас мало соглашений об адресах. Некоторые популярные соглашения включают в себя отсутствие улиц в небольших деревнях, только название и номер деревни, в то время как улицы находятся в адресах крупных городов. Я узнал, что в столице Венгрии - Будапеште есть несколько улиц с таким же названием (вы отличаете их по районам города), в то время как в других городах таких адресов нет (кто-то из Венгрии может подтвердить, что это правда). Таким образом, общее количество форматов адресов будет равно numer_of_countries, умноженному на количество форматов адресов в этой стране ... Может быть сделано с разными таблицами, но это будет ужасная работа.

...