¿Cómo deben almacenarse las direcciones geográficas internacionales en una base de datos relacional?


Dada la tarea de almacenar direcciones geográficas internacionales en una tabla relacional, ¿cuál es el esquema más flexible? ¿Debería desglosarse cada parte de la dirección en sus propios campos, o debería ser más como texto libre?

¿Tiene sentido separar direcciones con un formato diferente en tablas diferentes? Por ejemplo, tenga una tabla para USAAddress, CanadianAddress, UKAddress...?

Author: Juha Syrjälä, 2009-07-21

9 answers

Resumiré mis pensamientos de mi post de blog - Una lección sobre almacenamiento de direcciones.

En mi proyecto actual [trabajo para una empresa de logística] estamos almacenando direcciones internacionales. He investigado direcciones de todo el mundo en el diseño de esta parte de la base de datos. Hay muchos formatos diferentes. En el mundo occidental tendemos a utilizar un formato bastante uniforme-algunas diferencias, pero son en su mayoría:

  • Número de calle - Numérico
  • Nombre de la casa o edificio - [VarChar-en el Reino Unido algunas casas / edificios se identifican por nombre, no por número]
  • Sufijo del número de calle [VarChar, aunque en la mayoría de los casos, Char(1) sería suficiente]
    • A, B, etc
  • Nombre de la calle [VarChar]
  • Street Type [VarChar o Int si tienes una tabla StreetTypes]
    • Hasta ahora, he encontrado 262 tipos únicos en el mundo de habla inglesa, es probable que más, y no se olvide de otros idiomas, es decir, Strasse, Rue, etc.
  • Dirección de la calle [VarChar(2)]
    • N, E, S, W, NE, SE, NW, SW
  • Tipo de dirección [VarChar o Int si tiene una tabla AddressTypes]
    • Apartado de correos
    • Apartamento
    • Edificio
    • Piso
    • Oficina
    • Suite
    • etc...
  • Identificador de tipo de dirección [VarChar]
    • es decir, número de casilla, Número de apartamento, Número de piso recuerde números de apartamento y oficinas a veces tienen información alfanumérica-como 1A
  • Municipio local [VarChar o Int si tiene una tabla de Municipios]
    • Por ejemplo, si su aldea/pueblo aparece en la dirección antes de la ciudad.
  • Ciudad / Pueblo [VarChar o Int si tienes una tabla de Ciudades]
  • Distrito de Gobierno [VarChar o Int si tiene un Distrito tabla]
    • Estado (EE.UU.)
    • Provincia (Canadá)
    • Distrito Federal (México)
    • Condado (Reino Unido)
    • etc...
  • Área Postal [VarChar]
    • Zip (EE.UU.)
    • Código postal (Canadá, México)
    • Código postal (Reino Unido)
  • País [VarChar o Int si tiene una tabla de Países]

Esto parece cubrir la mayoría de los países, pero el orden de los campos puede mostrarse de manera diferente. Puede encontrar una lista de formatos de visualización en http://www.bitboost.com/ref/international-address-formats.html#Formats

Por ejemplo, en muchos países, el código postal cae antes del nombre de la ciudad y el número de la calle cae después del nombre de la calle. En Canadá, EE.UU. y el Reino Unido el número de la calle precede al nombre de la calle y el código postal (o ZIP) viene después del nombre de la ciudad.

En respuesta a su pregunta sobre la separación de las direcciones en diferentes países, I no lo sugeriría, solo hará la vida más difícil en otras áreas, por ejemplo, los informes. El formato que he proporcionado cubre todas las direcciones en nuestra base de datos logística que cubre EE.UU., Canadá, México y el Reino Unido sin ningún problema. También cubre todas nuestras direcciones europeas, chinas, japonesas y malasias. No puedo hablar por otros países, pero aún no he tenido que almacenar una dirección de un país que estos campos no admitirán.

No sugiero ir con la Dirección1, Address2, Address3 formato sugerido por otros y visto en muchas bases de datos porque el análisis de la información de la dirección de una cadena alfanumérica no es tan simple como podría parecer al principio-especialmente si los datos no se introducen correctamente, debido a la información errónea, error tipográfico, errores ortográficos, etc. Si separa sus campos, puede usar algoritmos de distancia para verificar el significado probable, usar probabilidad para verificar el nombre de la calle contra el código postal y el número de la calle o para verificar la provincia y la ciudad contra el nombre de la calle, etc. Tratar hacer algo de eso cuando tienes una cadena que denota toda tu dirección. No es un asunto trivial por cualquier tramo de la imaginación.

QA en una base de datos de direcciones es un dolor de cabeza, punto. La forma más fácil de simplificar su vida en esta área es asegurarse de que todos los campos contengan solo una sola pieza de información que pueda verificarse automáticamente como correcta a la hora de entrada. Los algoritmos de probabilidad, distancia y expresiones regulares pueden verificar la validez de la entrada y proporcionar retroalimentación a el usuario en cuanto a cuál fue su error y sugerir correcciones adecuadas.

Una advertencia a tener en cuenta es las carreteras con nombres que también son tipos de calles: si está cubriendo Canadá, debe estar al tanto de "Avenue Road" en Toronto, que lo hará tropezar a lo grande si usa el formato de Dirección1, 2, 3. Esto probablemente ocurre en otros lugares también, aunque no soy consciente de ellos - esta sola instancia fue suficiente para mí gritar WTF?!

 77
Author: BenAlabaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-02 16:17:06

Tenga cuidado de no sobre-analizar los formatos de direcciones. Cuando lo haga, es muy probable que termine con una especificación que la mayoría de los usuarios necesitarán trabajar alrededor de, forzándolos efectivamente a usar los campos incorrectos, o solo llenando los campos primarios e ignorando los campos adicionales.

Mantén las cosas simples.

Un StreetType como el mencionado por BenAlabaster causará problemas cuando comience a trabajar con idiomas diferentes de los idiomas de aislamiento como el inglés o el español.

Para mostrarte lo mal que se pueden poner las cosas en la naturaleza: la "Henriette Roland Holststraat" en Ámsterdam, construida a partir de "Henriette" + "Roland Holst" + "straat", que se puede abreviar como "Roland Holststraat", o "Roland Holststr.", o mal escrito como " H. R. Holststr."o "Henriette Roland-Holst straat", dependiendo del clima. A menos que tengas un registro callejero actualizado para cada país de la tierra, no irás a ninguna parte.

Y finalmente, tenga cuidado de que en algunos idiomas países, los nombres pueden ser diferentes de un idioma a otro! Por ejemplo, en Bruselas, donde muchas calles tienen un francés y un nombre holandés: "Avenu du Port" y "Havenlaan", dependiendo del idioma preferido del destinatario. (Google Maps muestra ambos nombres alternativamente, solo para estar seguros.)

Puedes intentar idear todo tipo de trucos inteligentes aquí, pero ¿los representantes de ventas van a entender esto?

 19
Author: Ruben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 16:51:18

Eso depende de lo que quieras hacer con él.

Siempre me ha resultado más fácil usar direcciones para otros fines (como verificar los datos de USPS o obtener tarifas de envío de UPS/FEDEX) si están separadas.

Esto es lo que normalmente uso para las direcciones:

  • Línea de dirección 1
  • Dirección Línea 2
  • Dirección Línea 3
  • Ciudad
  • Región
  • Código postal
  • Condado
  • País

En Respuesta a la edición: Para la mayoría de las situaciones no veo el uso. La tabla I listada anteriormente tiene suficientes campos (y es lo suficientemente genérica) para las direcciones de la mayoría de los países.

 7
Author: Stephen Wrighton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-21 15:25:50

Dirección

Como un polo opuesto a la excelente respuesta que @BenAlabaster ha proporcionado, simplemente podrías tener:

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

Los diseños de formularios del lado del cliente pueden ser tan complejos como mejor le parezca (o usar una entrada de varias líneas donde el usuario puede escribir manualmente su dirección). Luego puede agregar los saltos de línea en la dirección cuando sea necesario.

País

Su tabla de países se vería de la siguiente manera:

country_code  VARCHAR(2)
country_name  VARCHAR(255)

Además, usted podría tener uno del siguiente:

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

Luego use las siguientes listas para diseñar su tabla de países:

 4
Author: rybo111,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:34

Aquí hay una anécdota para cualquiera que tropiece con esta pregunta:

Hablo como una persona que ha vivido y trabajado en muchos continentes (Europa, Asia, América del Norte). En mi experiencia, y la experiencia de las personas con las que trabajo, ha sido mucho más fácil para nosotros usar sistemas que hacen lo siguiente:

  1. Proporcione tres líneas en las que escribiré una dirección. Pasa estas tres líneas a tu servicio postal local mientras las escribo, literalmente. Déjame usar cualquier conjunto de caracteres I want; use UTF-8 o algo mejor.
  2. Si su sistema tiene requisitos comerciales que necesitan que especifique información particular ( como código postal, prefectura, estado, etc. ), pídelo por separado. Por requisitos de negocio, me refiero a cosas como análisis; estos bits de información no deben compartirse con su servicio postal local ( a menos que también haya escrito la misma información en una de las tres líneas del punto 1, arriba ).
  3. Tiene un menú desplegable que me pide que especifique la ubicación categórica de la dirección que proporcioné en las líneas del punto 1 anterior, tal vez País.
  4. Si debe analizar la información que proporciono en las líneas del Punto 1, use mi respuesta al punto 3 para seleccionar expresiones regulares. Ejecute esa expresión regular contra la información en el punto 1 para analizarla. Intente llenar los elementos de la interfaz de usuario del Punto 2 usando la salida de su expresión regular. Si corrijo esa información autocompletada use usa el hecho de que la cambié para mejorar tu expresión regular. Del mismo modo, en la medida de lo posible, dar me una oportunidad para revisar y corregir la salida de su expresión regular: nadie sabe mejor lo que pretendía comunicar que yo.

Los sistemas construidos así, creo, hacen mi vida más fácil. Particularmente cuando estoy enviando correo a un sistema postal sobre el cual su firma no tiene prácticamente ningún conocimiento interno funcional.

Si su empresa tiene conocimientos internos sobre determinados sistemas postales, utilice mi selección en el punto 3 para informar qué vista me muestra. Mucha gente sabe lo que el sistema postal de los Estados Unidos espera en el embalaje; si nos selecciono en el punto 3, siéntase libre de hacer que la vista se vea adecuada para una dirección de los Estados Unidos. Si selecciono un país del que su firma no sabe nada display muestre tres líneas genéricas y déjeme hacer el resto; no me obligue a usar ASCII.

Y seamos realistas aquí building construir una base de datos completa y enciclopédica de todos los sistemas postales globales ( públicos y privados ) es una tarea hercúlea en el mejor de los casos, si no imposible. Hay, por ejemplo, postales sistemas en los que solo el operador local de última milla sabe realmente dónde se encuentra una dirección. A veces ser capaz de pasar notas a ese transportista en el embalaje es extremadamente útil. Y mapear el conocimiento local de cada portador de casos perimetrales en su base de datos es, de hecho, una tarea imposible.

Pregúntale a Gödel. (Y luego pregúntese si está intentando usar un sistema axiomático para modelar un universo de discurso, más o menos algún tipo de aritmética como la teoría de conjuntos o el álgebra relacional. )
 2
Author: StudentsTea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-01 17:19:43

Comentario de la respuesta de Ben Alabaster: Para dar formato a las direcciones según el país, puede usar una tabla de formato que tenga el orden de las columnas para cada país como filas separadas.

  • Formato de dirección (CountryCode, FieldName, FieldOrder)

El orden de los campos se puede codificar para usar diseños de cuadrícula complejos también.

No tiene sentido separar las direcciones por país. Esto será caótico a medida que aumente el número de países y caerá en problemas si lo desea para encontrar todas las direcciones de say, un cliente internacional. Tener un tipo de dirección sugerido por Ben también podría conducir a ambigüedades cuando tiene una dirección que tiene un número de edificio y un número de apartamento. Podría estar en un complejo de apartamentos donde cada edificio tiene un nombre diferente. Esto es muy común en la India.

 1
Author: bkm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 08:42:26

Utilizo https://github.com/commerceguys/addressing biblioteca para formatear direcciones internacionales y utilizan estos elementos:

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

Esto no ayuda si quieres analizar la calle (nombre, número de casa,...).

Por cierto. si está buscando una lista de países multilenguaje: https://github.com/umpirsky/country-list

 1
Author: Harald Ernst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-22 15:53:03

La única manera es dividirlos en:

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

Dado que casi todos los países tienen su propio estándar para tener datos de direcciones, y cada país tiene un formato diferente de códigos postales.
Puedes tener una pequeña muestra de problemas en mi post de una pregunta similar.

Esto no debería tener sentido separar direcciones para cada país, ya que hay países donde tiene pocas convenciones de direcciones. Algunas convenciones populares incluyen no tener calles en pueblos pequeños, solo nombre y número de la aldea, mientras que las calles están en las direcciones de las ciudades más grandes. He aprendido que en la capital de Hungría – Budapest, hay pocas calles que tengan el mismo nombre (las distingues por el número de distrito de la ciudad), mientras que otras ciudades no tienen esas direcciones (alguien de Hungría puede confirmar si esto es cierto). Así que el número total de formatos de dirección será numer_de_países multiplicado por el número de formatos de dirección en este país Can Se puede hacer con diferentes tablas, pero será un trabajo horrible que hacer.

 0
Author: smok1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:33

Sé que este es un tema extremadamente antiguo que ya está contestado, pero pensé que también podría aportar mis dos centavos. Todo depende de los objetivos de tu proyecto y de cómo esperas que tus usuarios objetivo ingresen las direcciones. La sugerencia de Ben le permitirá analizar las direcciones con precisión, pero por otro lado podría hacer que el proceso de entrada de datos del usuario sea más largo (y posiblemente más frustrante). La sugerencia de Stephen Wrighton es más simple, y podría ser más fácil para los usuarios ingresar direcciones como resultado.

También he visto algunos modelos que simplemente tenían una columna de "Dirección" que capturaría un número de calle típico, tipo, nombre de calle, número de unidad / apartamento, etc. todo en una columna, manteniendo la ciudad, el país, la región, etc. dentro de otras columnas. Similar a Esteban modelo, excepto Ip1, Ip2, y Address3 todos consolidado en una sola columna.

Mi opinión es que los modelos más flexibles tienden a ser los que son menos restrictivos, dependiendo de su interpretación de flexible.

 0
Author: Shan Plourde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-08 13:31:09