sql - tipos - ¿Es esta una buena manera de modelar información de direcciones en una base de datos relacional?
para que sirve una base de datos relacional (7)
Me pregunto si este es un buen diseño. Tengo varias tablas que requieren información de dirección (por ejemplo, calle, código postal / país, fax, correo electrónico). A veces, la misma dirección se repetirá varias veces. Por ejemplo, una dirección puede almacenarse contra un proveedor, y luego en cada orden de compra enviada a ellos. El proveedor puede entonces cambiar su dirección y cualquier orden de compra subsiguiente debe tener la nueva dirección. Es más complicado que esto, pero ese es un requisito de ejemplo.
Opción 1 Coloque todas las columnas de direcciones como atributos en las diversas tablas. Copie los detalles del proveedor al PO a medida que se crean. Potencialmente almacenar copias múltiples de
Opción 2 Cree una tabla de direcciones por separado. Tener una clave externa del proveedor y tablas de órdenes de compra en la tabla de direcciones. Solo permite insertar y eliminar en la tabla de direcciones ya que las actualizaciones podrían cambiar más de lo que deseas. Entonces tendría una tarea programada que elimine todas las filas de la tabla de direcciones a las que ya no hace referencia ningún elemento, por lo que no se dejaron las filas no utilizadas. Quizás también tenga una restricción única en todas las columnas que no sean pk en la tabla de direcciones para detener también los duplicados.
Me inclino por la opción 2. ¿Hay una mejor manera?
EDITAR: debo mantener la dirección en la orden de compra tal como estaba cuando se envió. Además, es un poco más complicado que lo sugerí, ya que puede haber una dirección de envío y una dirección de facturación (también hay muchas otras que tienen información de dirección).
Después de un tiempo, borraré las órdenes de compra antiguas en masa según su fecha. Es después de esto que tenía la intención de recolectar los registros de direcciones que ya no están referenciados por nada (de lo contrario, parece que estoy creando una fuga).
¿Desea mantener un registro histórico de qué dirección estaba originalmente en la orden de compra?
En caso afirmativo, vaya a la opción 1; de lo contrario, guárdela en la tabla de proveedores y vincule cada orden de compra al proveedor.
Por cierto: un signo seguro de un diseño de base de datos deficiente es la necesidad de un trabajo automatizado para mantener los datos "limpios" o sincronizados. La opción 2 es probablemente una mala idea para esa medida
¿Por qué alguna de las filas en la tabla de direcciones quedará sin utilizar? Seguramente, ¿seguirían siendo señalados por la orden de compra que los usó?
Me parece que detener los duplicados debería ser la prioridad, negando así la necesidad de cualquier limpieza.
Creo que estoy de acuerdo con JohnFx ..
Otra cosa sobre las direcciones de correo (caracol), dado que desea incluir el país, supongo que desea enviar / enviar correos internacionales, por favor mantenga el campo de la dirección en su mayoría libre de texto. Es realmente molesto tener que crear un código postal de 5 dígitos cuando Noruega no tiene códigos postales, tenemos números de correos de 4 dígitos.
Los mejores campos serían:
- Nombre / Compañía
- Dirección (área de texto multilínea)
- País
Esto debería ser bastante global, si el sistema postal de EE. UU. Necesita códigos postales en un formato específico, luego inclúyalos también, pero hágalo opcional a menos que se seleccione EE. UU. Como país. Todo el mundo sabe cómo formatear la dirección en su país, por lo que siempre que mantenga los saltos de línea debería estar bien ...
De hecho, uso esto como una de mis preguntas de entrevista. El siguiente es un buen lugar para comenzar:
Addresses
---------
AddressId (PK)
Street1
... (etc)
y
AddressTypes
------------
AddressTypeId
AddressTypeName
y
UserAddresses (substitute "Company", "Account", whatever for Users)
-------------
UserId
AddressTypeId
AddressId
De esta forma, sus direcciones desconocen por completo cómo se usan, y sus entidades (Usuarios, Cuentas) tampoco saben nada directamente sobre las direcciones. Todo depende de las tablas de enlace que cree (UserAddresses en este caso, pero puede hacer lo que corresponda a su modelo).
Una sugerencia un tanto contradictoria para una base de datos potencialmente grande: continúe y coloque una dirección "principal" directamente en sus entidades (en la tabla Usuarios en este caso) junto con un campo "HasMoreAddresses". Parece repugnante en comparación con solo usar el diseño limpio anterior, pero puede simplificar la codificación para casos de uso típicos, y la desnormalización puede marcar una gran diferencia para el rendimiento.
En el caso de pedidos, nunca querrá actualizar la dirección ya que la dirección de la persona (o empresa) cambió si la orden se envió. Cumplió con el registro de dónde se envió realmente el pedido si hay un problema con el pedido.
La tabla de direcciones es una buena idea. Establezca una restricción única para que la misma entidad no pueda tener direcciones duplicadas. Aún puede obtenerlos, ya que los usuarios pueden agregar otro en lugar de buscarlos y si deletrean las cosas de forma ligeramente diferente (St. en lugar de Street) la restricción única no evitará eso. Copie los datos en el momento en que se crea la orden para la orden. Este es un caso en el que desea los registros múltiples porque necesita un registro histórico de lo que envió donde. Permitir inserciones y eliminaciones en la tabla no tiene sentido para mí, ya que no son más seguras que las actualizaciones e implican más trabajo para la base de datos. Se realiza una actualización en una llamada a la base de datos. Si una dirección cambia en su idea, primero debe eliminar la dirección anterior y luego insertar la nueva. No solo hay más llamadas a la base de datos sino dos veces más posibilidades de cometer un error de código.
He visto a todos los sistemas que usan la opción 1 entrar en problemas de calidad de datos. Después de 5 años, el 30% de todas las direcciones ya no estarán vigentes.
Opción 2, sin duda.
Algunas cosas importantes a tener en cuenta: es un aspecto importante del diseño para indicar a los usuarios cuando las direcciones están vinculadas entre sí. Es decir, la dirección corporativa es la misma que la dirección de envío; si desean cambiar la dirección de envío, ¿desean cambiar también la dirección corporativa o si desean especificar un nuevo muelle de carga? Este tipo de cosas, y la capacidad de presentar a los usuarios esta información y de cambiar las cosas con este tipo de granularidad es MUY importante. Esto también es importante sobre las actualizaciones; darle al usuario la granularidad para "dividir" las entradas. No es que este tipo de UI sea fácil de diseñar; de hecho, es una perra. Pero es realmente importante hacerlo; cualquier cosa menos seguramente causará que los usuarios se sientan muy frustrados y molestos.
También; Recomiendo encarecidamente mantener alrededor de los datos de la dirección anterior; no ejecute un proceso para limpiarlo. A menos que tenga una base de datos MUY ocupada, su software de base de datos podrá manejar el exceso de datos. De Verdad. Un error común que veo sobre las bases de datos es intentar sobreoptimizar; QUIERES optimizar al máximo tus consultas, pero NO quieres optimizar tus datos no utilizados. (De nuevo, si la actividad de su base de datos es MUY ALTA, es posible que necesite que algo lo haga, pero es casi seguro que su base de datos funcionará bien teniendo aún demasiados datos en las tablas). En la mayoría de las situaciones, en realidad es más ventajoso simplemente dejar crecer su base de datos de lo que es intentar optimizarla. (La eliminación de datos esporádicos de sus tablas no causará una reducción significativa en el tamaño de su base de datos, y cuando lo haga ... bueno, la reindexación que causa puede ser un gasto gigantesco en la base de datos).