Refactorización o actualización de bases de datos para manejar nuevas funciones

9

Varias respuestas a una pregunta de esquema de base de datos , sugirieron una tabla adicional para normalizar una base de datos para una característica que no forma parte de los requisitos actuales (una tabla de departamento de usuario para permitir una relación de muchos a muchos entre empleados / usuarios y diferentes departamentos que pueden pertenece a.).

No en contra de la normalización. Parece que cuando se trata del diseño de la base de datos, hay un fuerte impulso para incluir características que están 'seguros' de que alguien querrá en el futuro. ¿Es tan difícil agregar tablas / campos a la base de datos para acomodar características que hay una tendencia a sobre-diseñar? ¿No serían refactorizados o actualizados al igual que el resto de la aplicación si fuera necesario? Rehacer cosas nunca es divertido, pero se puede mover datos de una tabla a una nueva. Simplemente no estoy seguro de dónde terminará esta línea de pensamiento.

Editar: Hay mucha aversión a esto, me pregunto cuántos proyectos terminan sin agregar una característica que requiere un cambio drástico de la base de datos o se toman enfoques no normalizados como agregar un campo DepartmentID2 en lugar de una nueva tabla. La necesidad de múltiples departamentos para un empleado es un problema de dominio común. Simplemente no he notado muchos esquemas de bases de datos que están llenos de relaciones de muchos a muchos.

JeffO
fuente
1
+1 Gracias por preguntar esto. Aprendí mucho leyendo las respuestas a mi pregunta original, y este también es un hilo perspicaz.
Jim

Respuestas:

3

Hay un libro completo escrito sobre refactorización de bases de datos. Al igual que con la refactorización de código, hay formas estándar de refactorización de bases de datos. La única diferencia es que cuando se realiza la refactorización de código, no tiene que tener en cuenta el estado del objeto / código, mientras que en las bases de datos debe tener en cuenta los datos, porque perder datos no es bueno para los usuarios (ni para nadie, en realidad )

Puede leer más sobre la refactorización de bases de datos aquí .

Pramod
fuente
Este sitio es lo que provocó la pregunta en primer lugar;)
JeffO
14

Refactorizar el código es fácil: simplemente cambia el código y ejecuta tus pruebas de regresión.

Refactorizar las bases de datos es difícil: debe mover (una cantidad potencialmente enorme) de datos, asegurarse de que no se elimine nada, asegurarse de que las restricciones se mantengan en el nuevo esquema. Y, si tiene requisitos de auditoría en los datos, debe ser capaz de explicar por qué está organizado de manera diferente y poder hacer coincidir los datos pre-refoctores con los datos post-refactor. Además, ninguno de sus viejos respaldos coincidirá con el nuevo esquema, lo cual es otro riesgo.

Cosas de miedo.

Matthew Flynn
fuente
Las pruebas de bases de datos no deberían ser diferentes. Todos los cambios requieren una auditoría y afectan las copias de seguridad. ¿Cuántos datos vas a acumular antes de reconocer esta necesidad? Si ha convertido datos, esta característica sería aún más obvia.
JeffO
8
+1 para @Mathew Flynn. ¿Cuántos datos vas a acumular antes de reconocer esta necesidad? MILLONES de filas. Otro problema es que muchas veces SU aplicación no es lo único que usa la base de datos. La base de datos podría tener muchas aplicaciones trabajando con ella y es posible que ni siquiera sepa que existen (por ejemplo, aplicaciones "BI" salvajes). Los cambios en los esquemas de la base de datos dan miedo.
Angelo
2
A veces miles de millones de filas
HLGEM
1
Si está lidiando con miles de millones de filas, es mejor que sepa cómo moverlas
JeffO
3

Hay una delgada línea entre pasar mucho tiempo sobre ingeniería e invertir un poco de tu tiempo para agregar las características suficientes para ahorrar una cantidad considerable de tiempo en el futuro.

0x4B1D
fuente
1
Podrías argumentar por una instancia aislada o dos, pero ¿cuándo se acumulan demasiado los 'bits' de tiempo?
JeffO
Desde mi propia experiencia, en realidad es el caso de la gran mayoría de los proyectos. Pero también supongo que viene con experiencia y es muy subjetivo :) Me sorprendería si alguien puede darle una receta exacta (de ahí la 'línea fina').
0x4B1D
@ Jeff O: No va a ser 'bits'. Es necesaria una inversión del 10% o del 20% del tiempo de desarrollo en el fortalecimiento porque el sistema puede durar más que el período previsto originalmente y su empleo.
rwong
3

Creo que la teoría es que si incluye una tabla de enlaces para admitir una relación de muchos a muchos entre 2 tablas, incluso si realmente existen muchas relaciones de uno a uno en los datos, todos escribirán el SQL de tal manera que si alguna vez muchos a muchos es compatible, todo "funcionará".

En la práctica, no siempre he encontrado que esto sea cierto, pero supongo que el SQL está más cerca de lo que debe ser para admitir a muchos de lo que hubiera sido de otra manera.

Pero para llegar específicamente a su pregunta, en realidad hay una buena cantidad de dolor que convierte una relación de 1 a muchos en muchos a muchos. La razón es que SQL no está diseñado con los mismos tipos de objetivos de encapsulación que los objetos, y la mayoría de las consultas usan más tablas en la capa de la base de datos de las que las personas se sentirían cómodas para que un objeto en la capa empresarial tenga visibilidad.

Por lo tanto, un cambio en una relación de muchos a muchos afectará cada consulta que involucre las 2 tablas originales, a menudo un efecto en cascada mucho más amplio que el que ocurrirá en la capa empresarial. Por lo tanto, las personas hacen todo lo posible para evitar que esto suceda.

En mi humilde opinión, esto no sería necesario si tuviéramos un mejor lenguaje que SQL para especificar el álgebra relacional. Si fuera factible construir una consulta SQL pieza por pieza por objetos que no necesitaran visibilidad para cada tabla en la consulta, esto no sucedería. Cosas como LINQ (a SQL o a entidades) intentan resolver esto, pero es una solución muy compleja y difícil de optimizar (y he estado en grupos de usuarios de DBA donde se menciona LINQ y un gemido colectivo aumenta cada vez). Sueño con un lenguaje de base de datos que sea universalmente compatible con funciones de álgebra relacional de primera clase ...

Mientras tanto, sí, puede refactorizar de 1 a muchos a muchos a muchos, pero puede ser mucho trabajo.

psr
fuente
¿No vas a convertir cada relación en una relación de muchos a muchos?
JeffO
@Jeff O - No estoy seguro de entender tu pregunta. En caso de duda, modelizo tantos como muchos para evitar las trampas mencionadas en varias respuestas a su pregunta original. Me he vuelto un poco más cauteloso al respecto después de mantener bases de datos que realmente hicieron que casi todas las relaciones fueran de muchos a muchos, porque terminaron haciendo cosas como crear vistas que hicieron que las relaciones parecieran de 1 a muchos (que, en la práctica, todos lo fueron). Entonces tenían lo peor de ambos mundos. Nunca me ha pasado eso en mis propios diseños, pero está disponible como una advertencia.
psr
3

Por lo general, lo explico de esta manera a los PHB: el código es las paredes y el techo, la base de datos es la base.

Se pueden mover las paredes y cambiar el techo. Cambiar los cimientos requiere mucha excavación y reconstrucción de las paredes y el techo.

Lo que dicen los desarrolladores sin experiencia (y los profesores universitarios) es "sobre ingeniería" es lo que los desarrolladores experimentados llaman "pruebas futuras". A pesar de lo que dice la especificación, usted sabe lo que probablemente cambiará durante el ALM o dónde ocurrirán los problemas de rendimiento, por lo que desea comenzar con la estructura de la tabla.

La implementación de scripts de actualización en los servidores de los clientes es un proyecto no trivial y cada uno de los DBA de los clientes está por encima de ti, con el deseo de verificar tres veces todo. Algunas columnas y tablas adicionales no son tan malas después de todo.

jqa
fuente
1

La regla general es que si una relación es uno a uno, pero puede ser en el futuro de muchos a muchos a continuación, lo convierten en un muchos a muchos.

El empleado / departamento es un ejemplo clásico. En la mayoría de las pequeñas empresas, esta es efectivamente una relación de uno a muchos la mayor parte del tiempo . Sin embargo, casi siempre hay una situación en la que se convierte en muchos a muchos: uno de sus ingenieros asciende a la gerencia, pero aún es responsable de respaldar un producto que desarrolló mientras estaba en ingeniería o uno de sus vendedores se mudó a desarrollo de productos, pero debido a que tiene una relación cercana con un cliente importante, sigue siendo el vendedor principal de ese cliente.

No cuesta mucho más si uno a muchos se implementa como muchos a muchos, pero refactorizar una base de datos y una aplicación para admitir muchos a muchos es costoso y está lleno de dificultades.

James Anderson
fuente
Estoy de acuerdo en que hay muchos dominios maduros (como RR. HH.) En los que el cliente no anticipa la necesidad, pero usted sabe que es probable que suceda.
JeffO
0

Hay dos formas de ver el diseño de software (y probablemente muchas otras cosas): una vista táctica o una vista estratégica. Cada uno tiene su propia ventaja e inconvenientes.

Incluso con las modificaciones de software OO sigue siendo un dolor, no solo la parte de codificación es difícil, sino que el proceso de promover un cambio en la producción en entornos de queja (dado el estado actual de la tecnología) es irreal para sistemas grandes que se supone que son trabajando 24/7.

Sigo mi principio que dice: " Cuando sea posible, diseñe artefactos de software compartidos estratégicamente ". Esto puede parecer que va en contra del principio de YAGNI de alguna manera, sin embargo, esta es mi opinión. Este enfoque garantiza menos retrabajo en el costo de la complejidad y los recursos.

En su caso, las actividades requeridas para agregar una nueva tabla de unión incluirían: diseño, aprobación de diseño, cambio del esquema, reescritura de varios métodos para CRUD para 3 tablas (con la excepción de algunas lecturas), creación de índices, creación de GUI para CRUD para la nueva tabla, para permitir al usuario seleccionar las PK en crear, actualizar la nueva tabla, etc. Ah, y por cierto, no olvide las pruebas unitarias, las pruebas de aceptación del usuario, las pruebas del sistema y la promoción de la producción.

Si esto no es suficiente, la verdadera pesadilla proviene de la pérdida de información. Si no tenía la tabla de unión para empezar y decidió capturar las fechas en que se produjo la asociación / separación entre un empleado y un departamento, no podrá completar automáticamente la fecha en la tabla de unión. Debe ingresarlos manualmente (si tiene los datos).

Por lo tanto, es mejor prever esto desde el principio.

Ninguna posibilidad
fuente
Todo es mejor prever desde el principio.
JeffO
0

Como Matthew dijo anteriormente, la refactorización / cambio de bases de datos a menudo es más complicada en comparación con el software, ya que la gestión de datos también debe tenerse en cuenta. Existen técnicas que pueden ayudar, por ejemplo, a garantizar que tenga un conjunto adecuado de pruebas unitarias de base de datos, desacoplar aplicaciones cliente de su esquema base mediante el uso de una 'API DB': sprocs / views, etc.

mbaylon
fuente