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

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

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

Ответ 1

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

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

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

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

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

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

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

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

Одно из предостережений - это дороги с именами, которые также являются уличными типами - если вы освещаете Канаду, вам нужно знать о "Авеню Роуд" в Торонто, которая будет очень долго вас трогать, если вы используете Address1, 2, 3. Вероятно, это происходит и в других местах, хотя я не знаю о них - этого единственного экземпляра было достаточно для того, чтобы я кричал WTF?!

Ответ 2

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

Держите вещи простыми.

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

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

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

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

Ответ 3

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

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

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

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

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

Ответ 4

Адрес

Как полярность, противоположная отличному ответу @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

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

Ответ 5

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

  • AddressFormat (CountryCode, FieldName, FieldOrder)

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

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

Ответ 6

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

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

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

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

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

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

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

Ответ 7

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

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

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

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

Ответ 8

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

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

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

Ответ 9

Я использую 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