Preciso registrar as alterações em um valor específico, que é lido como parte de vários eventos que são rastreados separadamente, e poder visualizar um log de todos os valores posteriormente.
Acho que um exemplo descreverá melhor o problema: digamos que estou projetando um banco de dados para uma locadora de carros. A empresa tem uma lista de todos os seus carros e quer acompanhar a leitura do hodômetro de cada carro com a maior frequência possível. Assim, a empresa tem o hodômetro lido como parte de uma série de eventos diferentes que também são registrados, como aluguel, transferências, manutenções, etc.
O banco de dados pode ser algo assim (observe como OdometerReading é repetido):
Cars Rentals Transfers Maintenance
==== ======= ========= ===========
Car_ID Rental_ID Transfer_ID Maintenance_ID
SerialNumber Car_ID Car_ID Car_ID
... RentalDate TransferDate MaintenanceDate
OdometerReading OfficeFrom Notes
... OfficeTo OdometerReading
OdometerReading ...
...
Este é um bom caminho para continuar descendo? Parece estranho ter o mesmo campo (OdometerReading) em tabelas diferentes como esta.
Eu preciso ser capaz de gerar um relatório mostrando o histórico das leituras do hodômetro ao longo do tempo.
Eu poderia escrever uma consulta como:
SELECT RentalDate, OdometerReading
FROM Rentals
UNION ALL
SELECT TransferDate, OdometerReading
FROM Transfers
UNION ALL
SELECT MaintenanceDate, OdometerReading
FROM Maintenance
ORDER BY RentalDate
Ou eu poderia remover o campo OdometerReading de todas as tabelas e ter uma tabela de leituras do hodômetro assim:
Rentals OdometerReadings
======= ================
Rental_ID OdometerReading_ID
Car_ID Date
RentalDate Mileage
OdometerReadings_ID
...
--(other tables removed for brevity)
Desta forma, ao visualizar todos os eventos de locação, a leitura do hodômetro ainda pode ser incluída.
Mas isso parece me dar outros problemas. A data agora é registrada em dois lugares (por exemplo, Rentals.RentalDate e OdometerReadings.Date), e parece mais difícil determinar de onde veio uma leitura do hodômetro (embora eu acredite que você possa juntar a tabela OdometerReadings com tabelas de origem e filtro em potencial onde a tabela da direita é nula).
Qual é uma boa rota para registrar o mesmo valor como parte de vários registros/eventos diferentes, cada um com sua própria tabela?
Outra opção é usar herança de tabela simples para seus eventos, com o evento como o tipo base:
Isso significa que as consultas sobre propriedades gerais (data do evento, carro envolvido, etc.) atingem apenas uma tabela em vez de precisar unir as fontes distintas, sem duplicar os detalhes gerais. É claro que para relatar um determinado tipo de evento, você precisa ingressar na subtabela relevante e, para relatar vários tipos de evento, deve ingressar em várias subtabelas.
Alguns bancos de dados têm suporte embutido para essa forma de herança, o que faz com que ela se comporte um pouco mais automaticamente (um pouco como particionamento), o que significa que você tem um pouco menos de trabalho a fazer como desenvolvedor, mas isso é essencialmente um açúcar sintático e, como você pode ver, estrutura básica não é de todo ciência de foguetes.