101 votes

Existe-t-il une norme pour stocker des numéros de téléphone normalisés dans une base de données ?

Quelle est une bonne structure de données pour stocker des numéros de téléphone dans des champs de base de données ? Je cherche quelque chose qui soit suffisamment souple pour gérer les numéros internationaux et qui permette d'interroger efficacement les différentes parties du numéro.

Editar: Juste pour clarifier le cas d'utilisation ici : Je stocke actuellement les numéros dans un champ varchar unique, et je les laisse tels que le client les a saisis. Ensuite, lorsque le numéro est requis par le code, je le normalise. Le problème est que si je veux interroger quelques millions de lignes pour trouver les numéros de téléphone qui correspondent, cela implique une fonction, par exemple

where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)

ce qui est terriblement inefficace. De même, les requêtes qui recherchent des éléments tels que l'indicatif régional deviennent extrêmement délicates lorsqu'il ne s'agit que d'un seul champ de type varchar.

[Edit]

Les gens ont fait beaucoup de bonnes suggestions ici, merci ! Voici ce que je fais maintenant : Je stocke toujours les numéros exactement tels qu'ils ont été saisis, dans un champ varchar, mais au lieu de normaliser les choses au moment de la requête, j'ai un déclencheur qui fait tout ce travail lorsque les enregistrements sont insérés ou mis à jour. J'ai donc des ints ou des bigints pour toutes les parties que je dois interroger, et ces champs sont indexés pour accélérer l'exécution des requêtes.

0 votes

Une réponse contemporaine à cette question se trouve ici - stackoverflow.com/a/51761170/968003 . L'essentiel est d'utiliser la RFC 3966 pour le stockage et libphonenumber pour l'analyse/validation.

82voto

Adam Davis Points 47683

Tout d'abord, au-delà du code pays, il n'existe pas de véritable norme. Le mieux que vous puissiez faire est de reconnaître, grâce à l'indicatif du pays, à quelle nation appartient un numéro de téléphone particulier et de traiter le reste du numéro selon le format de cette nation.

En général, cependant, les équipements téléphoniques et autres sont normalisés, de sorte que vous pouvez presque toujours décomposer un numéro de téléphone donné en éléments suivants

  • C Code pays 1-10 chiffres (actuellement 4 ou moins, mais cela peut changer)
  • Un code régional (province/état/région) de 0 à 10 chiffres (il est possible de vouloir un champ région et un champ zone séparément, plutôt qu'un seul code régional).
  • E Code d'échange (préfixe ou commutateur) 0-10 chiffres
  • L Numéro de ligne 1-10 chiffres

Avec cette méthode, vous pouvez potentiellement séparer les numéros de telle sorte que vous pouvez trouver, par exemple, des personnes qui pourraient être proches les unes des autres parce qu'elles ont le même pays, la même région et les mêmes codes d'échange. Avec les téléphones portables, vous ne pouvez plus compter sur cette méthode.

En outre, les normes varient d'un pays à l'autre. Vous pouvez toujours compter sur un (AAA) EEE-LLLL aux Etats-Unis, mais dans un autre pays, vous pouvez avoir des centraux dans les villes (AAA) EE-LLL, et simplement des numéros de ligne dans les zones rurales (AAA) LLLL. Vous devrez commencer au sommet d'un arbre quelconque et les formater en fonction des informations dont vous disposez. Par exemple, le code pays 0 a un format connu pour le reste du numéro, mais pour le code pays 5432, vous devrez peut-être examiner l'indicatif régional avant de comprendre le reste du numéro.

Vous pouvez également vous occuper vanity des chiffres tels que (800) Lucky-Guy Pour cela, il faut reconnaître que, s'il s'agit d'un numéro américain, il y a un chiffre de trop (et il se peut que vous ayez besoin d'une représentation complète à des fins publicitaires ou autres) et qu'aux États-Unis, les lettres ne correspondent pas aux chiffres de la même manière qu'en Allemagne.

Vous pouvez également stocker le numéro entier séparément dans un champ de texte (avec internationalisation) afin de pouvoir revenir plus tard et réorganiser les numéros si les choses changent, ou comme sauvegarde au cas où quelqu'un soumettrait une mauvaise méthode pour analyser le format d'un pays particulier et perdrait des informations.

1 votes

Connaissez-vous une bonne validation JavaScript pour essayer de valider ceci ?

6 votes

E164 fixe des limites beaucoup plus strictes sur la longueur des nombres : 1-3 pour les pays, et une longueur maximale de 15. Cela ne changera pas de sitôt, connaissant le système mondial de téléphonie.

0 votes

Les longueurs que vous avez spécifiées semblent être, selon la norme ITU-T E.164, complètement erronées. Il serait utile de publier un lien vers le document de normes d'où vous tirez vos informations, ou d'expliquer pourquoi la norme E.164 ne s'applique pas.

58voto

Bjorn Reppen Points 5009

KISS - Je commence à en avoir assez de la plupart des sites Web américains. Ils ont un code astucieux pour valider les codes postaux et les numéros de téléphone. Lorsque je tape mes coordonnées norvégiennes parfaitement valables, je constate qu'elles sont souvent rejetées.

Laissez une chaîne, à moins que vous n'ayez un besoin spécifique de quelque chose de plus avancé.

0 votes

Un bon vieux nvarchar(42) avec un peu de validation /^+?[0-9 -\.\(\)#*]{4,41}$/ fonctionne très bien !

0 votes

Je suis d'accord, mais pas d'accord en même temps. En général, vous voulez faire quelque chose avec ce numéro de téléphone stocké, par exemple l'afficher. Plutôt que d'essayer de l'analyser suffisamment pour l'afficher comme vous le souhaitez, je préfère le stocker de manière normalisée. Maintenant, je ne dis pas que nous devrions aller jusqu'à imposer des parenthèses autour de l'indicatif régional. Ce que je dis, c'est qu'il n'y a que des chiffres, pas de tirets, etc.

4 votes

Je pense que les numéros de téléphone devraient être analysés avant d'être stockés, afin qu'ils puissent être validés et stockés de manière normalisée. L'analyse syntaxique et le formatage des numéros de téléphone à l'échelle internationale sont parfaitement possibles grâce à l'outil de gestion des numéros de téléphone. googlei18n/libphonenombre .

21voto

Rich Points 2429

El Page Wikipedia sur E.164 devrait vous dire tout ce que vous avez besoin de savoir.

4 votes

Non, cette norme définit simplement la structure des numéros de téléphone (ils sont constitués de trois chiffres) mais elle ne précise pas comment ils doivent être affichés et/ou stockés. Ai-je dit "norme" ? Je voulais dire Recommandation .

8voto

Voici la structure que je propose, j'apprécierais vos commentaires :

Le champ de la base de données du téléphone doit être un varchar(42) avec le format suivant :

CountryCode - Numéro x Extension

Ainsi, par exemple, aux États-Unis, nous pourrions avoir :

1-2125551234x1234

Il s'agit d'un numéro américain (indicatif de pays 1) avec l'indicatif régional/numéro (212) 555 1234 et le poste 1234.

En séparant le code du pays par un tiret, le code du pays est clair pour une personne qui consulte les données. Ce n'est pas strictement nécessaire car les codes pays sont " codes préfixes " (vous pouvez les lire de gauche à droite et vous serez toujours en mesure de déterminer le pays sans ambiguïté). Mais, comme les codes pays ont des longueurs variables (entre 1 et 4 caractères pour le moment), il est difficile de déterminer d'un coup d'œil le code pays à moins d'utiliser une sorte de séparateur.

J'utilise un "x" pour séparer l'extension, car sinon il ne serait pas vraiment possible (dans de nombreux cas) de distinguer le numéro de l'extension.

De cette façon, vous pouvez stocker l'ensemble du numéro, y compris l'indicatif du pays et l'extension, dans un seul champ de la base de données, que vous pouvez ensuite utiliser pour accélérer vos requêtes, au lieu de les joindre à une fonction définie par l'utilisateur comme vous l'avez péniblement fait jusqu'à présent.

Pourquoi ai-je choisi un varchar(42) ? Tout d'abord, les numéros de téléphone internationaux sont de longueurs différentes, d'où le "var". Je stocke un tiret et un "x", ce qui explique le "char", et de toute façon, vous ne ferez pas d'arithmétique entière sur les numéros de téléphone (je suppose), donc cela n'a pas beaucoup de sens d'essayer d'utiliser un type numérique. Pour ce qui est de la longueur des 42, j'ai utilisé la longueur maximale possible de tous les champs additionnés, en me basant sur la réponse d'Adam Davis, et j'ai ajouté 2 pour le tiret et le "x".

6voto

Mike Fielden Points 3469

Personnellement, j'aime l'idée de stocker un numéro de téléphone varchar normalisé (par exemple 9991234567) puis, bien sûr, de formater ce numéro de téléphone en ligne lorsque vous l'affichez.

De cette façon, toutes les données de votre base de données sont "propres" et sans formatage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X