Vou compartilhar com você meu design e é diferente dos dois designs, pois exige uma tabela por cada tipo de entidade. Encontrei a melhor maneira de descrever qualquer design de banco de dados através do ERD, aqui está o meu:
Neste exemplo, temos uma entidade chamada employee . A tabela user guarda os registros de seus usuários, e entity e entity_revision são duas tabelas que mantêm o histórico de revisões de todos os tipos de entidade que você terá em seu sistema. Veja como esse design funciona:
Os dois campos de entity_id e revision_id
Cada entidade em seu sistema terá um ID de entidade exclusivo. Sua entidade pode passar por revisões, mas seu entity_id permanecerá o mesmo. Você precisa manter esse ID de entidade na tabela de funcionários (como uma chave estrangeira). Você também deve armazenar o tipo de sua entidade na tabela de entidades (por exemplo, 'funcionário'). Agora, quanto ao revision_id, como o nome mostra, ele acompanha as revisões da sua entidade. A melhor maneira que encontrei para isso é usar o employee_id como sua revision_id. Isso significa que você terá IDs de revisão duplicados para diferentes tipos de entidades, mas isso não é um prazer para mim (não tenho certeza sobre o seu caso). A única observação importante a ser feita é que a combinação de entity_id e revision_id deve ser única.
Há também um campo de estado na tabela entity_revision que indica o estado da revisão. Ele pode ter um dos três estados: latest
, obsolete
ou deleted
(não contando com a data de revisões ajuda muito a aumentar suas consultas).
Uma última observação em revision_id, não criei uma chave estrangeira conectando employee_id a revision_id porque não queremos alterar a tabela entity_revision para cada tipo de entidade que poderemos adicionar no futuro.
INSERÇÃO
Para cada funcionário que você deseja inserir no banco de dados, você também vai adicionar um registro de entidade e entity_revision . Esses dois últimos registros ajudarão você a controlar quem e quando um registro foi inserido no banco de dados.
ATUALIZAR
Cada atualização para um registro de funcionário existente será implementada como duas inserções, uma na tabela de funcionários e outra na entidade_revisão. O segundo ajudará você a saber por quem e quando o registro foi atualizado.
ELIMINAÇÃO
Para excluir um funcionário, um registro é inserido em entity_revision informando a exclusão e concluída.
Como você pode ver nesse design, nenhum dado é alterado ou removido do banco de dados e, mais importante, cada tipo de entidade requer apenas uma tabela. Pessoalmente, acho esse design realmente flexível e fácil de trabalhar. Mas não tenho certeza sobre você, pois suas necessidades podem ser diferentes.
[ATUALIZAR]
Tendo suportado partições nas novas versões do MySQL, acredito que meu design também vem com uma das melhores performances. Pode-se particionar entity
tabela usando type
campo enquanto particionar entity_revision
usando seu state
campo. Isso aumentará SELECT
de longe as consultas, mantendo o design simples e limpo.