Como os endereços geográficos internacionais devem ser armazenados em um banco de dados relacional?

StackOverflow https://stackoverflow.com/questions/1159756

  •  18-09-2019
  •  | 
  •  

Pergunta

Dada a tarefa de armazenar endereços geográficos internacionais em uma tabela relacional, qual é o esquema mais flexível? Cada parte do endereço deve ser dividida em seus próprios campos ou deve ser mais como texto gratuito?

Existe algum sentido em separar o endereço formatado de maneira diferente em diferentes tabelas? Por exemplo, tenha uma tabela para USAADDRESS, CanadianAddress, Ukaddress ...?

Foi útil?

Solução

Vou resumir meus pensamentos da minha postagem no blog - Uma lição no armazenamento de endereço.

No meu projeto atual [trabalho para uma empresa de logística] Estamos armazenando endereços internacionais. Eu fiz pesquisas sobre endereços em todo o mundo no design desta parte do banco de dados. Há muitos formatos diferentes. No mundo ocidental, tendemos a usar um formato bastante uniforme - algumas diferenças, mas elas são principalmente:

  • Número da rua - numérico
  • Casa ou nome de construção - [Varchar - No Reino Unido, algumas casas/edifícios são identificados por nome, não por número
  • Sufixo do número da rua Varchar, embora na maioria dos casos, Char (1) seria suficiente
    • A, B etc
  • Nome da rua Varchar
  • Tipo de rua Varchar ou int se você tiver uma mesa de rua StreetTypes
    • Até agora, encontrei 262 tipos únicos no mundo de língua inglesa, provavelmente há mais e não se esqueça de outros idiomas, ou seja, estrogada, rue etc.
  • Direção da rua Varchar (2)
    • N, e, s, w, ne, se, nw, sw
  • tipo de endereço Varchar ou int, se você tiver uma tabela de endereços
    • Caixa postal
    • Apartamento
    • Prédio
    • Piso
    • Escritório
    • Suíte
    • etc ...
  • Identificador de tipo de endereço Varchar
    • IE Número da caixa, número do apartamento, número do piso Lembre -se de números e escritórios do apartamento às vezes têm informações alfanuméricas - como 1A
  • Município local Varchar ou int se você tiver uma tabela de municípios
    • Por exemplo, se sua aldeia/vila aparecer no endereço antes da cidade.
  • Cidade Varchar ou int se você tiver uma tabela de cidades
  • Distrito governante Varchar ou int se você tiver uma tabela de distritos
    • Estado (EUA)
    • Província (Canadá)
    • Distrito Federal (México)
    • Condado (Reino Unido)
    • etc ...
  • Área postal Varchar
    • Zip (EUA)
    • Código postal (Canadá, México)
    • Código postal (Reino Unido)
  • País Varchar ou int se você tiver uma tabela de países

Isso parece cobrir a maioria dos países, mas a ordem dos campos pode ser exibida de maneira diferente. Você pode encontrar uma lista de formatos de exibição em http://www.bitboost.com/ref/international-address-formats.html#formats

Por exemplo, em muitos países, o código postal cai antes do nome da cidade e o número da rua cairá após o nome da rua. No Canadá, EUA e Reino Unido, o número da rua precede o nome da rua e o código postal (ou ZIP) vem após o nome da cidade.

Em resposta à sua pergunta sobre a separação dos endereços em diferentes países, eu não sugeriria, isso apenas tornará a vida mais difícil em outras áreas - por exemplo, relatórios. O formato que forneci abrange todos os endereços em nosso banco de dados de logística, que abrange EUA, Canadá, México e Reino Unido, sem problemas. Também abrange todos os nossos endereços europeus, chineses, japoneses e malaios. Não posso falar por outros países, mas ainda não tive que armazenar um endereço de um país que esses campos não apoiarão.

Eu não sugiro ir com o formato de endereço1, endereço2, endereço3 sugerido por outros e visto em muitos bancos de dados, porque a análise de informações sobre endereços de uma corda alfanumérica não é tão simples quanto parece primeiro - especialmente se os dados não forem inseridos corretamente , devido a desinformação, erro de digitação, erro de ortografia etc. Se você separar seus campos, poderá usar algoritmos de distância para verificar se há significado provável, use a probabilidade de verificar o nome da rua contra o código postal e o número da rua ou para verificar a província e a cidade contra o nome da rua etc. tente Fazendo nada disso quando você tem uma corda que denota todo o seu endereço de rua. Não é uma questão trivial em nenhum trecho da imaginação.

QA em um banco de dados de endereço é uma dor de cabeça, período. A maneira mais fácil de simplificar sua vida nessa área é garantir que todos os campos mantenham apenas uma única informação que possa ser automaticamente verificada como correta no horário de entrada. Probabilidade, algoritmos de distância e expressões regulares podem verificar a validade da entrada e fornecer feedback ao usuário sobre qual foi seu erro e sugerir correções adequadas.

Uma advertência a estar ciente é de estradas com nomes que também são tipos de rua - se você está cobrindo o Canadá, você precisa estar ciente de "Avenue Road" em Toronto, que o levará a muito tempo se você estiver usando o endereço1, 2 , 3 formato. Isso provavelmente também ocorre em outros lugares, embora eu não esteja ciente deles - essa única instância foi suficiente para eu gritar WTF?!

Outras dicas

Cuidado para não exagerar os formatos de endereço. Quando você o fizer, é provável que você acabe com uma especificação que a maioria dos usuários precisará trabalhar por aí, forçando -os efetivamente a usar os campos errados, ou apenas preencher os campos primários e ignorar os campos extras.

Mantenha as coisas simples.

Um streettype como mencionado por Benalabaster causará problemas quando você começar a trabalhar com idiomas diferentes de isolar idiomas como inglês ou espanhol.

Para mostrar como as coisas ruins podem ficar na natureza: o "Henriette Roland Holststraat" em Amsterdã, construído a partir de "Henriette" + "Roland Holst" + "Straat", que pode ser abreviado como o "Roland Holststraat", ou " Roland Holststr. ", Ou incorretamente como" Hrholststr ". ou "Henriette Roland-Holst Straat", dependendo do clima. A menos que você tenha um registro de rua atualizado para cada país da Terra, você não estará indo a lugar nenhum.

E, finalmente, tenha cuidado para que, em alguns países multilíngues, os nomes possam ser diferentes de um idioma para outro! Por exemplo, em Bruxelas, onde muitas ruas têm ambos os franceses e Um nome holandês: "Avenu du Port" e "Havenlaan", dependendo do idioma preferido do destinatário. (O Google Maps mostra os dois nomes alternadamente, apenas para estar do lado seguro.)

Você pode tentar criar todos os tipos de truques inteligentes aqui, mas são os representantes de vendas. vai entender isso?

Isso depende do que você quer fazer com isso.

Achei sempre mais fácil usar endereços para outros fins (como verificação contra dados do USPS ou obter taxas de envio da UPS/FedEx) se elas forem separadas.

Aqui está o que eu normalmente uso para endereços:

  • Endereço Linha 1
  • endereço linha 2
  • Linha de endereço 3
  • Cidade
  • Região
  • Código postal
  • Condado
  • País

Em resposta à edição: Para a maioria das situações, não vejo o uso. A tabela que listei acima tem campos suficientes (e é genérico o suficiente) para a maioria dos endereços do país.

Endereço

Como um oposto polar da excelente resposta @Benalabaster forneceu, você pode simplesmente ter:

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

Os layouts do formulário do lado do cliente ainda podem ser tão complexos quanto você achar adequado (ou usar uma entrada de várias linhas em que o usuário pode digitar manualmente seu endereço). Você pode adicionar as quebras de linha no endereço sempre que necessário.

País

Sua mesa de campo pareceria o seguinte:

country_code  VARCHAR(2)
country_name  VARCHAR(255)

Além disso, você poderia ter 1 da seguinte:

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

Em seguida, use as listas a seguir para projetar sua tabela de país:

Aqui está uma anedota para quem tropeça nessa pergunta:

Falo como uma pessoa que viveu e trabalhou em muitos continentes (Europa, Ásia, América do Norte). Na minha experiência e na experiência das pessoas com quem trabalho, foi muito mais fácil para nós usar sistemas que fazem o seguinte:

  1. Forneça três linhas nas quais digitarei um endereço. Passe essas três linhas para o seu serviço postal local enquanto eu as digito, literalmente. Deixe -me usar qualquer conjunto de personagens que eu queira; Use UTF-8 ou algo melhor.
  2. Se o seu sistema tiver requisitos de negócios que precisem que eu especifique informações específicas (como código postal, prefeitura, estado etc.), peça isso separadamente. Por requisitos de negócios, quero dizer coisas como análises; Esses bits de informação não devem ser compartilhados com o seu serviço postal local (a menos que eu também escreva as mesmas informações em uma das três linhas do ponto 1, acima).
  3. Tenha um suspensão que me pede para especificar o local categórico do endereço que forneci nas linhas do ponto 1 acima, talvez país.
  4. Se você deve analisar as informações que eu forneço nas linhas do ponto 1, use minha resposta ao ponto 3 para selecionar Regex. Execute essa regex contra as informações no ponto 1 para analisá -las. Tente preencher os elementos da interface do usuário do ponto 2 usando a saída da sua regex. Se eu corrigir as informações definidas automaticamente-use o fato de alterá-las para melhorar seu regex. Da mesma forma, o máximo possível, dê -me a oportunidade de revisar e corrigir a saída do seu regex: ninguém sabe melhor o que eu pretendia me comunicar do que eu.

Os sistemas construídos assim, acho, tornam minha vida mais fácil. Particularmente quando estou enviando e -mails para um sistema postal sobre o qual sua empresa praticamente não tem conhecimento interno funcional.

Se sua empresa tiver conhecimento interno sobre sistemas postais específicos, use minha seleção no ponto 3 para informar qual visão você exibe para mim. Muitas pessoas sabem o que o sistema postal dos EUA espera na embalagem; Se eu nos selecionar no ponto 3, sinta -se à vontade para fazer com que a visualização pareça apropriada para um endereço nos EUA. Se eu selecionar um país sobre o qual sua empresa não sabe nada-exiba três linhas genéricas e deixe-me fazer o resto; Não me force a usar ASCII.

E vamos ser reais aqui-construindo um banco de dados enciclopédico completo de todos os sistemas postais globais (público e privado) é uma tarefa hercúlea na melhor das hipóteses, se não impossível. Existem, por exemplo, sistemas postais nos quais apenas a transportadora local de última milha sabe realmente onde um endereço está localizado. Às vezes, ser capaz de passar anotações para essa transportadora na embalagem é extremamente útil. E mapear o conhecimento local de cada transportadora de casos de borda no seu banco de dados é realmente uma tarefa impossível.

Basta perguntar a Gödel. (E então pergunte a si mesmo se você está tentando usar um sistema axiomático para modelar um universo de discurso, dar ou tomar algum tipo de aritmética como teoria de conjuntos ou álgebra relacional.)

Comentário da resposta de Ben Alabaster: Para os endereços de formato com base no país, você pode usar uma tabela de formatação que tenha a ordem das colunas para cada país como linhas separadas.

  • Endereço Format (CountryCode, FieldName, FieldOrder)

A ordem de campo também pode ser codificada para usar layouts complexos de grade.

Não faz sentido separar endereços por país. Isso será caótico à medida que o número de países aumenta e você terá problemas se quiser encontrar todos os endereços de, digamos, um cliente internacional. Ter um tipo de endereço sugerido por Ben também pode levar a ambiguidades quando você tem um endereço que possui um número de construção e um número de apartamento. Eu poderia estar em um complexo de apartamentos onde cada edifício tem um nome diferente. Isso é muito comum na Índia.

eu uso https://github.com/commerceguys/addressing Biblioteca para formatar endereços internacionais e eles usam esses 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

Isso não ajuda se você quiser analisar a rua (nome, número da casa, ...).

Por falar nisso. Se você está procurando uma lista de países multilanguage: https://github.com/umpirsky/country-list

A única maneira é dividi -los para:

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

Como quase todos os países têm seu próprio padrão para ter dados de endereços, o evey país tem um formato diferente de código ZIPC.
Você pode ter uma pequena amostra de problemas em minha publicação de uma pergunta semelhante.

Isso não deve fazer sentido separar endereços para todos os países, uma vez que existem países em que você tem poucas convenções de endereços. Algumas convenções populares incluem não ter ruas em pequenas aldeias, apenas nome e número da vila, enquanto as ruas estão nos endereços das cidades maiores. Aprendi que, na capital da Hungria - Budapeste, existem poucas ruas com o mesmo nome (você as distinta pelo número distrital da cidade), enquanto outras cidades não têm esses endereços (alguém da Hungria pode realmente confirmar se isso é verdade). Portanto, o número total de formatos de endereço será numer_of_countries multiplicado pelo número de formatos de endereço neste país ... pode ser feito com tabelas diferentes, mas será um trabalho horrível a fazer.

Sei que este é um tópico extremamente antigo que já foi respondido, mas pensei que jogaria meus dois centavos também. Tudo depende do que os seus objetivos do seu projeto e de como você espera que seus usuários -alvo digitem endereços. A sugestão de Ben permitirá que você analise os endereços com precisão, mas, por outro lado, pode ser um processo de entrada de dados de usuário mais longo (e possivelmente mais frustrante). A sugestão de Stephen Wrighton é mais simples e pode ser mais fácil para os usuários inserir endereços como resultado.

Também vi alguns modelos que simplesmente tinham uma coluna de "endereço" que capturaria um número típico de rua, tipo, nome da rua, número de unidade / apartamento, etc. Tudo em uma coluna, mantendo a cidade, o país, a região, etc. Dentro de outras colunas. Semelhante ao modelo de Stephen, exceto endereço1, endereço2 e endereço3, todos consolidados em uma coluna.

Minha opinião é que os modelos mais flexíveis tendem a ser aqueles que são menos restritivos, dependendo da sua interpretação do flexível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top