database - ¿Mejores prácticas para almacenar direcciones postales en una base de datos(RDBMS)?
database-design types (14)
¿Hay alguna buena referencia para las mejores prácticas para almacenar direcciones postales en un RDBMS? Parece que se pueden hacer muchas concesiones y muchos pros y contras para que cada uno sea evaluado. ¿Seguro que esto se ha hecho una y otra vez? Tal vez alguien al menos ha escrito 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 char, el número de la casa debe almacenarse como un campo separado o parte de la línea de dirección 1, deben los números suite / apartamento / etc. normalizarse o simplemente almacenarse como un fragmento de texto en la línea de dirección 2, ¿cómo maneja zip +4 (campos separados o un campo grande, entero versus texto)? etc.
En este momento me preocupo principalmente por las direcciones de los EE. UU. Pero imagino que hay algunas mejores prácticas para prepararse para la eventualidad de convertirse en global (por ejemplo, nombrar los campos apropiadamente como región en lugar de estado o código postal en lugar de código postal, etc.
Para un uso más internacional, un esquema a considerar es el utilizado por Drupal Address Field . Se basa en el estándar xNAL y parece abarcar la mayoría de los casos internacionales. Un poco de exploración en ese módulo revelará algunas perlas bonitas para interpretar y validar direcciones internacionalmente. También tiene un buen conjunto de áreas administrativas (provincia, estado, oblast, etc.) con códigos ISO.
Aquí está la esencia del esquema, copiado 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)
Una lección que aprendí:
- No almacene nada numéricamente.
- Almacene el país y el área administrativa como códigos ISO cuando sea posible.
- Cuando no lo sepas, sé poco exigente con los campos. Es posible que algunos países no usen los campos que usted da por sentado, ni siquiera los aspectos básicos como la
locality
y lathoroughfare
.
¿Dónde está la "compensación" al almacenar el ZIP como NÚMERO o VARCHAR? Esa es solo una opción, no es una compensación, a menos que haya beneficios para ambos y tenga que renunciar a algunos beneficios para obtener a los demás.
A menos que la suma de las cremalleras tenga algún significado, Zips como número no es útil.
A menos que vaya a hacer cálculos matemáticos en los números de calles o en los códigos postales / postales, solo está invitando dolor futuro almacenándolos como números.
Puede guardar algunos bytes aquí y allá, y tal vez obtener un índice más rápido, pero, ¿qué sucede cuando US postal, o cualquier otro país con el que está tratando, decide introducir los alfas en los códigos?
El costo de espacio en disco va a ser mucho más barato que el costo de arreglarlo más tarde ... ¿alguien?
Como usuario "internacional", no hay nada más frustrante que lidiar con un sitio web orientado solo a direcciones en formato estadounidense. Es un poco grosero al principio, pero se convierte en un problema grave cuando la validación es demasiado celosa.
Si le preocupa ser global, el único consejo que tengo es mantener las cosas libres. Los diferentes países tienen diferentes convenciones; en algunos, el número de la casa aparece antes que el nombre de la calle, en algunos aparece 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.
Aconsejo 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 describir eso para hacer frente a las sensibilidades nacionales). Deje que el usuario / cliente decida cómo escribir sus direcciones.
Hice esto (rigurosamente modelé las estructuras de direcciones en una base de datos) y nunca volvería a hacerlo. No puede imaginarse cuán locas son las excepciones que tendrá que tener en cuenta como regla general.
Recuerdo vagamente algún problema con los códigos postales noruegos (creo), que eran los 4 puestos, excepto Oslo, que tenía 18 o más.
Estoy seguro de que desde el momento en que comenzamos a usar los códigos postales geográficamente correctos para todas nuestras direcciones nacionales, bastantes personas comenzaron a quejarse de que su correo llegaba 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 debe dirigirse a la zona postal 1610, porque en realidad era esa zona postal vecina que realmente le sirvió, así que enviar su correo a su área postal correcta tomaría ese correo un par de días más para llegar, debido a la intervención no deseada que se requería en la oficina postal correcta para enviarla a la zona postal incorrecta ...
(Terminamos registrando a aquellas personas con una dirección en el extranjero en el país con el código ISO ''ZZ'').
Esto podría ser una exageración, pero si necesita una solución que funcione en varios países y necesita procesar partes de la misma mediante programación:
podría tener manejo de direcciones específicas del país utilizando 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.
Si necesita información completa sobre cómo otros países usan direcciones postales, aquí hay un enlace de referencia muy bueno (Universidad de Columbia):
La Guía Compulsiva de Frank para Direcciones Postales
Direcciones efectivas para correo internacional
Simplemente juntaría todos los campos en un gran campo NVARCHAR (1000), con un elemento textarea para que el usuario ingrese el valor (a menos que desee realizar un análisis en, por ejemplo, códigos postales). Todas las entradas de la línea de dirección 1, la línea de dirección 2, etc. son tan molestas si tienes una dirección que no encaja bien con ese formato (y, como sabes, hay otros países aparte de EE. UU.).
He encontrado que enumerar todos los campos posibles desde la unidad discreta más pequeña hasta la más grande es la manera 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
*********************************
Si alguna vez tiene que verificar una dirección o usarla para procesar los 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 de tarjetas de pago sin utilizar toda la dirección. Así que tenga un campo separado y de gran tamaño para eso (al menos 10 caracteres).
Inspirado por Database Answers
Line1
Line2
Line3
City
Country_Province
PostalCode
CountryId
OtherDetails
Agregando a lo que han dicho Jonathan Leffler y @ Paul Fisher
Si alguna vez prevé tener direcciones postales para Canadá o México añadidas a sus requisitos, es imprescindible almacenar el postal-code
como una cadena. Canadá tiene códigos postales alfanuméricos y no recuerdo cómo se ve México en mi cabeza.
Sin duda debería consultar " ¿Es esta una buena manera de modelar 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 ejemplos de modelos de datos en DatabaseAnswers , por ejemplo). Muchas de las respuestas preexistentes son defectuosas en algunas circunstancias (sin elegir las respuestas de DB 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 direcciones en un país.
En mi opinión, a menudo (lo que no siempre significa) es sensato registrar la "imagen de etiqueta de dirección" de la dirección y analizar el contenido por separado. Esto le permite tratar 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 maneje las excentricidades de diferentes países (por ejemplo, las direcciones estadounidenses tienen 2 o 3 líneas, por el contrario, las direcciones británicas pueden tener mucho más, una dirección que escribo periódicamente tiene 9 líneas). Pero puede ser más fácil hacer que los humanos realicen el análisis y el formateo y permitan que el DBMS simplemente almacene los datos.
Definitivamente debería considerar almacenar el número de la casa como un campo de caracteres en lugar de un número, debido a casos especiales como "medio números" o mi dirección actual, que es algo así como "129A", pero la A no se considera como un apartamento número para servicios de entrega.