Estou tentando criar uma tabela de log para armazenar eventos em um company
-object e estou com medo de estar seguindo o caminho errado. Cheguei à conclusão de que devo registrar diferentes tipos de dados na mesma coluna e não parece certo. Vou explicar o caso de uso básico com 2 tabelas; company
e user
.
company
- id int
- name nvarchar
- description
user
- id int
- name nvarchar
- company int (references company.id)
Agora, digamos que eu queira registrar diferentes tipos de eventos no company
-object. Eu faria uma tabela de log chamada company_log
e company_log_type
armazenaria eventos lá. Essas tabelas ficariam assim:
company_log
- id int
- old_value nvarchar
- new_value nvarchar
- log_type int (references company_log_type.id)
company_log_type
- id int
- name
Exemplos de eventos interessantes são
- O nome da empresa foi alterado
- A descrição da empresa foi alterada
- Um usuário foi adicionado à empresa
- Um usuário foi removido da empresa
Para os dois eventos anteriores, eu armazenaria o tipo de evento, o valor antigo e o novo valor. Isso funciona bem, desde que eu pare aqui. No entanto, se eu quiser registrar os 2 eventos anteriores, precisarei armazenar diferentes tipos de dados na mesma coluna. As mudanças ficariam mais ou menos assim:
old_value new_value log_type
----------------------------------------------
Acme PiedPiper CompanyNameChanged
NULL 132 UserAdded
97 NULL UserRemoved
Neste ponto, eu precisaria armazenar o valor textual antigo/novo do nome da empresa, bem como a id do usuário adicionado recentemente. Você pode ver que já estou indo na direção errada, e é aqui que Eu peço ajuda. Eu tenho 2 perguntas:
Devo usar apenas sql_variant
-datatype ou, se isso for considerado um design ruim, qual seria uma maneira sensata de armazenar esses eventos de log?
Desde já, obrigado.
Existem restrições e dificuldades com o tipo sql_variant. Consulte o MSDN para obter detalhes: Variante SQL
Como você já "sente", também pode ter problemas com a transmissão e a conversão posteriormente. Para exemplos, consulte 10 razões para converter tipos de dados do SQL Server explicitamente .
Eu tentaria evitar variantes neste e em qualquer outro caso, se possível.
Mas seu problema básico não é o tipo de variante, mas mais o design da mesa. Mesmo se você tivesse apenas valores inteiros em suas tabelas de log, eu ainda pensaria em alterá-lo para um pouco mais de normalização.
No entanto, depois de pensar sobre o seu problema, cheguei a outra abordagem que talvez valha a pena tentar: por que não projetar sua tabela de log da mesma forma que a tabela original.
Por exemplo:
Dessa forma, você pode adicionar uma nova linha sempre que a linha original for alterada e adicionar a linha anterior à tabela de log. Isso fornecerá um histórico completo das linhas sem problemas de tipo de dados.
Você também pode limitar o registro a alterações de colunas específicas. Acho que você vai precisar de gatilhos para perceber isso.
Ele fornecerá várias tabelas de log, mas se você as mantiver semelhantes
log_type
elog_stamp
ainda poderá consultar todo o histórico de quaisquer alterações (das tabelas rastreadas) porUNION
elas.Encontrei outra dúvida onde esta e outras formas possíveis de resolver são explicadas bem detalhadamente: Como armazenar registros históricos em uma tabela de históricos no SQL Server