¿Cuál es una buena estructura de datos para almacenar números de teléfono en los campos de la base de datos? Estoy buscando algo que sea lo suficientemente flexible para manejar números internacionales, y también algo que permita consultar las distintas partes del número de manera eficiente.
Editar: Solo para aclarar el caso de uso aquí: actualmente almaceno números en un solo campo varchar, y los dejo tal como los ingresó el cliente. Luego, cuando el código necesita el número, lo normalizo. El problema es que si quiero consultar unos pocos millones de filas para encontrar números de teléfono coincidentes, implica una función, como
where dbo.f_normalizenum(num1) = dbo.f_normalizenum(num2)
que es terriblemente ineficaz. Además, las consultas que buscan cosas como el código de área se vuelven extremadamente complicadas cuando se trata de un solo campo varchar.
[Editar]
La gente ha hecho muchas buenas sugerencias aquí, ¡gracias! Como actualización, esto es lo que estoy haciendo ahora: todavía almaceno números exactamente como se ingresaron, en un campo varchar, pero en lugar de normalizar las cosas en el momento de la consulta, tengo un disparador que hace todo ese trabajo cuando se insertan los registros o actualizado. Así que tengo ints o bigints para las partes que necesito consultar, y esos campos están indexados para que las consultas se ejecuten más rápido.
Respuestas:
Primero, más allá del código de país, no existe un estándar real. Lo mejor que puede hacer es reconocer, por el código de país, a qué país pertenece un número de teléfono en particular y tratar el resto del número de acuerdo con el formato de ese país.
Sin embargo, en general, el equipo telefónico y demás están estandarizados, por lo que casi siempre puede dividir un número de teléfono determinado en los siguientes componentes
Con este método, puede separar números de manera que pueda encontrar, por ejemplo, personas que podrían estar cerca unas de otras porque tienen el mismo país, área y códigos de intercambio. Sin embargo, con los teléfonos móviles eso ya no es algo con lo que pueda contar.
Además, dentro de cada país existen diferentes estándares. Siempre puede depender de un EEE-LLLL (AAA) en los EE. UU., Pero en otro país puede tener intercambios en las ciudades (AAA) EE-LLL, y simplemente números de línea en las áreas rurales (AAA) LLLL. Tendrá que comenzar en la parte superior de un árbol de alguna forma y formatearlos según tenga la información. Por ejemplo, el código de país 0 tiene un formato conocido para el resto del número, pero para el código de país 5432, es posible que deba examinar el código de área antes de comprender el resto del número.
Es posible que también desee manejar
vanity
números como(800) Lucky-Guy
, lo que requiere reconocer que, si es un número de EE. UU., Hay demasiados dígitos (y es posible que necesite una representación completa para publicidad u otros fines) y que en los EE. UU. Las letras se asignan al números de manera diferente que en Alemania.También es posible que desee almacenar el número completo por separado como un campo de texto (con internacionalización) para que pueda volver más tarde y volver a analizar los números a medida que cambian las cosas, o como copia de seguridad en caso de que alguien envíe un método incorrecto para analizar el formato de un país en particular. y pierde información.
fuente
KISS - Me estoy cansando de muchos de los sitios web de EE. UU. Tienen un código inteligentemente escrito para validar códigos postales y números de teléfono. Cuando escribo mi información de contacto noruego perfectamente válida, encuentro que a menudo es rechazada.
Déjelo una cadena, a menos que tenga alguna necesidad específica de algo más avanzado.
fuente
nvarchar(42)
con un poco de validación/^+?[0-9 -\.\(\)#*]{4,41}$/
funciona muy bien!La página de Wikipedia sobre E.164 debería decirle todo lo que necesita saber.
fuente
Aquí está mi estructura propuesta, agradecería sus comentarios:
El campo de la base de datos del teléfono debe ser un varchar (42) con el siguiente formato:
CountryCode - Número x Extensión
Entonces, por ejemplo, en EE. UU., Podríamos tener:
1-2125551234x1234
Esto representaría un número de EE. UU. (Código de país 1) con código de área / número (212) 555 1234 y extensión 1234.
Separar el código del país con un guión hace que el código del país sea claro para alguien que está examinando los datos. Esto no es estrictamente necesario porque los códigos de país son " códigos de prefijo " (puede leerlos de izquierda a derecha y siempre podrá determinar sin ambigüedades el país). Pero, dado que los códigos de país tienen diferentes longitudes (entre 1 y 4 caracteres en este momento), no puede saber fácilmente de un vistazo el código de país a menos que use algún tipo de separador.
Utilizo una "x" para separar la extensión porque de otro modo no sería posible (en muchos casos) averiguar cuál era el número y cuál era la extensión.
De esta manera, puede almacenar el número completo, incluido el código de país y la extensión, en un solo campo de base de datos, que luego puede usar para acelerar sus consultas, en lugar de unirse a una función definida por el usuario como lo ha estado haciendo hasta ahora. .
¿Por qué elegí un varchar (42)? Bueno, en primer lugar, los números de teléfono internacionales serán de distintas longitudes, de ahí la "var". Estoy almacenando un guión y una "x", de modo que eso explica el "char" y, de todos modos, no harás aritmética de enteros en los números de teléfono (supongo), por lo que no tiene mucho sentido intentar usar un tipo numérico . En cuanto a la longitud de 42, utilicé la longitud máxima posible de todos los campos sumados, según la respuesta de Adam Davis, y agregué 2 para el guión y la "x".
fuente
Busque E.164. Básicamente, almacena el número de teléfono como un código que comienza con el prefijo del país y un sufijo pbx opcional. La visualización es entonces un problema de localización. También se puede realizar la validación, pero también es un problema de localización (según el prefijo del país).
Por ejemplo, + 12125551212 + 202 se formateará en la configuración regional en_US como (212) 555-1212 x202. Tendría un formato diferente en
en_GB
ode_DE
.Hay bastante información sobre ITU-T E.164, pero es bastante críptica.
fuente
Personalmente, me gusta la idea de almacenar un número de teléfono varchar normalizado (por ejemplo, 9991234567) y luego, por supuesto, formatear ese número de teléfono en línea a medida que lo muestra.
De esta forma, todos los datos de su base de datos están "limpios" y sin formato.
fuente
Almacenamiento
Almacene los teléfonos en RFC 3966 (como
+1-202-555-0252
,+1-202-555-7166;ext=22
). La principal diferencia con E.164 sonPara optimizar el rendimiento de las operaciones de visualización, almacene el teléfono en formato nacional / internacional junto al campo RFC 3966.
No guarde el código de país en un campo separado a menos que tenga una razón seria para ello. ¿Por qué? Porque no debe solicitar el código de país en la interfaz de usuario.
En su mayoría, las personas ingresan a los teléfonos cuando los escuchan. Por ejemplo, si el formato local comenzará desde
0
o8
, sería molesto para el usuario hacer la transformación numérica en la cabeza (como, " OK, no escriba '0', elija el país y escriba el resto de lo que persona dijo en este campo ").Analizando
Google te respalda y puedes validar y analizar cualquier número de teléfono usando su biblioteca libphonenumber . Hay puertos para casi cualquier idioma.
Así que deje que el usuario ingrese "
0449053501
" o "04 4905 3501
" o "(04) 4905 3501
". La herramienta se encargará del resto por ti.Vea la demostración oficial para tener una idea de cuánto ayuda.
fuente
¿Quizás almacenar las secciones de números de teléfono en diferentes columnas, permitiendo entradas en blanco o nulas?
fuente
De acuerdo, según la información de esta página, aquí hay un comienzo en un validador de número de teléfono internacional:
Basado libremente en un script de esta página: http://www.webcheatsheet.com/javascript/form_validation.php
fuente
El estándar para formatear números es e.164 . Siempre debe almacenar números en este formato. Nunca debe permitir el número de extensión en el mismo campo con el número de teléfono, estos deben almacenarse por separado. En cuanto a numérico vs alfanumérico, depende de lo que vaya a hacer con esos datos.
fuente
Creo que el texto libre (quizás varchar (25)) es el estándar más utilizado. Esto permitirá cualquier formato, ya sea nacional o internacional.
Supongo que el principal factor determinante puede ser la forma exacta en que consulta estos números y lo que hace con ellos.
fuente
Encuentro que la mayoría de los formularios web permiten correctamente el código de país, el código de área y luego los 7 dígitos restantes, pero casi siempre olvido permitir la entrada de una extensión. Esto casi siempre termina haciendo que pronuncie palabras de enojo, ya que en el trabajo no tenemos recepcionista y se necesita mi número de extensión para comunicarse conmigo.
fuente
Tendría que comprobarlo, pero creo que nuestro esquema de base de datos es similar. Tenemos un código de país (puede ser el predeterminado de EE. UU., No estoy seguro), un código de área, 7 dígitos y una extensión.
fuente
¿Qué hay de almacenar una columna de texto libre que muestra una versión fácil de usar del número de teléfono, luego una versión normalizada que elimina espacios, corchetes y expande '+'? Por ejemplo:
Fácil de usar: +44 (0) 181 4642542
Normalizado: 00441814642542
fuente
Yo optaría por un campo de texto libre y un campo que contenga una versión puramente numérica del número de teléfono. Dejaría la representación del número de teléfono al usuario y usaría el campo normalizado específicamente para las comparaciones de números de teléfono en aplicaciones basadas en TAPI o cuando intento encontrar entradas dobles en un directorio telefónico. Por supuesto, no está de más proporcionar al usuario un esquema de entrada que agregue inteligencia como campos separados para el código de país (si es necesario), código de área, número base y extensión.
fuente
¿De dónde sacas los números de teléfono? Si los obtiene de parte de la red telefónica, obtendrá una cadena de dígitos y un tipo de número y plan, p. Ej.
441234567890 tipo / plan 0x11 (que significa E.164 internacional)
En la mayoría de los casos, lo mejor que puede hacer es almacenar todos estos como están y normalizarlos para su visualización, aunque almacenar números normalizados puede resultar útil si desea utilizarlos como una clave única o similar.
fuente
El (0) no es válido en el formato internacional. Consulte el estándar ITU-T E.123.
El formato "normalizado" no sería útil para los lectores estadounidenses, ya que utilizan 011 para acceso internacional.
fuente
He utilizado 3 formas diferentes de almacenar números de teléfono según los requisitos de uso.
fuente