Melhores práticas para armazenar endereços postais em um banco de dados (RDBMS)?

106

Existem boas referências de melhores práticas para armazenar endereços postais em um RDBMS? Parece que há muitas compensações que podem ser feitas e muitos prós e contras para cada um a ser avaliado - certamente isso já foi feito repetidas vezes? Talvez alguém tenha pelo menos escrito algumas lições aprendidas em algum lugar?

Exemplos das vantagens e desvantagens de que estou falando são armazenar o CEP como um número inteiro versus um campo char, se o número da casa for armazenado como um campo separado ou parte da linha de endereço 1, se os números de suíte / apartamento / etc forem normalizados ou apenas armazenados como um pedaço de texto na linha de endereço 2, como você lida com zip +4 (campos separados ou um campo grande, inteiro vs texto)? etc.

Estou principalmente preocupado com os endereços dos EUA neste momento, mas imagino que haja algumas práticas recomendadas em relação à preparação para a eventualidade de se tornar global também (por exemplo, nomear campos apropriadamente como região em vez de estado ou código postal em vez de código postal, etc.

John
fonte
3
Logo de início, o zip do morcego deve ser um campo char - caso contrário, alguns códigos postais que começam com 0 se tornariam imprecisos.
Menasheh
1
Como regra geral, quando você precisa fazer cálculos matemáticos com o número, ele deve ser inteiro. Se você apenas exibi-lo, deve ser char (telefone, CEP, etc.)
Zikato

Respostas:

37

Para um uso mais internacional, um esquema a ser considerado é o usado pelo Drupal Address Field . É baseado no padrão xNAL e parece cobrir a maioria dos casos internacionais. Um pouco de aprofundamento nesse módulo revelará algumas belas pérolas para interpretar e validar endereços internacionalmente. Ele também tem um bom conjunto de áreas administrativas (província, estado, oblast, etc) com códigos ISO.

Esta é a essência do esquema, copiado da página do módulo:

country => Country (always required, 2 character ISO code)
name_line => Full name (default name entry)
first_name => First name
last_name => Last name
organisation_name => Company
administrative_area => State / Province / Region (ISO code when available)
sub_administrative_area => County / District (unused)
locality => City / Town
dependent_locality => Dependent locality (unused)
postal_code => Postal code / ZIP Code
thoroughfare => Street address
premise => Apartment, Suite, Box number, etc.
sub_premise => Sub premise (unused)

Uma lição que aprendi:

  • Não armazene nada numericamente.
  • Armazene o país e a área administrativa como códigos ISO sempre que possível.
  • Quando você não sabe, seja negligente ao exigir campos. Alguns países podem não usar campos que você considera normais, mesmo coisas básicas como locality& thoroughfare.
Samm Cooper
fonte
1
Posso perguntar a que "name_line" se destina? Eu realmente não encontrei uma explicação no Drupal Docs ou no xNal Standard. Pelo que entendi o name_line é para o envio de cartas reais ou encomendas pelo correio. O first_name / last_name são necessários apenas se você quiser se dirigir ao cliente diretamente, por exemplo, por e-mail ("Prezado Senhor <last_name>"). Ou existe algum outro propósito / benefício nisso?
luba de
Ao entregar em instalações comerciais (grandes), muitas vezes é necessário um nome para o sistema interno de entrega de correspondência (considere edifícios de escritórios com salas de correspondência)
Chris Browne
O campo de endereço foi substituído por endereço . Parece que os campos podem ser um pouco diferentes
Gavin Haynes
24

Como um usuário 'internacional', não há nada mais frustrante do que lidar com um site voltado apenas para endereços no formato dos EUA. É um pouco rude no início, mas se torna um problema sério quando a validação também é excessivamente zelosa.

Se você está preocupado em se tornar global, o único conselho que tenho é para manter a forma livre. Diferentes países têm diferentes convenções - em alguns, o número da casa vem antes do nome da rua, em alguns, vem depois. Alguns têm estados, algumas regiões, alguns condados, algumas combinações desses. Aqui no Reino Unido, o código postal não é um código postal, é um código postal que contém letras e números.

Aconselharia simplesmente ~ 10 linhas de strings de comprimento variável, junto com um campo separado para um código postal (e seja cuidadoso como você descreve isso para lidar com as sensibilidades nacionais). Deixe o usuário / cliente decidir como escrever seus endereços.

Andrew Ferrier
fonte
Pelo que vale a pena, não se trata de um site, mas a questão sobre endereços internacionais ainda é bem interpretada.
João
47
Embora eu não discorde da mensagem e, na verdade, aplaudo pela postura que você assume, tive que votar contra você porque abomino o fato de ser alguém que passa a maior parte do meu tempo escrevendo ferramentas para limpar dados de endereço de armazenamento de dados de endereço em um formato de formato livre. Os endereços podem ser formatados de maneira diferente, mas os dados ainda são praticamente os mesmos. O fato de um número de rua ser exibido antes ou depois do nome da rua é irrelevante para fins de armazenamento - apenas para fins de exibição.
BenAlabaster
17

Definitivamente, você deve considerar armazenar o número da casa como um campo de caractere em vez de um número, por causa de casos especiais como "meios-números" ou meu endereço atual, que é algo como "129A" ​​- mas o A não é considerado um apartamento número para serviços de entrega.

Paul Fisher
fonte
11

Eu fiz isso (modelar estruturas de endereço rigorosamente em um banco de dados) e nunca faria isso novamente. Você não pode imaginar como são loucas as exceções que você terá que levar em consideração como regra.

Lembro-me vagamente de algum problema com os códigos postais noruegueses (eu acho), que eram todas as 4 posições, exceto Oslo, que tinha 18 ou mais.

Tenho certeza absoluta de que, a partir do momento em que começamos a usar os CEPs geograficamente corretos para todos os nossos endereços nacionais, algumas pessoas começaram a reclamar de que suas correspondências chegaram tarde demais. Acontece que essas pessoas viviam perto de uma fronteira entre áreas postais e, apesar do fato de alguém realmente viver na área postal, digamos, 1600, na realidade sua correspondência deveria ser enviada para a área postal 1610, porque na realidade era aquela área postal vizinha que realmente o serviu, então enviar sua correspondência para a área postal correta demoraria alguns dias a mais para chegar, por causa da intervenção indesejada que foi necessária na estação postal correta para encaminhá-la para a área postal incorreta ...

(Acabamos cadastrando aquelas pessoas com endereço no exterior no país com o código ISO 'ZZ'.)


fonte
8

Você certamente deve consultar " Esta é uma boa maneira de modelar informações de endereço em um banco de dados relacional ", mas sua pergunta não é uma duplicata direta disso.

Certamente há muitas respostas pré-existentes (verifique os exemplos de modelos de dados em DatabaseAnswers , por exemplo). Muitas das respostas pré-existentes são defeituosas em algumas circunstâncias (não escolhendo respostas do banco de dados de forma alguma).

Uma questão importante a considerar é o escopo dos endereços. Se o seu banco de dados deve lidar com endereços internacionais, você deve ser mais flexível do que se só tivesse que lidar com endereços em um país.

Na minha opinião, é frequentemente (o que não significa sempre ) sensato registar a 'imagem da etiqueta de endereço' do endereço e analisar separadamente o conteúdo. Isso permite que você lide com as diferenças entre a colocação de códigos postais, por exemplo, entre diferentes países. Claro, você pode escrever um analisador e um formatador que lida com as excentricidades de diferentes países (por exemplo, os endereços dos EUA têm 2 ou 3 linhas; em contraste, os endereços britânicos podem ter consideravelmente mais; um endereço para o qual escrevo periodicamente tem 9 linhas). Mas pode ser mais fácil fazer com que os humanos façam a análise e a formatação e deixar o DBMS apenas armazenar os dados.

Jonathan Leffler
fonte
7

A menos que você vá fazer matemática sobre os números das ruas ou códigos postais / postais, você está apenas convidando a dor futura ao armazená-los como números.

Você pode economizar alguns bytes aqui e ali, e talvez obter um índice mais rápido, mas o que você faz quando a US postal, ou qualquer outro país com o qual você está lidando, decide a introdução de alfas nos códigos?

O custo do espaço em disco vai ser muito mais barato do que o custo de consertá-lo mais tarde ... y2k, alguém?

Seanb
fonte
7

Adicionando ao que @ Jonathan Leffler e @ Paul Fisher disseram

Se você já previu a adição de endereços postais do Canadá ou do México aos seus requisitos, o armazenamento postal-codecomo string é obrigatório. O Canadá tem códigos postais alfanuméricos e não me lembro como eram os do México na minha cabeça.

Ken Gentil
fonte
7

Eu descobri que listar todos os campos possíveis, da menor unidade discreta à maior, é a maneira mais fácil. Os usuários preencherão os campos que considerarem adequados. Minha tabela de endereços é parecida com esta:

*********************************
  Field              Type
*********************************
  address_id (PK)    int
  unit               string
  building           string        
  street             string
  city               string
  region             string
  country            string
  address_code       string
*********************************
Gaz_Edge
fonte
Como você armazena caixas postais?
Jowen de
basta adicionar outra coluna PO_box Se você tiver que fazer isso retrospectivamente, isso significa que nenhum dos endereços anteriores precisava de uma caixa postal, então pode ser definido como nulo
Gaz_Edge
2

Onde está a "troca" em armazenar o ZIP como um NÚMERO ou VARCHAR? Isso é apenas uma escolha - não é uma troca, a menos que haja benefícios para ambos e você tenha que abrir mão de alguns benefícios para obter outros.

A menos que a soma dos zips tenha algum significado, Zips como número não é útil.


fonte
Uma compensação pode ser o tamanho do banco de dados. No mysql 5, uma linha mediumint levaria apenas 3 bytes por linha, enquanto um varchar (5) levaria o dobro. Também pensei que as pesquisas numéricas eram mais rápidas do que as de texto, mas não tenho certeza disso.
gpojd
4
deve-se usar um varchar. O código postal canadense usa uma codificação alfanumérica, que não caberia bem em um número.
EvilTeach
1
Embora eu compreenda a lógica "compatível com versões futuras" por trás do uso de varchar neste sentido, a afirmação de que "zips como número não é útil" é um pouco dogmática. Se você sabe que vai trabalhar com CEPs apenas dos EUA, faz sentido armazenar CEPs como inteiros, assim como ao escrever em uma linguagem estritamente digitada, você não define tudo como tipo String ... Se você Sei que vai ser um número, por que não apoiar-se na verificação de tipo do banco de dados / linguagem de programação e chamá-la como ela é - um inteiro?
rinogo
1
@rinogo um argumento para usar varchar é que os códigos postais não são numéricos no sentido matemático; não faz sentido fazer adição ou subtração neles; eles são simplesmente codificados com um conjunto de caracteres restrito. stackoverflow.com/a/893489/48659
Steve Folly,
1
@SteveFolly E no suporte adicional de códigos postais como strings, os caracteres iniciais têm um significado especial: en.wikipedia.org/wiki/ZIP_Code#Primary_state_prefixes Se alguém vai implementar uma lógica como "quais são os caracteres mais à esquerda do valor ? " então isso soa mais como uma string do que um inteiro.
David Aldridge
2

Isso pode ser um exagero, mas se você precisar de uma solução que funcione com vários países e precisar processar programaticamente partes do endereço:

você poderia ter tratamento de endereço específico de país usando duas tabelas: uma tabela genérica com 10 colunas VARCHAR2, 10 colunas de número, outra tabela que mapeia esses campos para prompts e tem uma coluna de país que vincula uma estrutura de endereço a um país.

Shanmu
fonte
Na verdade, eu mesmo considerei isso. Além de, ou talvez em vez de uma tabela que mapeia colunas para prompts com base no país, eu estava pensando em criar visualizações atualizáveis ​​para cada formato de endereço específico. Ainda não puxei o gatilho, mas pensei nisso.
Andrew Steitz
1

Se alguma vez você tiver que verificar um endereço ou usá-lo para processar pagamentos com cartão de crédito, precisará de pelo menos um pouco de estrutura. Um bloco de texto de formato livre não funciona muito bem para isso.

O código postal é um campo opcional comum para validar transações de cartão de pagamento sem usar o endereço completo. Portanto, tenha um campo separado e de tamanho generoso para isso (pelo menos 10 caracteres).

Ted Bigham
fonte
-1

Gostaria apenas de colocar todos os campos juntos em um grande campo NVARCHAR (1000), com um elemento textarea para o usuário inserir o valor (a menos que você queira realizar análises em, por exemplo, códigos postais). Todas essas entradas de linha de endereço 1, linha de endereço 2, etc. são muito irritantes se você tiver um endereço que não se encaixa bem nesse formato (e, você sabe, há outros países além dos EUA).

Erikkallen
fonte
3
Que ideia horrível! Não há espaço suficiente em um "Comentário" para descrever o pesadelo que isso suscita. Melhor gastar um pouco mais de tempo projetando-o adequadamente do que tentar desemaranhar a bagunça depois. Veja a resposta de Samm Cooper. Acho que apenas votei contra uma outra resposta aqui no SO, mas esta definitivamente ganhou um voto negativo meu.
Andrew Steitz
Qual bagunça? Para que você precisa dos dados? Freqüentemente, você só precisa passá-lo diretamente para alguma impressora de etiquetas ou similar e, então, pode tratá-lo apenas como uma bolha de texto. Outras vezes, você pode se preocupar com cidades e códigos postais (mas é melhor certificar-se de que só tem clientes em países com suporte)
erikkallen
2
OP não mencionou "só preciso passar para uma impressora de etiquetas" e em todos os trabalhos que já tive usamos o endereço como "dados", executando relatórios, recolhendo impostos (imposto sobre vendas do Colorado para eletrodomésticos sendo colocados em uma nova casa variam de um lado a outro da rua), atribuindo leads aos vendedores, atendendo aos requisitos de conformidade do governo, a lista é infinita. "Destruir" dados (misturando itens distintos em um campo ou não capturando dados disponíveis) é um "pecado" em meu livro e sempre provou ser o pesadelo sobre o qual alertei quando as pessoas me ignoraram.
Andrew Steitz
Se você descobrir mais tarde que não precisa de um dado, você sempre pode "destruí-lo" mais tarde. A "criação" de dados varia de pesadelo (divisão de informações em campos separados) a impossível (captura de dados após o fato). Se o OP tivesse dito "só preciso enviar para a impressora de etiquetas", eu teria aplaudido e votado positivamente em sua resposta. No entanto, sem uma menção específica a algo assim, uma sugestão de "destruir" dados, IMO, está à beira de ser irresponsável ou mesmo maldoso.
Andrew Steitz
Onde já trabalhei (principalmente e-commerce), tendemos a armazená-lo em 5 a 6 campos diferentes, mas nunca, jamais, fazemos nada com as informações a não ser usá-las para enviar para entrega.
erikkallen