Eu tenho essas tabelas:
create table data (
id int identity not null,
ref int not null
);
create table reference (
refid int not null
);
com aproximadamente 2 milhões de linhas em dados e aproximadamente 200 mil linhas em referência. Eu adiciono cerca de 5.000 linhas aos dados todos os dias, resultando em 500-5.000 linhas adicionais em referência por dia.
Na maioria dos casos, preciso salvar apenas uma referência para uma coluna de dados (várias entradas de dados podem ter a mesma referência), mas em alguns casos (atualmente cerca de 0,1%) preciso salvar mais de uma referência.
Eu provavelmente poderia usar uma terceira tabela como:
create table data_reference (
dataid int not null,
refid int not null
);
criar um mapeamento an:m mas para a maioria dos valores não vai ter nenhum ganho aqui, vai apenas criar outro join...
Eu também poderia criar uma segunda coluna em cada linha de dados, porque na maioria dos casos eu tenho apenas uma referência adicional (mas em teoria poderia haver mais) e salvar null se nenhuma outra referência estiver lá - o que me parece muito ruim porque pode haver tuplas com 3 ou mais referências.
Existe uma maneira eficiente e fácil de manter para salvar esses dados?
Usar uma tabela intermediária é a maneira correta de fazer isso. Com índices adequados e boa manutenção não vai prejudicar muito o desempenho.
Evite a solução de várias colunas (
refid1
,refid2
etc.) - isso está repetindo grupos e não está devidamente normalizado. Além disso, suas consultas degenerarão em um café da manhã canino de cláusulas OR e instruções CASE, o que prejudicará o desempenho.Você pode obter algum benefício ao subdigitar suas
data
linhas, então a maioria usa seu arranjo atual, mas aqueles com váriosreference
usam um diferente. Suas consultas serãoUNION ALL
os dois conjuntos para obter o total. Eu realmente duvido que a sobrecarga disso compense a junção redundante para arquivosdata_reference
.O esquema subtipado ficaria assim:
A consulta seria algo como:
Isso é bastante feio. Você teria sorte se evitasse duas varreduras de arquivos
data
. Idealmente, você desejaria índices filtrados, mas o IIRC não está disponível até o SQL Server 2008. O aplicativo teria que saber quantasreference
linhas havia pordata
, definir sinalizadores de acordo e mantê-los se o número fosse alterado. Basta usar a abordagem n:m.Uma maneira de fazer isso - tenha uma coluna varchar com uma lista delimitada de referências adicionais, se existirem (123.458.658.587 etc). Em seguida, crie uma UDF para dividir esses dados, se existirem, que você pode usar em consultas SELECT. Deve ser fácil projetar o UDF para extrair os dados. Como é raro, não deve prejudicar muito os recursos. Uma coluna varchar também deve significar requisitos mínimos de espaço extra.