Как хранить международные географические адреса в реляционной базе данных?
учитывая задачу хранения международных географических адресов в реляционной таблице, какова наиболее гибкая схема? Должна ли каждая часть адреса быть разбита на свои собственные поля или она должна быть больше похожа на свободный текст?
есть ли смысл в разделении по-разному отформатированные адреса в разных таблицах? Например, есть таблица для USAAddress, CanadianAddress, UKAddress...?
9 ответов
я обобщу свои мысли из моего блога -урок хранения адресов.
в моем текущем проекте [я работаю в логистической компании] мы храним международные адреса. Я провел исследования по адресам во всем мире при разработке этой части базы данных. Есть много разных форматов. В западном мире мы, как правило, используем довольно однородный формат - несколько отличий, но они в основном:
- улицы Номер - числовое
- название дома или здания - [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]
- PO Box
- квартиры
- здание
- пол
- офис
- Люкс
- etc...
-
Идентификатор Типа Адреса [тип varchar]
- т. е. номер коробки, номер квартиры, номер этажа помните, что номера квартир и офисов иногда имеют буквенно-цифровую информацию-как 1A
-
Муниципалитета [VarChar или Int, если у вас есть Муниципалитеты стол]
- например, если ваша деревня / деревня появляется в адресе перед городом.
- Города [VarChar или Int, если у вас есть таблица городов]
-
Управляющих Район [VarChar или Int, если у вас есть таблица районов]
- государство (США)
- Провинция (Канада)
- Федеральный Округ (Мексика)
- округа (Великобритания)
- etc...
-
Почтовая Площадь [тип varchar]
- Zip (США)
- Почтовый Индекс (Канада, Мексика)
- почтовый индекс (в Великобритании)
- страны [VarChar или Int, если у вас есть таблица стран]
Это, по-видимому, охватывает большинство стран, но порядок полей может отображаться по-разному. Вы можете найти список форматов отображения в http://www.bitboost.com/ref/international-address-formats.html#Formats
например, во многих странах почтовый индекс падает перед названием города, а номер улицы - после названия улицы. В Канаде, США и Великобритании номер улицы предшествует названию улицы, а почтовый индекс (или почтовый индекс) - после названия города.
отвечая на ваш вопрос о разделении адресов на разные страны, я бы не предложил, это будет просто усложняйте жизнь в других областях-например, в области отчетности. Формат, который я предоставил, охватывает все адреса в нашей базе данных логистики, которая охватывает США, Канаду, Мексику и Великобританию без каких-либо проблем. Он также охватывает все наши европейские, китайские, японские и малайзийские адреса. Я не могу говорить за другие страны, но мне еще не приходилось хранить адрес из страны, которую эти поля не будут поддерживать.
Я не предлагаю идти с форматом Address1, Address2, Address3 предложенный другими и увиденный во многих базах данных, потому что разбор адресной информации из буквенно - цифровой строки не так прост, как может показаться на первый взгляд, особенно если данные введены неправильно, из-за дезинформации, опечатки, неправильного написания и т. д. Если вы разделяете свои поля, вы можете использовать алгоритмы расстояния для проверки вероятного значения, использовать вероятность для проверки названия улицы по почтовому индексу и номеру улицы или для проверки провинции и города по названию улицы и т. д. Попробуйте сделать что-нибудь из этого, когда есть строка, обозначающая весь твой адрес. Это не тривиальный вопрос, если напрячь воображение.
QA в адресной базе данных-головная боль, точка. Самый простой способ упростить вашу жизнь в этой области-убедиться, что все поля содержат только одну информацию, которая может быть автоматически проверена как правильная во время ввода. Вероятность, алгоритмы расстояния и регулярные выражения могут проверить правильность ввода и предоставить обратную связь пользователю относительно того, что их ошибкой было и предложить необходимые изменения.
одно предостережение, чтобы быть в курсе, это дороги с именами, которые также являются уличными типами - если вы покрываете Канаду, вам нужно знать о "Avenue Road" в Торонто, который заставит вас много времени, если вы используете формат Address1, 2, 3. Вероятно, это происходит и в других местах, хотя я не знаю о них - этого единственного случая было достаточно для меня, чтобы кричать WTF?!
будьте осторожны, чтобы не анализировать форматы адресов. Когда вы это сделаете, вы, скорее всего, получите спецификацию, которую большинству пользователей нужно будет работать вокруг, эффективно заставляя их использовать неправильные поля или только заполняя первичные поля и игнорируя дополнительные поля.
сохранить вещи простыми.
StreetType как упомянуто BenAlabaster вызовет проблемы, когда вы начнете работать с языками, отличными от изолирующих языков как английский или испанский.
чтобы показать вам, как плохие вещи могут попасть в дикую природу:" Генриетта Ролан Хольстстрат "в Амстердаме, построенная из" Генриетты " + "Ролан Хольст" + "Страат", который может быть сокращен как" Роланд Хольстстрат "или" Роланд Хольстстрат"."или с ошибками, как "Х. Р. Holststr."или "Генриетта Роланд-Хольст Страат", в зависимости от погоды. Если у вас нет современного уличного регистра для каждой страны на земле, вы никуда не пойдете.
и, наконец,, будьте осторожны, что в некоторых многоязычных странах имена могут отличаться от одного языка к другому! Например, в Брюсселе, где на многих улицах есть и французский и голландское название: "Avenu du Port" и "Havenlaan", в зависимости от предпочтительного языка адресата. (Google Maps показывает оба имени поочередно, просто на всякий случай.)
вы можете попытаться разработать все виды умных трюков здесь, но являются торговыми представителями. собираетесь понять это?
зависит от того, что вы хотите сделать с ним.
Я обнаружил, что всегда проще использовать адреса для других целей (например, проверка данных USPS или получение тарифов доставки от UPS/FEDEX), если они разделены.
вот что я обычно использую для адресов:
- Адресная Строка 1
- Адресная Строка 2
- Адресная Строка 3
- города
- края
- почтовое Код
- округа
- страны
в ответ на редактирование: для большинства ситуаций я не вижу пользы. В таблице I, приведенной выше, достаточно полей (и достаточно общих) для адресов большинства стран.
адрес
как полярная противоположность отличному ответу @BenAlabaster предоставил, вы могли бы просто иметь:
address TEXT(300)
postal_code VARCHAR(15)
country_code VARCHAR(2)
ваши клиентские макеты форм все еще могут быть настолько сложными, насколько вы считаете нужным (или использовать многострочный ввод, где пользователь может вручную ввести свой адрес). Затем вы можете добавить разрывы строк в адрес, где это необходимо.
страны
таблица вашей страны будет выглядеть следующим образом:
country_code VARCHAR(2)
country_name VARCHAR(255)
кроме того, вы мог бы!--14-->один следующее:
postal_code_required TINYINT(1)
postal_code_regex VARCHAR(255) NULL DEFAULT NULL
затем используйте следующие списки для разработки таблицы стран:
вот анекдот для всех, кто натыкается на этот вопрос:
Я говорю как человек, который жил и работал на многих континентах (Европа, Азия, Северная Америка). По моему опыту и опыту людей, с которыми я работаю, нам было намного проще использовать системы, которые делают следующее:
- укажите три строки, в которые я введу один адрес. Передайте эти три строки вашей местной почтовой службе, как я их печатаю, дословно. Позвольте мне использовать любой набор символов, который я хочу; используйте UTF-8 или что-то лучше.
- если ваша система имеет бизнес-требования, которые мне нужно указать конкретную информацию(например, почтовый индекс, префектура, штат и т. д. ), попросите об этом отдельно. Под бизнес-требованиями я имею в виду такие вещи, как аналитика; эти биты информации не должны делиться с вашей местной почтовой службой ( если только я также не записал ту же информацию в одну из трех строк из пункта 1 выше ).
- есть выпадающий список, который просит меня указать категориальное местоположение адреса, который я предоставил в строках пункта 1 выше, возможно, страна.
- если вы должны проанализировать информацию, которую я предоставляю в строках пункта 1, используйте мой ответ на пункт 3, Чтобы выбрать регулярное выражение. Запустите это регулярное выражение против информации в пункте 1, чтобы проанализировать ее. Попробуйте заполнить элементы пользовательского интерфейса пункта 2 с помощью вывода из вашего регулярного выражения. Если я исправлю эту автоматически заполненную информацию-используйте тот факт, что я изменил ее, чтобы улучшить ваше регулярное выражение. Точно так же, насколько это возможно, дайте мне возможность пересмотреть и исправить результат вашего регулярного выражения: никто лучше меня не знает, что я намеревался сообщить.
системы, построенные таким образом, я нахожу, делают мою жизнь проще. Особенно когда я отправляю почту в почтовую систему, о которой ваша фирма практически ничего не знает.
Если ваша фирма имеет внутренние знания о конкретных почтовых системах, используйте мой выбор в пункте 3, чтобы сообщить какой вид вы показываете мне. Многие люди знают, что почтовая система США ожидает на упаковке; если я выберу нас в пункте 3, Не стесняйтесь делать вид подходящим для адреса США. Если я выберу страну, о которой ваша фирма ничего не знает, покажите общие три строки и позвольте мне сделать остальное; не заставляйте меня использовать ASCII.
и давайте будем реальными здесь-создание полной, энциклопедической базы данных всех глобальных почтовых систем (государственных и частных ) является геркулесовой задачей в лучшем случае, если не невозможное. Есть, например, почтовые системы, в которых только местный перевозчик на последней миле действительно знает, где находится адрес. Иногда возможность передавать заметки этому носителю на упаковке чрезвычайно полезна. И сопоставление локальных знаний каждого носителя edge case в вашей базе данных действительно является невозможной задачей.
просто спросите Геделя. (А затем спросите себя, пытаетесь ли вы использовать аксиоматическую систему для моделирования Вселенной дискурса, плюс-минус какая-то арифметика вроде теории множеств или реляционной алгебры. )
комментарий к ответу Бена Алабастера: Для форматирования адресов в зависимости от страны можно использовать таблицу форматирования с упорядочением столбцов для каждой страны в виде отдельных строк.
- AddressFormat (CountryCode, FieldName, FieldOrder)
порядок полей может быть закодирован для использования сложных макетов сетки.
нет смысла разделять адреса по странам. Это будет хаотично, поскольку количество стран увеличивается, и вы будете земля в беде, если вы хотите найти все адреса скажем, международного клиента. Наличие типа адреса, предложенного Беном, также может привести к двусмысленностям, когда у вас есть адрес, который имеет номер здания и номер квартиры. Я мог бы быть в жилом комплексе, где каждое здание имеет другое название. Это очень распространено в Индии.
Я использую 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
Это не поможет, если вы хотите разобрать улицу (имя, номер дома,...).
кстати. если вы ищете многоязычный список стран:https://github.com/umpirsky/country-list
единственный способ-разделить их на:
Name varchar,
Title varchar,
StreetAddress varchar,
StreetAddressLine2 varchar,
zipCode varchar,
City varchar,
Province varchar,
Country lookup
так как почти каждая страна имеет свой собственный стандарт для получения адресных данных, и каждая страна имеет другой формат zipcodes.
У вас может быть небольшая выборка проблем в мой пост из аналогичного вопроса.
Это не должно иметь смысла для отдельных адресов для каждой страны, так как есть страны, где у вас мало соглашений об адресах. Некоторые популярные конвенции включают отсутствие улицы в маленьких деревнях, только название и номер деревни, в то время как улицы находятся в адресах больших городов. Я узнал, что в столице Венгрии – Будапеште есть несколько улиц с одинаковым названием (вы различаете их по номеру района города), в то время как другие города не имеют таких адресов (кто-то из Венгрии может фактически подтвердить, что это правда). Таким образом, общее количество форматов адресов будет numer_of_countries умноженное на количество форматов адресов в этой стране... можно сделать с помощью разные столы, но это будет ужасная работа.
Я знаю, что это очень старая тема, на которую уже ответили, но я думал, что я бы бросил свои два цента. Все зависит от того, какие цели вашего проекта и как вы ожидаете, что ваши целевые пользователи будут вводить адреса. Предложение Бена позволит вам точно анализировать адреса, но, с другой стороны, может сделать более длительный (и, возможно, более неприятный) процесс ввода пользовательских данных. Предложение Стивена Райтона проще и может быть проще для пользователей вводить адреса в результате.
Я также видел некоторые модели, которые просто имели столбец "адрес", который будет захватывать типичный номер улицы, тип, название улицы, номер единицы / квартиры и т. д. все в одном столбце, пока держащ город, страну, регион, ЕТК. в других колонках. Аналогично модели Стивена, за исключением Address1, Address2 и Address3, объединенных в один столбец.
Я считаю, что наиболее гибкие модели, как правило, являются наименее ограничительными, в зависимости от вашей интерпретации гибкого.