Antecedentes
Escribo muchos informes grandes y generalmente mantengo una base de datos de registros de salud grandes (escribo SP, funciones, trabajos, etc.). El esquema original, y el software que lo usa, es de un proveedor diferente, por lo que no puedo cambiar mucho estructuralmente. Hay muchos registros que requieren seguimiento, como laboratorios, procedimientos, vacunas, etc., y están dispersos en docenas de tablas, muchas de las cuales están hinchadas y mal indexadas (he podido solucionar esto de alguna manera).
El problema
El problema es que debido a que tenemos poco control sobre el DB, y dado que puede cambiar desde cualquier actualización o parche, hace que escribir y mantener estos informes sea difícil y tedioso, especialmente cuando hay una gran cantidad de superposición. Todo lo que se necesita es un parche y estoy atascado reescribiendo grandes porciones de una docena de informes. Además, las consultas se ofuscan rápidamente y se ralentizan a medida que las uniones, las selecciones anidadas y las aplicaciones se acumulan.
Mi solución"
Mi plan era escribir todos estos registros en una tabla "general" y escribir desencadenantes en las tablas originales para mantener los registros en esta tabla agregada. Por supuesto, tendría que asegurarme de que mis disparadores estuvieran intactos después de las actualizaciones, pero esto sería mucho más fácil desde el punto de vista de la mantenibilidad, y solo haciendo referencia a los datos.
La tabla sería delgada y larga, almacenando solo los datos requeridos, algo como esto:
CREATE TABLE dbo.HCM_Event_Log (
id INT IDENTITY,
type_id INT NULL,
orig_id VARCHAR(36) NULL,
patient_id UNIQUEIDENTIFIER NOT NULL,
visit_id UNIQUEIDENTIFIER NULL,
lookup_id VARCHAR(50) NULL,
status VARCHAR(15) NULL,
ordered_datetime DATETIME NULL,
completed_datetime DATETIME NULL,
CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id)
)
Luego tendría varias tablas relacionales para cosas como type_id y agrupaciones de elementos.
Estoy empezando a adivinar esta idea, ya que varias de estas tablas se escriben bastante, los SP e informes que escribiría también harían referencia a los datos. Por lo tanto, me preocupa que esta tabla se convierta en una pesadilla de bloqueo de registros y rendimiento con tanta E / S.
Mi pregunta
¿Es una mala o una buena idea? Me doy cuenta de que cada situación es diferente en SQL Server (2008 r2 Standard Edition BTW) y la regla de "a veces", pero realmente solo estoy buscando consejos generales.
Comencé a considerar el uso de un intermediario de servicios, pero solo realizaría actualizaciones / inserciones simples ( consulte la alternativa a la respuesta aceptada ). Los datos en muchos casos deben ser en tiempo real, por lo que el uso de una base de datos de respaldo no funcionaría realmente. El rendimiento ya es un problema para nosotros, pero la mayor parte de eso está relacionado con el hardware que se resolverá pronto.
fuente
Respuestas:
Si te entendí correctamente,
Lo abordaría así:
En este caso, puede ajustar la estructura y los índices de su base de datos para mejorar el rendimiento de sus informes, sin afectar el sistema de terceros. A menos que la estructura de datos original cambie drásticamente, la lógica de sus consultas para sus informes no cambiaría si cambia la base de datos de terceros. Tendría que ajustar solo el proceso de sincronización.
El proceso de sincronización es efectivamente el proceso de conversión : convierte datos de bases de datos de terceros en la estructura que necesita. Parte de este proceso de conversión podría estar solucionando cualquier problema de normalización que pueda tener la base de datos de terceros original. Solo esta parte del sistema tiene que conocer y depender de la estructura interna del sistema de terceros. Sus informes principales y consultas principales dependerán solo de su base de datos.
Por lo tanto, el punto principal es: separar y limitar la parte de su sistema que depende de los componentes internos de un sistema de terceros.
actualizar
En cuanto a los requisitos en tiempo real. Por cierto, siempre pensé que la definición de "tiempo real" es "tiempo de respuesta garantizado", no "un tiempo de respuesta pequeño". Depende de su aplicación, por supuesto. En mi práctica, es suficiente si sincronizo dos bases de datos dentro de un minuto del cambio detectado. Si un usuario ve un informe en la pantalla y algunos cambios en los datos subyacentes, el informe debe volver a ejecutarse de alguna manera para reflejar este cambio. Puede sondear los cambios o escuchar algún evento / mensaje, pero la consulta del informe debe ejecutarse nuevamente para mostrar los últimos cambios.
Ya tiene la intención de escribir disparadores para capturar los cambios en las tablas originales y escribir estos cambios en una tabla genérica. Por lo tanto, capture los cambios como pretendía, pero escríbalos en tablas correctamente normalizadas, no en una sola.
Entonces, este es un caso extremo: la conversión de la estructura de datos de terceros en su estructura de datos interna se realiza en los disparadores que se activan en las
INSERT/UPDATE/DELETE
tablas de terceros. Puede ser complicado El código de los disparadores dependería de la estructura interna de ambos sistemas. Si la conversión no es trivial, puede retrasar el originalINSERT/UPDATE/DELETE
hasta el punto de su falla. Si hay un error en su activador, puede afectar la transacción original hasta el punto de su falla. Si el sistema de un tercero cambia, puede romper su disparador, lo que provocaría un error en las transacciones del sistema de terceros.Caso menos extremo. Para hacer que el código de sus desencadenantes sea más simple y menos propenso a errores, escriba todos los cambios capturados en algunas tablas de etapas / auditoría / diferencias, establezca algún indicador / envíe un mensaje de que hay cambios pendientes e inicie el proceso de conversión principal que iría a través de estas tablas intermedias y realizar la conversión. Lo principal aquí es que el proceso de conversión potencialmente pesado debe ocurrir fuera del alcance de la transacción original.
En un segundo vistazo, se parece bastante a su sugerencia original en la pregunta. Pero, la diferencia es: las tablas de capturar todo contienen datos solo temporalmente; la cantidad de datos es pequeña, solo lo que ha cambiado; no tiene que ser una sola mesa; finalmente, los datos se almacenarán en tablas permanentes separadas debidamente normalizadas, de las cuales usted tiene control total, que son independientes del sistema de terceros y que puede ajustar para sus consultas.
fuente
Por supuesto, colóquelo en un conjunto estandarizado de tablas para que pueda modificar la etapa de importación en lugar de tener que cambiar informes complejos y consultas. Pero los datos aún deben normalizarse, lo que requerirá tablas múltiples (pero con buenos índices).
Como otros han mencionado, no use disparadores, sincronice en lotes.
No se preocupe por muchas uniones, cuando los datos se normalizan e indexan correctamente, estos no agregan ningún costo significativo o carga administrativa.
El momento de desnormalizar en algo como un almacén de datos es cuando necesita poder realizar muchos tipos diferentes de consultas sobre los datos que no puede predecir. Tiene sus propias desventajas y gastos generales y debe usarse donde sea apropiado, no como un recurso de referencia.
fuente
Trabajé con una situación muy similar como esta en el pasado en una empresa de fabricación 24x7 y finalmente decidí usar la replicación transaccional. Es posible configurar DDL para que se replique de manera que pueda enviar cualquier cambio que el parche cambie al suscriptor. Obviamente, hay pros y contras en todo y debe sopesarlos para determinar qué puede respaldar contra lo que funciona mejor para la empresa.
En el lado positivo:
Sin embargo, hay inconvenientes:
fuente
Los disparadores tienen tantos problemas que debes evitarlos:
Una mejor opción es un trabajo que copia periódicamente los datos en una nueva tabla. Sus informes pueden ejecutarse de la copia. Un trabajo que copia filas es fácil de escribir y mantener, y no hay riesgo de que afecte el funcionamiento de la aplicación de terceros.
fuente
NOCOUNT
? 4. No habría desencadenantes en la tabla de destino, y podría asegurar lo mismo para los demás.