fundo
Escrevo muitos relatórios grandes para e geralmente mantenho um banco de dados grande de registros de saúde (escreva SPs, funções, trabalhos etc.). O esquema original e o software que o utiliza são de um fornecedor diferente, portanto não posso mudar muito estruturalmente. Existem muitos registros que exigem rastreamento, como laboratórios, procedimentos, vacinas etc., e estão espalhados por dezenas de tabelas, muitas das quais estão inchadas e mal indexadas (consegui corrigir isso de alguma forma).
O problema
O problema é que, como temos pouco controle sobre o banco de dados e, como ele pode mudar de qualquer atualização ou patch, torna difícil escrever e manter esses relatórios difíceis e entediantes - especialmente quando há muita sobreposição. Só é preciso um patch e estou preso reescrevendo grandes porções de uma dúzia de relatórios. Além disso, as consultas rapidamente ficam ofuscadas e lentas à medida que as junções, aninhados selecionam e se aplicam.
Minha "solução"
Meu plano era gravar todos esses registros em uma tabela "catch-all" e gravar gatilhos nas tabelas originais para manter os registros nessa tabela agregada. É claro que eu precisaria garantir que meus gatilhos estivessem intactos após as atualizações, mas isso seria muito mais fácil do ponto de vista de manutenção e apenas referenciando os dados.
A tabela seria fina e longa, armazenando apenas os dados necessários, algo como isto:
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)
)
Então, eu teria várias tabelas relacionais para coisas como o type_id e os agrupamentos de itens.
Estou começando a adivinhar essa idéia, já que várias dessas tabelas são gravadas um pouco, os SPs e os relatórios que eu estaria escrevendo também referenciam os dados. Por isso, estou preocupado que essa tabela se torne um pesadelo de bloqueio e desempenho de registros com tanta E / S.
Minha pergunta
É uma má ou uma boa ideia? Sei que todas as situações são diferentes no SQL Server (2008 r2 Standard Edition BTW) e a regra "às vezes", mas estou apenas procurando conselhos gerais.
Comecei a considerar o uso de um corretor de serviços, mas só estaria executando atualizações / inserções simples ( consulte a alternativa à resposta aceita ). Os dados em muitos casos precisam ser em tempo real, portanto, o uso de um banco de dados de backup não funcionaria realmente. O desempenho já é um problema para nós, mas a maior parte está relacionada ao hardware que será resolvida em breve.
fonte
Respostas:
Se eu entendi direito,
Eu abordaria assim:
Nesse caso, você pode ajustar a estrutura e os índices do seu banco de dados para melhorar o desempenho dos seus relatórios, sem afetar o sistema de terceiros. A menos que a estrutura de dados original mude drasticamente, a lógica de suas consultas para seus relatórios não mudará se o banco de dados de terceiros for alterado. Você precisaria ajustar apenas o processo de sincronização.
O processo de sincronização é efetivamente o processo de conversão - você converte dados do banco de dados de terceiros na estrutura necessária. Parte desse processo de conversão pode estar corrigindo quaisquer problemas de normalização que o banco de dados de terceiros original possa ter. Somente essa parte do sistema precisa conhecer e depender da estrutura interna do sistema de terceiros. Seus principais relatórios e consultas principais dependeriam apenas do seu banco de dados.
Portanto, o ponto principal é - separe e limite a parte do seu sistema que depende de componentes internos do sistema de terceiros.
atualizar
Em relação à exigência em tempo real. BTW, eu sempre pensei que a definição de "tempo real" é "tempo de resposta garantido", não "um pequeno tempo de resposta". Depende da sua aplicação, é claro. Na minha prática, basta sincronizar dois bancos de dados dentro de um minuto após a alteração detectada. Se um usuário vê um relatório na tela e algumas alterações de dados subjacentes, o relatório deve ser executado de alguma forma para refletir essa alteração. Você pode pesquisar alterações ou ouvir algum evento / mensagem, ainda que a consulta do relatório precise ser executada novamente para mostrar as alterações mais recentes.
Você já pretende gravar gatilhos para capturar alterações nas tabelas originais e gravá-las em uma tabela genérica. Portanto, capture as alterações conforme desejado, mas grave-as em tabelas normalizadas adequadamente, e não em uma única.
Portanto, esse é um caso extremo - a conversão da estrutura de dados de terceiros em sua estrutura de dados interna é realizada nos gatilhos acionados em
INSERT/UPDATE/DELETE
tabelas de terceiros. Pode ser complicado. O código dos gatilhos dependeria da estrutura interna dos dois sistemas. Se a conversão não for trivial, pode atrasar o originalINSERT/UPDATE/DELETE
até o ponto de falha. Se houver um bug no seu gatilho, isso poderá afetar a transação original ao ponto da falha. Se o sistema de terceiros for alterado, isso poderá interromper o gatilho, o que causaria falha nas transações do sistema de terceiros.Caso menos extremo. Para tornar o código de seus gatilhos mais simples e menos propenso a erros, grave todas as alterações capturadas em algumas tabelas de teste / auditoria / diff, defina algum sinalizador / envie uma mensagem informando que há alterações pendentes e inicie o processo de conversão principal através dessas tabelas intermediárias e realize a conversão. O principal aqui é que o processo de conversão potencialmente pesado deve ocorrer fora do escopo da transação original.
À primeira vista, parece bastante com a sua sugestão original na pergunta. Mas a diferença é: as tabelas de captura de todos retêm dados apenas temporariamente; a quantidade de dados é pequena - exatamente o que mudou; não precisa ser uma única tabela; eventualmente, os dados serão armazenados em tabelas permanentes, normalizadas e adequadamente separadas, das quais você tem controle total, independentes do sistema de terceiros e que podem ser ajustadas para suas consultas.
fonte
De qualquer forma, coloque-o em um conjunto padronizado de tabelas para que você possa ajustar o estágio de importação em vez de precisar alterar relatórios e consultas complexas. Mas os dados ainda devem ser normalizados, o que exigirá tabelas múltiplas (mas com bons índices).
Como outros já mencionaram, não use gatilhos, sincronize em lotes.
Não se preocupe com muitas associações, quando os dados são normalizados e indexados adequadamente, eles não adicionam nenhum custo ou ônus de gerenciamento significativo.
O momento de desnormalizar algo como um data warehouse é quando você precisa fazer muitos tipos diferentes de consulta nos dados que não pode prever. Ele tem suas próprias desvantagens e despesas gerais e deve ser usado onde for apropriado, não como um item essencial.
fonte
Eu trabalhei com uma situação muito semelhante como essa no passado em uma empresa de manufatura 24x7 e finalmente decidi usar a replicação transacional. É possível configurar o DDL para ser replicado de forma que você possa enviar o que quer que os patches mudem para o assinante. Obviamente, existem prós e contras em tudo e é preciso ponderá-los para determinar o que você pode apoiar e o que funciona melhor para a empresa.
Pelo lado positivo:
Existem contras, no entanto:
fonte
Os gatilhos têm tantos problemas que você deve evitá-los:
Uma opção melhor é um trabalho que copia os dados periodicamente para uma nova tabela. Seus relatórios podem ser executados da cópia. Um trabalho que copia linhas é fácil de gravar e manter, e não há risco de afetar a operação do aplicativo de terceiros.
fonte
NOCOUNT
? 4. Não haveria gatilhos na tabela de destino, e eu poderia garantir o mesmo para os outros.