Qual é uma boa estrutura de dados para armazenar números de telefone em campos de banco de dados? Estou procurando algo que seja flexível o suficiente para lidar com números internacionais e também algo que permita que as várias partes do número sejam consultadas com eficiência.
Edit: Apenas para esclarecer o caso de uso aqui: Atualmente, armazeno números em um único campo varchar e os deixo exatamente como o cliente os inseriu. Então, quando o número é necessário por código, eu normalizo. O problema é que, se eu quiser consultar alguns milhões de linhas para encontrar números de telefone correspondentes, isso envolve uma função, como
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
o que é terrivelmente ineficiente. Além disso, as consultas que procuram coisas como o código de área tornam-se extremamente complicadas quando é apenas um único campo varchar.
[Editar]
As pessoas fizeram muitas sugestões boas aqui, obrigado! Como uma atualização, aqui está o que estou fazendo agora: eu ainda armazeno os números exatamente como foram inseridos, em um campo varchar, mas em vez de normalizar as coisas no momento da consulta, tenho um gatilho que faz todo o trabalho conforme os registros são inseridos ou atualizado. Portanto, tenho ints ou bigints para todas as partes que preciso consultar, e esses campos são indexados para tornar as consultas mais rápidas.
Respostas:
Primeiro, além do código do país, não existe um padrão real. O melhor que você pode fazer é reconhecer, pelo código do país, a qual nação um determinado número de telefone pertence e lidar com o resto do número de acordo com o formato dessa nação.
Geralmente, no entanto, equipamentos de telefone e outros são padronizados, então você quase sempre pode dividir um determinado número de telefone nos seguintes componentes
Com esse método, você pode separar potencialmente os números de forma que possa localizar, por exemplo, pessoas que podem ser próximas umas das outras porque têm o mesmo país, área e códigos de câmbio. Com os telefones celulares, isso não é mais algo com que você pode contar.
Além disso, dentro de cada país existem padrões diferentes. Você sempre pode depender de um (AAA) EEE-LLLL nos EUA, mas em outro país você pode ter trocas nas cidades (AAA) EE-LLL e simplesmente números de linha nas áreas rurais (AAA) LLLL. Você terá que começar no topo de uma árvore de alguma forma e formatá-los conforme você tiver informações. Por exemplo, o código do país 0 tem um formato conhecido para o resto do número, mas para o código do país 5432 você pode precisar examinar o código de área antes de entender o resto do número.
Você também pode querer lidar com
vanity
números como(800) Lucky-Guy
, que requer o reconhecimento de que, se for um número dos EUA, há muitos dígitos (e você pode precisar de representação completa para publicidade ou outros fins) e que nos EUA as letras mapeiam para o números de forma diferente do que na Alemanha.Você também pode querer armazenar o número inteiro separadamente como um campo de texto (com internacionalização) para que possa voltar mais tarde e re-analisar os números conforme as coisas mudam ou como um backup no caso de alguém enviar um método incorreto para analisar o formato de um determinado país e perde informações.
fonte
KISS - Estou ficando cansado de muitos sites dos EUA. Eles têm alguns códigos habilmente escritos para validar códigos postais e números de telefone. Quando eu digito minhas informações de contato norueguesas perfeitamente válidas, descubro que muitas vezes elas são rejeitadas.
Deixe uma string, a menos que você tenha alguma necessidade específica de algo mais avançado.
fonte
nvarchar(42)
com um pouco de validação/^+?[0-9 -\.\(\)#*]{4,41}$/
funciona muito bem!A página da Wikipedia em E.164 deve informar tudo o que você precisa saber.
fonte
Aqui está minha estrutura proposta, gostaria de receber feedback:
O campo do banco de dados do telefone deve ser um varchar (42) com o seguinte formato:
CountryCode - Número x Extensão
Então, por exemplo, nos EUA, poderíamos ter:
1-2125551234x1234
Isso representaria um número dos EUA (código do país 1) com código de área / número (212) 555 1234 e ramal 1234.
Separar o código do país com um traço torna o código do país claro para quem está lendo os dados. Isso não é estritamente necessário porque os códigos de país são " códigos de prefixo " (você pode lê-los da esquerda para a direita e sempre será capaz de determinar sem ambigüidade o país). Mas, uma vez que os códigos de país têm comprimentos variados (entre 1 e 4 caracteres no momento), você não pode dizer facilmente o código do país a menos que use algum tipo de separador.
Eu uso um "x" para separar a extensão porque, caso contrário, realmente não seria possível (em muitos casos) descobrir qual era o número e qual era a extensão.
Desta forma, você pode armazenar o número inteiro, incluindo o código do país e o ramal, em um único campo do banco de dados, que você pode usar para acelerar suas consultas, em vez de ingressar em uma função definida pelo usuário como tem feito penosamente até agora .
Por que escolhi um varchar (42)? Bem, em primeiro lugar, os números de telefone internacionais terão comprimentos variados, daí o "var". Estou armazenando um hífen e um "x", o que explica o "char" e, de qualquer forma, você não fará aritmética inteira com os números de telefone (eu acho), então não faz sentido tentar usar um tipo numérico . Quanto ao comprimento de 42, usei o comprimento máximo possível de todos os campos somados, com base na resposta de Adam Davis, e adicionei 2 para o travessão e o 'x ".
fonte
Procure E.164. Basicamente, você armazena o número de telefone como um código que começa com o prefixo do país e um sufixo PBX opcional. A exibição é, então, um problema de localização. A validação também pode ser feita, mas também é um problema de localização (com base no prefixo do país).
Por exemplo, + 12125551212 + 202 seria formatado na localidade en_US como (212) 555-1212 x202. Teria um formato diferente em
en_GB
oude_DE
.Há muitas informações por aí sobre o ITU-T E.164, mas são bastante enigmáticas.
fonte
Pessoalmente, gosto da ideia de armazenar um número de telefone varchar normalizado (por exemplo, 9991234567) e, é claro, formatar esse número de telefone em linha conforme você o exibe.
Desta forma, todos os dados em seu banco de dados ficam "limpos" e livres de formatação
fonte
Armazenamento
Armazene telefones em RFC 3966 (como
+1-202-555-0252
,+1-202-555-7166;ext=22
). A principal diferença do E.164 sãoPara otimizar o desempenho das operações de visualização, armazene o telefone no formato Nacional / Internacional próximo ao campo RFC 3966.
Não armazene o código do país em um campo separado, a menos que você tenha um motivo sério para isso. Por quê? Porque você não deve pedir o código do país na IU.
Geralmente, as pessoas entram nos telefones quando os ouvem. Por exemplo, se o formato local vai começar de
0
ou8
, seria irritante para o usuário fazer a transformação do número na cabeça (como, " OK, não digite '0', escolha o país e digite o resto do pessoa disse neste campo ").Análise
O Google está a seu lado e você pode validar e analisar qualquer número de telefone usando sua biblioteca libphonenumber . Existem portas para quase todos os idiomas.
Portanto, deixe o usuário inserir apenas "
0449053501
" ou "04 4905 3501
" ou "(04) 4905 3501
". A ferramenta descobrirá o resto para você.Veja a demonstração oficial para ter uma ideia do quanto isso ajuda.
fonte
Talvez armazenando as seções de número de telefone em colunas diferentes, permitindo entradas em branco ou nulas?
fonte
Ok, então com base nas informações desta página, aqui está um início em um validador de número de telefone internacional:
Vagamente baseado em um script desta página: http://www.webcheatsheet.com/javascript/form_validation.php
fonte
O padrão para formatar números é e.164 . Você sempre deve armazenar os números neste formato. Você nunca deve permitir o número do ramal no mesmo campo com o número do telefone, eles devem ser armazenados separadamente. Quanto a numérico vs alfanumérico, depende do que você fará com esses dados.
fonte
Acho que o texto livre (talvez varchar (25)) é o padrão mais usado. Isso permitirá qualquer formato, seja nacional ou internacional.
Acho que o principal fator motivador pode ser como exatamente você está consultando esses números e o que está fazendo com eles.
fonte
Acho que a maioria dos formulários da web permite corretamente o código do país, código de área e os 7 dígitos restantes, mas quase sempre me esqueço de permitir a entrada de um ramal. Isso quase sempre acaba fazendo com que eu fale palavrões, já que no trabalho não temos recepcionista e meu ramal é necessário para me alcançar.
fonte
Eu teria que verificar, mas acho que nosso esquema de banco de dados é semelhante. Temos um código de país (pode ser os EUA, não tenho certeza), código de área, 7 dígitos e ramal.
fonte
Que tal armazenar uma coluna de texto livre que mostra uma versão amigável do número de telefone e, em seguida, uma versão normalizada que remove espaços, colchetes e expande '+'. Por exemplo:
Amigável: +44 (0) 181 4642542
Normalizado: 00441814642542
fonte
Eu escolheria um campo de texto livre e um campo que contém uma versão puramente numérica do número de telefone. Eu deixaria a representação do número de telefone para o usuário e usaria o campo normalizado especificamente para comparações de número de telefone em aplicativos baseados em TAPI ou ao tentar localizar entradas duplas em uma lista telefônica. Claro que não faz mal fornecer ao usuário um esquema de entrada que adiciona inteligência, como campos separados para código do país (se necessário), código de área, número de base e ramal.
fonte
De onde você está conseguindo os números de telefone? Se você os está obtendo de parte da rede telefônica, obterá uma sequência de dígitos e um tipo de número e plano, por exemplo
441234567890 tipo / plano 0x11 (que significa internacional E.164)
Na maioria dos casos, a melhor coisa a fazer é armazenar todos eles como estão e normalizar para exibição, embora armazenar números normalizados possa ser útil se você quiser usá-los como uma chave única ou semelhante.
fonte
O (0) não é válido no formato internacional. Consulte o padrão ITU-T E.123.
O formato "normalizado" não seria útil para leitores dos Estados Unidos, pois eles usam 011 para acesso internacional.
fonte
Usei três maneiras diferentes de armazenar números de telefone, dependendo dos requisitos de uso.
fonte