¿Mejores prácticas para almacenar direcciones postales en una base de datos (RDBMS)?

106

¿Existen buenas referencias sobre las mejores prácticas para almacenar direcciones postales en un RDBMS? Parece que hay muchas compensaciones que se pueden hacer y muchos pros y contras de cada uno para ser evaluados. Seguramente esto se ha hecho una y otra vez. ¿Quizás alguien ha escrito al menos algunas lecciones aprendidas en alguna parte?

Ejemplos de las compensaciones de las que estoy hablando son almacenar el código postal como un número entero frente a un campo de caracteres, si el número de casa se debe almacenar como un campo separado o parte de la línea de dirección 1, si los números de suite / apartamento / etc.se normalizan o simplemente se almacenan como un fragmento de texto en la línea de dirección 2, ¿cómo se maneja zip +4 (campos separados o un campo grande, entero vs texto)? etc.

En este momento, me preocupan principalmente las direcciones de EE. UU., Pero imagino que existen algunas prácticas recomendadas en lo que respecta a prepararse para la eventualidad de globalizarse también (por ejemplo, nombrar los campos de manera apropiada como región en lugar de estado o código postal en lugar de código postal, etc.

Juan
fuente
3
Desde el principio, debe haber un campo de caracteres; de lo contrario, ciertos códigos postales que comienzan con 0 se volverían inexactos.
Menasheh
1
Como regla general, cuando necesite hacer cálculos matemáticos con el número, debe ser un número entero. Si solo lo muestra, debe ser char (teléfono, código postal, etc.)
Zikato

Respuestas:

37

Para un uso más internacional, un esquema a considerar es el que utiliza el campo de dirección Drupal . Se basa en el estándar xNAL y parece cubrir la mayoría de los casos internacionales. Un poco de investigación en ese módulo revelará algunas perlas interesantes para interpretar y validar direcciones a nivel internacional. También tiene un buen conjunto de áreas administrativas (provincia, estado, oblast, etc.) con códigos ISO.

Aquí está la esencia del esquema, copiada de la página del 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)

Lecciones que he aprendido:

  • No almacene nada numéricamente.
  • Almacene el país y el área administrativa como códigos ISO cuando sea posible.
  • Cuando no lo sepa, sea poco estricto a la hora de solicitar campos. Es posible que algunos países no utilicen campos que da por sentado, incluso cosas básicas como locality& thoroughfare.
Samm Cooper
fuente
1
¿Puedo preguntar para qué está destinado "name_line"? Realmente no encontré una explicación en Drupal Docs o xNal Standard. ¿Cómo lo entiendo? Name_line es para enviar cartas o paquetes reales por correo. El nombre apellido / APELLIDOS sólo son necesarios si se quiere abordar el cliente directamente, por ejemplo, por correo electrónico ( "Estimado señor <apellidos>"). ¿O tiene algún otro propósito / beneficio?
Luba
Cuando se realizan entregas en locales comerciales (grandes), a menudo se necesita un nombre para el sistema de entrega de correo interno (considere los edificios de oficinas con salas de correo)
Chris Browne
El campo de dirección ha sido reemplazado por Dirección . Parece que los campos pueden ser un poco diferentes
Gavin Haynes
24

Como usuario "internacional", no hay nada más frustrante que tratar con un sitio web que está orientado únicamente a direcciones de formato estadounidense. Al principio es un poco grosero, pero se convierte en un problema grave cuando la validación también es demasiado entusiasta.

Si le preocupa la globalización, el único consejo que tengo es mantener las cosas en forma libre. Los diferentes países tienen convenciones diferentes: en algunos, el número de la casa viene antes del nombre de la calle, en algunos viene después. Algunos tienen estados, algunas regiones, algunos condados, algunas combinaciones de esos. Aquí en el Reino Unido, el código postal no es un código postal, es un código postal que contiene letras y números.

Aconsejaría simplemente ~ 10 líneas de cadenas de longitud variable, junto con un campo separado para un código postal (y tenga cuidado de cómo lo describe para hacer frente a las sensibilidades nacionales). Deje que el usuario / cliente decida cómo escribir sus direcciones.

Andrew Ferrier
fuente
Por lo que vale, esto no es para un sitio web, pero el punto sobre direcciones internacionales aún está bien tomado.
John
47
Si bien no estoy en desacuerdo con el mensaje, y de hecho lo aplaudo por la postura que toma, tuve que rechazarlo porque aborrezco el hecho de ser alguien que pasa la mayor parte de mi tiempo escribiendo herramientas para limpiar los datos de direcciones. de almacenamiento de datos de direcciones en un formato de forma libre. Las direcciones pueden tener un formato diferente, pero los datos siguen siendo en gran medida los mismos. Si el número de una calle se muestra antes o después del nombre de la calle, es en gran parte irrelevante para fines de almacenamiento, solo para fines de visualización.
BenAlabaster
17

Definitivamente, debería considerar almacenar el número de casa como un campo de caracteres en lugar de un número, debido a casos especiales como "medios números" o mi dirección actual, que es algo así como "129A", pero la A no se considera un apartamento. número para servicios de entrega.

Paul Fisher
fuente
11

He hecho esto (modelar rigurosamente las estructuras de direcciones en una base de datos) y nunca lo volvería a hacer. No te imaginas lo locas que son las excepciones que tendrás que tener en cuenta como regla.

Recuerdo vagamente algún problema con los códigos postales noruegos (creo), que eran las 4 posiciones, excepto Oslo, que tenía 18 más o menos.

Estoy absolutamente seguro de que desde el momento en que comenzamos a utilizar los códigos postales geográficamente correctos para todas nuestras direcciones nacionales, muchas personas comenzaron a quejarse de que su correo llegó demasiado tarde. Resultó que esas personas vivían cerca de una frontera entre áreas postales, y a pesar de que alguien realmente vivía en el área postal, digamos 1600, en realidad su correo debería estar dirigido al área postal 1610, porque en realidad era el área postal vecina. que realmente le sirvió, por lo que enviar su correo a su área postal correcta demoraría un par de días más en llegar, debido a la intervención no deseada que se requirió en la oficina postal correcta para reenviarlo al área postal incorrecta ...

(Terminamos registrando a aquellas personas con una dirección en el extranjero en el país con el código ISO 'ZZ').


fuente
8

Ciertamente debería consultar " ¿Es esta una buena manera de modelar la información de direcciones en una base de datos relacional? ", Pero su pregunta no es un duplicado directo de eso.

Seguramente hay muchas respuestas preexistentes (consulte los modelos de datos de ejemplo en DatabaseAnswers , por ejemplo). Muchas de las respuestas preexistentes son defectuosas en algunas circunstancias (sin elegir DB Answers en absoluto).

Un tema importante a considerar es el alcance de las direcciones. Si su base de datos debe tratar con direcciones internacionales, debe ser más flexible que si solo tuviera que tratar con direcciones en un país.

En mi opinión, a menudo (lo que no significa siempre ) es sensato registrar la 'imagen de la etiqueta de dirección' de la dirección y analizar por separado el contenido. Esto le permite lidiar con las diferencias entre la ubicación de los códigos postales, por ejemplo, entre diferentes países. Claro, puede escribir un analizador y un formateador que manejen las excentricidades de diferentes países (por ejemplo, las direcciones de EE. UU. Tienen 2 o 3 líneas; por el contrario, las direcciones británicas pueden tener considerablemente más; una dirección a la que escribo periódicamente tiene 9 líneas). Pero puede ser más fácil que los humanos hagan el análisis y el formateo y que el DBMS simplemente almacene los datos.

Jonathan Leffler
fuente
7

A menos que vaya a hacer cálculos matemáticos con los números de la calle o los códigos postales, solo está invitando al dolor futuro al almacenarlos como números.

Puede guardar unos pocos bytes aquí y allá, y tal vez obtener un índice más rápido, pero ¿qué hace cuando el servicio postal de EE. UU., O cualquier otro país con el que esté tratando, decide introducir alfa en los códigos?

El costo del espacio en disco será mucho más barato que el costo de arreglarlo más adelante ... ¿y2k alguien?

seanb
fuente
7

Agregando a lo que han dicho @ Jonathan Leffler y @ Paul Fisher

Si alguna vez prevé agregar direcciones postales de Canadá o México a sus requisitos, postal-codees imprescindible almacenarlas como una cadena. Canadá tiene códigos postales alfanuméricos y no recuerdo cómo se ve México en la parte superior de mi cabeza.

Ken Gentle
fuente
7

He descubierto que enumerar todos los campos posibles, desde la unidad discreta más pequeña hasta la más grande, es la forma más fácil. Los usuarios completarán los campos que consideren adecuados. Mi tabla de direcciones se ve así:

*********************************
  Field              Type
*********************************
  address_id (PK)    int
  unit               string
  building           string        
  street             string
  city               string
  region             string
  country            string
  address_code       string
*********************************
Gaz_Edge
fuente
¿Cómo se almacenan los apartados de correos?
Jowen
simplemente agregue otra columna PO_box Si tiene que hacer esto retrospectivamente, eso significa que ninguna de las direcciones anteriores necesitaba un apartado postal, por lo que se puede configurar como nulo
Gaz_Edge
2

¿Dónde está la "compensación" de almacenar el ZIP como un NÚMERO o VARCHAR? Eso es solo una elección, no es una compensación a menos que haya beneficios para ambos y tenga que renunciar a algunos beneficios para obtener otros.

A menos que la suma de cremalleras tenga algún significado, las cremalleras como número no son útiles.


fuente
Una compensación podría ser el tamaño de la base de datos. En mysql 5, una fila mediumint solo tomaría 3 bytes por fila mientras que un varchar (5) tomaría el doble. También pensé que las búsquedas numéricas eran más rápidas que las de texto, pero no estoy seguro de eso.
gpojd
4
uno debería usar un varchar. El código postal canadiense usa una codificación alfanumérica, que no encajaría bien en un número.
EvilTeach
1
Si bien entiendo la lógica "compatible con versiones posteriores" detrás del uso de varchar en este sentido, la afirmación de que "las cremalleras como número no son útiles" es un poco demasiado dogmática. Si sabe que va a trabajar con códigos postales exclusivos de EE. UU., Tiene sentido almacenar los códigos postales como números enteros, al igual que cuando escribe en un idioma estrictamente escrito, no define todo como tipo Cadena ... sabe que va a ser un número, ¿por qué no apoyarse en la verificación de tipo del lenguaje de programación / DB y llamarlo como es: un entero?
rinogo
1
@rinogo un argumento para usar varchar es que los códigos postales no son numéricos en el sentido matemático; no tiene sentido hacer sumas o restas en ellos; simplemente están codificados con un juego de caracteres restringido. stackoverflow.com/a/893489/48659
Steve Folly
1
@SteveFolly Y en mayor apoyo a que los códigos postales sean cadenas, los caracteres principales tienen un significado especial: en.wikipedia.org/wiki/ZIP_Code#Primary_state_prefixes Si uno va a implementar una lógica como "¿cuáles son los caracteres más a la izquierda del valor ? " entonces seguro que suena más como una cadena que como un número entero.
David Aldridge
2

Esto puede ser una exageración, pero si necesita una solución que funcione con varios países y necesita procesar partes de la dirección mediante programación:

podría tener el manejo de direcciones específicas de un país usando dos tablas: una tabla genérica con 10 columnas VARCHAR2, 10 columnas de números, otra tabla que asigna estos campos a las solicitudes y tiene una columna de país que vincula una estructura de direcciones a un país.

Shanmu
fuente
De hecho, lo he considerado yo mismo. Además de, o tal vez en lugar de, una tabla que asigna columnas a solicitudes según el país, estaba pensando en crear vistas actualizables para cada formato de dirección específico. Todavía no he apretado el gatillo, pero lo he pensado.
Andrew Steitz
1

Si alguna vez tiene que verificar una dirección o usarla para procesar pagos con tarjeta de crédito, al menos necesitará una pequeña estructura. Un bloque de texto de forma libre no funciona muy bien para eso.

El código postal es un campo opcional común para validar transacciones con tarjeta de pago sin usar la dirección completa. Así que tenga un campo separado y de tamaño generoso para eso (al menos 10 caracteres).

Ted Bigham
fuente
-1

Simplemente pondría todos los campos juntos en un gran campo NVARCHAR (1000), con un elemento de área de texto para que el usuario ingrese el valor (a menos que desee realizar un análisis, por ejemplo, códigos postales). Todas esas entradas de la línea de dirección 1, línea de dirección 2, etc. son tan molestas si tiene una dirección que no encaja bien con ese formato (y, ya sabe, hay otros países además de los EE. UU.).

erikkallen
fuente
3
¡Qué idea tan horrible! No hay suficiente espacio en un "Comentario" para describir la pesadilla que esto invita. Es mejor dedicar un poco más de tiempo a diseñarlo correctamente que tratar de desenredar el desorden después. Vea la respuesta de Samm Cooper. Creo que solo he votado en contra de otra respuesta aquí en SO, pero esta definitivamente obtuvo un voto en contra de mí.
Andrew Steitz
¿Qué lío? ¿Para qué necesitas los datos? A menudo, solo lo necesita para pasarlo directamente a alguna impresora de etiquetas o similar, y luego puede tratarlo como una gota de texto. En otras ocasiones, es posible que le interesen las ciudades y los códigos postales (pero es mejor que se asegure de tener solo clientes en los países admitidos)
erikkallen
2
OP no mencionó "solo la necesidad de pasarlo a una impresora de etiquetas" y en cada trabajo que tuve, usamos la dirección como "datos", ejecutando informes, recaudando impuestos (impuesto sobre las ventas de Colorado para electrodomésticos que se instalan en una nueva casa varían de un lado de la calle a otro), la asignación de clientes potenciales a los vendedores, la satisfacción de los requisitos de cumplimiento del gobierno, la lista sigue y sigue. "Destruir" datos (al combinar distintos elementos en un campo o no capturar los datos disponibles) es un "pecado" en mi libro y siempre ha demostrado ser la pesadilla sobre la que advertí cuando la gente me ignoraba.
Andrew Steitz
Si luego descubre que no necesitaba un dato, siempre puede "destruirlo" más tarde. La "creación" de datos varía desde una pesadilla (dividir la información en campos separados) hasta lo imposible (capturar datos después del hecho). Si el OP hubiera dicho, "solo necesito enviarlo a la impresora de etiquetas", habría aplaudido y votado a favor de su respuesta. Sin embargo, sin una mención específica de algo así, una sugerencia de "destruir" datos, en mi opinión, está al borde de lo irresponsable o incluso mezquino.
Andrew Steitz
Donde he trabajado (principalmente comercio electrónico), tendemos a almacenarlo en 5-6 campos diferentes, pero nunca, nunca, hacemos nada con la información que no sea usarla para enviar a entrega.
erikkallen