none
Dúvida sobre criação de tabelas de LOG de aplicação. RRS feed

  • Pergunta

  • Boa tarde pessoal.

    Estou fazendo as tabelas de LOG do meu sistema, e tive uma idéia e gostaria de saber a opnião de vocês sobre, e se é possivel que eu tenha um bottleneck de insert em uma única tabela.

    Praticamente para toda tabela existente em meu banco, existe uma tabela 'cópia' de LOG. Por exemplo Clientes e Clientes_LOG.

    Os campos da tabela de log são os mesmos da tabela principal, + um campo DataModificacao e uma FK para tabela de Usuarios (UsuarioIdModificacao) que corresponde ao usuario logado na web responsável pela alteração/inserção do registro.

    Como os campos UsuarioIdModificacao e DataModificacao  são comuns para todas as tabelas de log então eu pensei em criar uma tabela padrão de log chamada LOG. E todas as tabelas de log especializarem dessa tabela LOG para que eu não precise criar os dois campos comuns em todas as tabelas de log, e nem tenha que fazer uma CONSTRAINT FK de todas as essas tabelas para a tabela de usuários.

    Considerando que praticamente todas as operações de banco serão realizadas um INSERT na tabela padrão de LOG fiquei me perguntando se não pode causar um gargalo de insert nessa tabela 'padrão' chamada LOG.

    O que vocês acham sobre isso? 

    Vale a pena? Porque considerando essa nova modelagem eu não teria centenas de FKs, mas teria um insert á mais em cada operação, porque antes de inserir na tabela_log eu teria que inserir primeiro na tabela LOG, pegar o id e inserir na tabela_log.

    Se eu considerar essa opção, como eu poderia evitar um gargalo nessa tabela LOG? Utilizar um GUID como chave primária para gravar em páginas diferente a cada insert?

    Pergunta Bonus!:

    Para as tabelas 'cópia' de log, exemplo Cliente_Log. Tive pensando em criar SEM chave primária para reduzir o custo de inserção. Mas não criar como Heap, e sim utilizar o campo ClienteFK como Index Clustered. Não vejo necessidade de uma tabela de log possuir uma PK. O que vocês acham disso também? Obrigado!

    Obrigado pela apoio e opnião, abraço!

    Eduardo Moura Schaukoski


    quarta-feira, 19 de março de 2014 19:38

Respostas

  • Boa noite Eduardo.

    Eu já fiz um trabalho desse de Log das modificações de banco.

    Eu não aconselho você utilizar essa tabela LOG geral não. Querendo ou não será um processamento maior na hora de inserir e não vejo muito ganho, nem em espaço de armazenamento, pelo contrário, terá um campo a mais nessa tabela pra você relacionar à tabela_log, que também terá esse campo.

    Se por um acaso ficar um pouco mais lento, ou mesmo não aguentar e dar lock, a explicação de que travou por causa do log não irá causar uma boa impressão.

    A respeito de criar uma FK com a tabela de usuário, nem isso eu faria. É LOG... você não vai utilizar esse relacionamento para consultas com o sistema, e mesmo se utilizar e não encontrar o usuário (porque alguém apagou o usuário) você só informa isso.

    PK? Também não vejo necessidade... eu criei somente um identity bigint lá por ter, pra conseguir um order by desc as vezes...

    Uma outra dica que dou é tentar alimentar essas tabelas de log via trigger... o que vai ter de tabela que o desenvolvedor esqueceu de alimentar, vai ser muito comum, além de ter um trabalho a mais para ajustar tb o código do Log. Eu fiz uma trigger de banco, capturando create/alter table, que quando adiciona uma coluna nova na tabela ela já ajusta a tabela de LOG com a nova coluna e já sai armazenando... Criou uma tabela??? já cria a tabela de log... adicionou um campo??? já ajusta a tabela de log e a trigger que alimenta ela.

    Falar pra você que nunca tive problemas de performance dessa forma, e nem de programação. Milhões e milhões de registros e sempre rápido.

    Dica: Excluiu um campo da tabela??? Deixa esse campo na tabela de LOG... você não vai mais mencionar ela nos inserts, mas ela existiu e teve conteúdo um dia.

    Espero ter ajudado.

    Abç


    André Duarte

    quinta-feira, 20 de março de 2014 03:52
  • Olá Eduardo.

    Entendi sua explicação sim. Eu já fiz dessa forma também e nesse caso eu adicionei a coluna do IdUsuario na tabela principal, mas acho sua solução boa!!

    Colocando na tabela principal a sua trigger fica simples de tudo!
    INSERT INTO TABELA_LOG (n, n...) SELECT n, n... FROM inserted

    Lembrando: É um processamento a mais e consumo do seu tempdb.

    Vlw


    André Duarte

    quinta-feira, 20 de março de 2014 12:53
  • Então.. ontem mesmo estava lendo sobre os fix do 2008 e tinha lá uma correção desse CDC ai, ai vi o que era... mas não li muito tb e nem utilizei... Se um dia utilizar e ver que realmente eliminou tuuudo isso que discutimos (rs), te dou um toque.

    Vlw, e boa sorte ai!


    André Duarte

    quinta-feira, 20 de março de 2014 13:14

Todas as Respostas

  • Boa noite Eduardo.

    Eu já fiz um trabalho desse de Log das modificações de banco.

    Eu não aconselho você utilizar essa tabela LOG geral não. Querendo ou não será um processamento maior na hora de inserir e não vejo muito ganho, nem em espaço de armazenamento, pelo contrário, terá um campo a mais nessa tabela pra você relacionar à tabela_log, que também terá esse campo.

    Se por um acaso ficar um pouco mais lento, ou mesmo não aguentar e dar lock, a explicação de que travou por causa do log não irá causar uma boa impressão.

    A respeito de criar uma FK com a tabela de usuário, nem isso eu faria. É LOG... você não vai utilizar esse relacionamento para consultas com o sistema, e mesmo se utilizar e não encontrar o usuário (porque alguém apagou o usuário) você só informa isso.

    PK? Também não vejo necessidade... eu criei somente um identity bigint lá por ter, pra conseguir um order by desc as vezes...

    Uma outra dica que dou é tentar alimentar essas tabelas de log via trigger... o que vai ter de tabela que o desenvolvedor esqueceu de alimentar, vai ser muito comum, além de ter um trabalho a mais para ajustar tb o código do Log. Eu fiz uma trigger de banco, capturando create/alter table, que quando adiciona uma coluna nova na tabela ela já ajusta a tabela de LOG com a nova coluna e já sai armazenando... Criou uma tabela??? já cria a tabela de log... adicionou um campo??? já ajusta a tabela de log e a trigger que alimenta ela.

    Falar pra você que nunca tive problemas de performance dessa forma, e nem de programação. Milhões e milhões de registros e sempre rápido.

    Dica: Excluiu um campo da tabela??? Deixa esse campo na tabela de LOG... você não vai mais mencionar ela nos inserts, mas ela existiu e teve conteúdo um dia.

    Espero ter ajudado.

    Abç


    André Duarte

    quinta-feira, 20 de março de 2014 03:52
  • Obrigado pela resposta André Duarte, excelente explicação.

    Ontem mesmo cheguei a conclusão com um DBA que realmente essa tabela de LOG não tem muitas vantagens portanto não tem sentido!

    Concordo com seu ponto de vista sobre PKs e FKs nas tabelas de log, bom saber da sua opnião.

    Sobre utilizar triggers para os insert dos logs eu concordo com você, mas existe um detalhe. As tabelas de Log possuem um código de uma tabela de usuários de sistema, que corresponde ao usuário responsável pela alteração do registro. Esse código eu não tenho ele nas tabelas 'normais', apenas nas tabelas de log. A trigger é feita na tabela 'normal' como você faz para ter o código do usuário no momento da trigger, sendo que esse campo não faz parte da tabela? 

    Eu estava imaginando em na aplicação sempre que abrir uma transaction adicionar em uma tabela temporária #UsuarioIdSistema e então nma trigger eu pegar sempre esse Id. O que você acha?

    Não sei se consegui ser bem claro na explicação, abraço!

    quinta-feira, 20 de março de 2014 11:52
  • Olá Eduardo.

    Entendi sua explicação sim. Eu já fiz dessa forma também e nesse caso eu adicionei a coluna do IdUsuario na tabela principal, mas acho sua solução boa!!

    Colocando na tabela principal a sua trigger fica simples de tudo!
    INSERT INTO TABELA_LOG (n, n...) SELECT n, n... FROM inserted

    Lembrando: É um processamento a mais e consumo do seu tempdb.

    Vlw


    André Duarte

    quinta-feira, 20 de março de 2014 12:53
  • Valeu André, obrigado pelas respostas e opiniões!

    Colocando o IdUsuario na tabela principal é possível de utilizar o CDC, já ouviu falar? Achei uma boa opção mas é um recurso do SqlServer 2008. Pelo que li parece ser perfeito para o que discutimos aqui, mas não sei se é muito utilizado porque nunca tinha ouvido falar até esses dias mesmo. Não sei se existe algum 'efeito colateral' com ele, mas me pareceu ótimo!

    Um abraço!

    Eduardo Moura Schaukoski

    quinta-feira, 20 de março de 2014 13:02
  • Então.. ontem mesmo estava lendo sobre os fix do 2008 e tinha lá uma correção desse CDC ai, ai vi o que era... mas não li muito tb e nem utilizei... Se um dia utilizar e ver que realmente eliminou tuuudo isso que discutimos (rs), te dou um toque.

    Vlw, e boa sorte ai!


    André Duarte

    quinta-feira, 20 de março de 2014 13:14
  • Haha!

    Abraços, obrigado!

    quinta-feira, 20 de março de 2014 13:19