uma tabela de itens que (potencialmente) conterá dezenas de milhões de registros.
Na verdade, não é tanto assim, considerando o que o SQL Server pode lidar com eficiência. Obviamente, lembro-me de um dos meus trabalhos anteriores, em que uma das maiores tabelas (um sistema de instância única) tinha 2 milhões de linhas, e foi com isso que eu já lidei. Em seguida, o próximo trabalho teve 17 instâncias de produção, com algumas tabelas com centenas de milhões de linhas e que foram agregadas em um Data Warehouse com várias tabelas de fatos com mais de 1 bilhão de linhas. Não me interpretem mal, não estou zombando de dezenas de milhões de linhas, apenas enfatizando que, com um bom modelo de dados e uma indexação adequada (e manutenção de índice), o SQL Server pode lidar muito .
Até 50% dos itens podem ser "não aprovados" a qualquer momento.
Hmm. Isso não parece certo. A taxa de "aprovar" entradas será metade da taxa de obtenção de novas entradas? Para cada 2 novas entradas, apenas 1 será "aprovado"? No seu exemplo de 2 milhões de linhas e 1 milhão cada para "aprovado" e "não aprovado", alguns anos depois com outros 10 milhões de entradas, você espera 6 milhões cada para "aprovado" e "não aprovado"? Ou será que os 1 milhão de "não aprovados" permanecerão um pouco constantes, de modo que, com 10 milhões de novas entradas, haverá 11 milhões de "aprovados" e ainda 1 milhão de "não aprovados"?
Os registros podem se tornar "aprovados", mas não vice-versa.
Isso é verdade hoje , mas as coisas mudam com o tempo e, portanto, sempre há a possibilidade de a empresa decidir permitir "não aprovação" ou talvez algum outro status, como "arquivado", etc.
Então, vejamos as opções:
Sinalizador (ou possivelmente TINYINT
"status")
- Um pouco mais lento para consultas de cada status
- Mais flexível ao longo do tempo / fácil de incorporar uma alteração como um terceiro estado (por exemplo, "Arquivado") com apenas um novo valor de status de Pesquisa. Nenhuma nova tabela (necessariamente), algum novo código, apenas algum código atualizado.
- Menos trabalho (ou seja, código, teste etc.) e menos espaço para erro ao atualizar uma única
TINYINT
coluna
- Menos complicado = menor custo de manutenção ao longo do tempo, menor tempo de treinamento para os novos funcionários descobrirem
- (possivelmente) Menor impacto no log de transações quando uma tabela é atualizada
- Só precisa de uma tabela de pesquisa para "RecordStatus" e FK entre as duas tabelas.
Duas tabelas separadas (uma para "aprovado" e uma para "não aprovado")
- Um pouco mais rápido para consultas de cada status
- Menos flexível ao longo do tempo / mais difícil de incorporar uma mudança como um terceiro estado (por exemplo, "Arquivado"); Um novo estado exigiria provavelmente outra tabela e, definitivamente, um código novo e atualizado.
- Mais trabalho (código, teste, etc.) e mais espaço para erros ao mover registros da tabela "Não aprovado" para a tabela "Aprovado"
- Mais complicado = custos de manutenção mais altos ao longo do tempo, mais tempo de treinamento para os novos funcionários descobrirem
- (possivelmente) Maior impacto no log de transações quando uma tabela é excluída e outra é inserida
- Não há necessidade de se preocupar com a " renovação da ID do item de ": a tabela não aprovado tem coluna ID, que é uma
IDENTITY
coluna e tabela aprovada tem coluna de ID que é não um IDENTITY
(uma vez que não é necessário lá). Portanto, os valores de ID permanecem consistentes à medida que o registro se move entre as tabelas.
Pessoalmente, eu me inclinaria para a única tabela com StatusID
coluna para começar. Usar duas tabelas parece uma otimização prematura complicada demais. Esse tipo de otimização pode ser discutido se / quando o número de registros estiver em várias centenas de milhões e a indexação não fornecer nenhum ganho de desempenho.