web-dev-qa-db-fra.com

Comment stocker les adresses géographiques internationales dans une base de données relationnelle?

Compte tenu de la tâche de stockage des adresses géographiques internationales dans une table relationnelle, quel est le schéma le plus flexible? Chaque partie de l'adresse doit-elle être divisée en ses propres champs, ou doit-elle ressembler davantage à du texte libre?

Y a-t-il un sens à séparer des adresses formatées différemment en différents tableaux? Par exemple, avez une table pour USAAddress, CanadianAddress, UKAddress ...?

55
Bob

Je vais résumer mes réflexions à partir de mon blog - ne leçon sur le stockage d'adresses .

Sur mon projet actuel [je travaille pour une entreprise de logistique], nous stockons des adresses internationales. J'ai fait des recherches sur des adresses partout dans le monde dans la conception de cette partie de la base de données. Il existe de nombreux formats différents. Dans le monde occidental, nous avons tendance à utiliser un format assez uniforme - quelques différences mais elles sont principalement:

  • Numéro de rue - Numérique
  • Nom de la maison ou du bâtiment - [VarChar - au Royaume-Uni, certaines maisons/bâtiments sont identifiés par leur nom et non par leur numéro]
  • Suffixe du numéro de rue [VarChar, bien que dans la plupart des cas, Char (1) suffise]
    • A, B etc.
  • Nom de la rue [VarChar]
  • Type de rue [VarChar ou Int si vous avez une table StreetTypes]
    • Jusqu'à présent, j'ai trouvé 262 types uniques dans le monde anglophone, il y en a probablement plus, et n'oubliez pas d'autres langues, c'est-à-dire Strasse, Rue, etc.
  • Direction de la rue [VarChar (2)]
    • N, E, S, W, NE, SE, NW, SW
  • Type d'adresse [VarChar ou Int si vous avez une table AddressTypes]
    • Boîte postale
    • Appartement
    • Bâtiment
    • Sol
    • Bureau
    • Suite
    • etc...
  • Identificateur du type d'adresse [VarChar]
    • c'est-à-dire le numéro de boîte, le numéro d'appartement, le numéro d'étage, souvenez-vous que les numéros d'appartement et les bureaux ont parfois des informations alphanumériques - comme 1A
  • Municipalité locale [VarChar ou Int si vous avez une table Municipalités]
    • Par exemple, si votre hameau/village apparaît dans l'adresse avant la ville.
  • Ville/Ville [VarChar ou Int si vous avez une table Cities]
  • District directeur [VarChar ou Int si vous avez une table Districts]
    • État (États-Unis)
    • Province (Canada)
    • District fédéral (Mexique)
    • Comté (U.K.)
    • etc...
  • Zone postale [VarChar]
    • Zip (États-Unis)
    • Code postal (Canada, Mexique)
    • Code postal (Royaume-Uni)
  • Pays [VarChar ou Int si vous avez une table Pays]

Cela semble couvrir la plupart des pays, mais l'ordre des champs peut être affiché différemment. Vous pouvez trouver une liste des formats d'affichage sur http://www.bitboost.com/ref/international-address-formats.html#Formats

Par exemple, dans de nombreux pays, le code postal tombe avant le nom de la ville et le numéro de rue tombe après le nom de la rue. Au Canada, aux États-Unis et au Royaume-Uni, le numéro de rue précède le nom de la rue et le code postal (ou Zip) vient après le nom de la ville.

En réponse à votre question sur la séparation des adresses dans différents pays, je ne le suggérerais pas, cela rendra la vie plus difficile dans d'autres domaines - par exemple, les rapports. Le format que j'ai fourni couvre toutes les adresses de notre base de données logistique qui couvre les États-Unis, le Canada, le Mexique et le Royaume-Uni sans aucun problème. Il couvre également toutes nos adresses européennes, chinoises, japonaises et malaisiennes. Je ne peux pas parler pour d'autres pays, mais je n'ai pas encore eu à enregistrer une adresse d'un pays que ces champs ne prennent pas en charge.

Je ne suggère pas d'utiliser le format Address1, Address2, Address3 suggéré par d'autres et vu dans de nombreuses bases de données, car l'analyse des informations d'adresse à partir d'une chaîne alphanumérique n'est pas aussi simple que cela puisse paraître à première vue, surtout si les données ne sont pas entrées correctement , en raison de la désinformation, de la faute de frappe, de l'orthographe, etc. Si vous séparez vos champs, vous pouvez utiliser des algorithmes de distance pour vérifier la signification probable, utilisez la probabilité pour comparer le nom de la rue par rapport au code postal et au numéro de rue ou pour vérifier la province et la ville par rapport au nom de la rue, etc. Essayez faire tout cela lorsque vous avez une chaîne indiquant votre adresse complète. Ce n'est pas une question banale par un effort d'imagination.

L'assurance qualité sur une base de données d'adresses est un casse-tête, point final. Le moyen le plus simple de vous simplifier la vie dans ce domaine est de vous assurer que tous les champs ne contiennent qu'une seule information pouvant être automatiquement vérifiée comme correcte au moment de la saisie. La probabilité, les algorithmes de distance et les expressions régulières peuvent vérifier la validité de la saisie et fournir à l'utilisateur des informations sur son erreur et suggérer des corrections appropriées.

Une mise en garde à connaître est les routes avec des noms qui sont également des types de rues - si vous couvrez le Canada, vous devez être au courant de "Avenue Road" à Toronto qui vous fera trébucher si vous utilisez l'Adresse1, 2 , 3 format. Cela se produit probablement dans d'autres endroits aussi, bien que je ne les connaisse pas - cette seule instance m'a suffi pour crier WTF?!

88
BenAlabaster

Faites attention à ne pas sur-analyser les formats d'adresse. Lorsque vous le faites, vous risquez de vous retrouver avec une spécification que la plupart des utilisateurs devront contourner , les forçant ainsi à utiliser les mauvais champs, ou en remplissant uniquement les champs principaux et en ignorant les champs supplémentaires.

Gardez les choses simples.

Un StreetType comme mentionné par BenAlabaster causera des problèmes lorsque vous commencerez à travailler avec des langues différentes des langues isolantes comme l'anglais ou l'espagnol.

Pour vous montrer à quel point les choses peuvent mal se passer dans la nature: la "Henriette Roland Holststraat" à Amsterdam, construite à partir de "Henriette" + "Roland Holst" + "straat", qui peut être abrégée en "Roland Holststraat", ou " Roland Holststr. ", Ou mal orthographié" HRHolststr. " ou "Henriette Roland-Holst straat", selon la météo. À moins d'avoir un registre des rues à jour pour chaque pays sur terre, vous n'irez nulle part.

Et enfin, faites attention à ce que dans certains pays multilingues, les noms puissent être différents d'une langue à l'autre! Par exemple à Bruxelles, où de nombreuses rues ont à la fois un nom français et un nom néerlandais: "Avenu du Port" et "Havenlaan", selon la langue préférée du destinataire. (Google Maps affiche les deux noms en alternance, juste pour être sûr.)

Vous pouvez essayer de concevoir toutes sortes de trucs astucieux ici, mais ce sont les représentants des ventes. va comprendre ça?

20
Ruben

Cela dépend de ce que vous voulez en faire.

J'ai trouvé qu'il était toujours plus facile d'utiliser des adresses à d'autres fins (telles que la vérification par rapport aux données USPS ou l'obtention des tarifs d'expédition d'UPS/FEDEX) si elles étaient séparées.

Voici ce que j'utilise généralement pour les adresses:

  • Adresse 1
  • Adresse Ligne 2
  • Ligne d'adresse 3
  • Ville
  • Région
  • Code postal
  • Comté
  • Pays

En réponse à l'édition: Pour la plupart des situations, je ne vois pas l'utilité. Le tableau que j'ai énuméré ci-dessus contient suffisamment de champs (et est suffisamment générique) pour la plupart des adresses de pays.

8
Stephen Wrighton

Adresse

Contrairement à l'excellente réponse fournie par @BenAlabaster, vous pourriez simplement avoir:

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

Vos dispositions de formulaire côté client peuvent toujours être aussi complexes que vous le souhaitez (ou utilisez une entrée sur plusieurs lignes où l'utilisateur peut saisir manuellement son adresse). Vous pouvez ensuite ajouter les sauts de ligne dans l'adresse si nécessaire.

Pays

Votre tableau de pays se présenterait comme suit:

country_code  VARCHAR(2)
country_name  VARCHAR(255)

De plus, vous pouvez avoir un des éléments suivants:

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

Utilisez ensuite les listes suivantes pour concevoir votre tableau de pays:

6
rybo111

Voici une anecdote pour quiconque bute sur cette question:

Je parle en tant que personne qui a vécu et travaillé sur de nombreux continents (Europe, Asie, Amérique du Nord). D'après mon expérience et celle des gens avec qui je travaille, il nous a été beaucoup plus facile d'utiliser des systèmes qui font ce qui suit:

  1. Fournissez trois lignes dans lesquelles je vais taper une adresse. Transmettez ces trois lignes à votre service postal local au fur et à mesure que je les tape, textuellement. Permettez-moi d'utiliser n'importe quel jeu de caractères que je veux; utilisez UTF-8 ou quelque chose de mieux.
  2. Si votre système a des exigences commerciales qui nécessitent que je spécifie des informations particulières (telles que le code postal, la préfecture, l'état, etc.), demandez-le séparément. Par exigences commerciales, je veux dire des choses comme l'analyse; ces informations ne doivent pas être partagées avec votre service postal local (sauf s'il m'est également arrivé d'écrire les mêmes informations sur l'une des trois lignes du point 1 ci-dessus).
  3. Avoir une liste déroulante qui me demande de spécifier l'emplacement catégorique de l'adresse que j'ai fournie dans les lignes du point 1 ci-dessus, peut-être Pays.
  4. Si vous devez analyser les informations que je fournis dans les lignes du point 1, utilisez ma réponse au point 3 pour sélectionner l'expression régulière. Exécutez cette expression régulière par rapport aux informations du point 1 pour l'analyser. Essayez de remplir les éléments de l'interface utilisateur du point 2 en utilisant la sortie de votre expression régulière. Si je corrige ces informations remplies automatiquement, utilisez le fait que je les ai modifiées pour améliorer votre expression régulière. De même, autant que possible, donnez-moi l'occasion de revoir et de corriger la sortie de votre regex: personne ne sait mieux que moi ce que j'avais l'intention de communiquer.

Les systèmes construits comme ça, je trouve, me facilitent la vie. En particulier lorsque j'envoie du courrier à un système postal sur lequel votre entreprise n'a pratiquement aucune connaissance fonctionnelle interne.

Si votre entreprise possède des connaissances internes sur des systèmes postaux particuliers, utilisez ma sélection au point 3 pour indiquer la vue que vous affichez. Beaucoup de gens savent ce que le système postal américain attend des emballages; si je sélectionne US au point 3, n'hésitez pas à rendre la vue appropriée pour une adresse américaine. Si je sélectionne un pays dont votre entreprise ne sait rien - affichez trois lignes génériques et laissez-moi faire le reste; ne me force pas à utiliser ASCII.

Et soyons réalistes ici - la construction d'une base de données encyclopédique complète de tous les systèmes postaux mondiaux (publics et privés) est au mieux une tâche herculéenne, sinon impossible. Il existe, par exemple, des systèmes postaux dans lesquels seul le transporteur local du dernier kilomètre sait vraiment où se trouve une adresse. Parfois, être en mesure de transmettre des notes à ce transporteur sur l'emballage est extrêmement utile. Et mapper les connaissances locales de chaque support de cas Edge dans votre base de données est en effet une tâche impossible.

Demandez à Gödel. (Et puis demandez-vous si vous essayez d'utiliser un système axiomatique pour modéliser un univers de discours, donner ou prendre une sorte d'arithmétique comme la théorie des ensembles ou l'algèbre relationnelle.)

3
StudentsTea

Commentaire de la réponse de Ben Alabaster: Pour formater les adresses en fonction du pays, vous pouvez utiliser un tableau de mise en forme qui présente l'ordre des colonnes pour chaque pays sur des lignes distinctes.

  • AddressFormat (CountryCode, FieldName, FieldOrder)

L'ordre des champs peut être codé pour utiliser également des dispositions de grille complexes.

Il ne sert à rien de séparer les adresses par pays. Ce sera chaotique car le nombre de pays augmente et vous atterrirez des ennuis si vous voulez trouver toutes les adresses de disons, un client international. Avoir un type d'adresse suggéré par Ben pourrait également entraîner des ambiguïtés lorsque vous avez une adresse qui a à la fois un numéro de bâtiment et un numéro d'appartement. Je pourrais être dans un complexe d'appartements où chaque immeuble a un nom différent. C'est très courant en Inde.

1
bkm

J'utilise https://github.com/commerceguys/addressing bibliothèque pour formater des adresses internationales et ils utilisent ces éléments:

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

Cela n'aide pas si vous voulez analyser la rue (nom, numéro de maison, ...).

Btw. si vous recherchez une liste de pays multilingue: https://github.com/umpirsky/country-list

1
Harald Ernst

La seule façon est de les diviser en:

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

puisque presque chaque pays a sa propre norme pour avoir des données d'adresse, et chaque pays a un format différent de codes postaux.
Vous pouvez avoir un petit échantillon de problèmes dans mon message à partir d'une question similaire.

Cela ne devrait pas avoir de sens de séparer les adresses pour chaque pays, car il existe des pays où vous avez peu de conventions d'adresse. Certaines conventions populaires incluent l’absence de rues dans les petits villages, uniquement le nom et le numéro du village, tandis que les rues se trouvent dans les adresses des grandes villes. J'ai appris que dans la capitale hongroise - Budapest, il y a peu de rues ayant le même nom (vous les distinguez par le numéro de quartier de la ville), tandis que d'autres villes n'ont pas de telles adresses (un Hongrois peut en fait confirmer si c'est vrai). Ainsi, le nombre total de formats d'adresse sera multiplié par nombre de pays par le nombre de formats d'adresse dans ce pays… Cela peut être fait avec différentes tables, mais ce sera un travail horrible à faire.

0
smok1

Je sais que c'est un sujet extrêmement ancien auquel on a déjà répondu, mais je pensais que je mettrais aussi mes deux cents. Tout dépend des objectifs de votre projet et de la façon dont vous vous attendez à ce que vos utilisateurs cibles entrent des adresses. La suggestion de Ben vous permettra d'analyser les adresses avec précision, mais d'un autre côté, cela pourrait rendre le processus de saisie des données utilisateur plus long (et peut-être plus frustrant). La suggestion de Stephen Wrighton est plus simple, et il pourrait être plus facile pour les utilisateurs d'entrer des adresses en conséquence.

J'ai également vu certains modèles qui avaient simplement une colonne "Adresse" qui capturerait un numéro de rue, un type, un nom de rue, un numéro d'unité/appartement, etc. dans une seule colonne, tout en conservant la ville, le pays, la région, etc. dans d'autres colonnes. Semblable au modèle de Stephen, sauf Address1, Address2 et Address3 tous regroupés en une seule colonne.

Mon opinion est que les modèles les plus flexibles ont tendance à être ceux qui sont les moins restrictifs, selon votre interprétation de la flexibilité.

0
Shan Plourde