¿Cómo prevenir registros huérfanos en tablas detalladas de bases de datos normalizadas?

StackOverflow https://stackoverflow.com/questions/448592

  •  19-08-2019
  •  | 
  •  

Pregunta

Tengo que mantener una base de datos antigua que no está correctamente normalizada. Por ejemplo, hay una tabla de proyecto que ha crecido (o tal vez se ha multiplicado) para tener 5 o más columnas de fechas diferentes, para que se ordenen diferentes hitos del proyecto hasta la fecha de entrega. También hay varias tablas, cada una con columnas para direcciones de calles, direcciones de correo o enlaces web.

Me gustaría normalizar la estructura, crear tablas para direcciones, fechas programadas y similares, y las tablas necesarias para permitir relaciones 1: N (dirección por cliente, fecha de vencimiento por proyecto, etc.).

En este momento no estoy completamente seguro de cómo manejar los cambios en los datos en las tablas de detalles. Considere, por ejemplo, el cambio de la dirección de entrega de un cliente. Cambiar los datos en la tabla de direcciones está fuera de discusión, porque más de un registro (posiblemente en más de una tabla) podría hacer referencia a ese registro. Agregar un nuevo registro de dirección podría dejar huérfano el registro anterior si ninguna otra fila tiene una relación de clave externa.

He pensado en las siguientes formas de manejar esto:

  • Agregue un nuevo registro de detalles y compruebe en un activador de actualización de la tabla maestra si el registro de detalles anterior debe eliminarse. Esto requeriría conocimiento sobre todas las tablas que tienen relaciones con la tabla de detalles, en todas ellas o en un sproc. No me gusta esta pérdida de separación. También implicaría más tablas en la transacción activa.

  • Deje que el disparador intente eliminar el registro de detalle anterior y detecte cualquier error. Esto simplemente se siente mal.

  • Vive con el registro huérfano y realiza una tarea de mantenimiento periódica para limpiar todas las tablas de detalles.

¿Cuál es la forma preferida de manejar los cambios de datos en las tablas de detalles que están vinculadas a varias tablas maestras? ¿Algún consejo para leer sobre esto?

¿Fue útil?

Solución

Parte del problema puede ser el diseño del esquema original: las claves externas apuntan en la dirección incorrecta, tratando las direcciones, los números de teléfono, etc. como maestros en lugar de detalles. Esto puede ser conveniente cuando desea que todos los usos de una dirección determinada se actualicen a la vez, pero en mi experiencia siempre se traduce en demasiados casos excepcionales difíciles, por ejemplo, una persona en una ubicación se mueve, por lo que debe romper su enlace frente a un todo mudanza de hogar u oficina para que actualice el registro existente. Si intenta ocultar este detalle al usuario en la pantalla CRUD, terminará en una situación en la que simplemente no hace lo que quiere.

Si se hace de esa manera solo para colapsar valores duplicados, es efectivamente una desnormalización de la base de datos: la mera existencia de la fila de direcciones no tiene sentido. La única diferencia es que, a diferencia de la mayoría de las desnormalizaciones, intenta ganar eficiencia espacial en lugar de velocidad. Crear una tabla de enlaces en ese punto es simplemente agravar el problema.

Si desea, por ejemplo, varias direcciones por contacto, haga de las direcciones una tabla de detalles con una clave externa que apunte al contacto principal y no se preocupe por los valores de direcciones duplicados porque son solo valores De lo contrario, convierta a Address en una entidad real: agregue un campo de título o descripción y una pantalla CRUD para que pueda sostenerse por sí mismo como una entidad.

Otros consejos

Vive con el registro huérfano y realiza una tarea de mantenimiento periódica para limpiar todas las tablas de detalles.

Creo que está borrando los casos de eliminación y actualización.

Si tiene el cliente a y el cliente b, y ambos usan la misma dirección, eso se reflejaría en los registros de una tabla relacional (por ejemplo, ClientAddresses, aunque si está almacenando direcciones para varias entidades, estoy seguro de que será más complejo que eso)

Creo que si dos clientes comparten y dirigen y es incorrecto para el cliente a, también sería incorrecto para el cliente b (es decir, error de entrada de datos), pero si está seguro de que no desea que el cliente cambie a el hecho a la información de la dirección base, elimine el registro de asociación (eliminar de ClientAddresses) y agregue una nueva dirección. Cuando realice la eliminación de la tabla relacional (presumiblemente de un procedimiento almacenado), verifique si hay algún otro registro que se refiera al registro de dirección que se está disociando, si no se elimina de la tabla base.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top