Normalizar suas tabelas operacionais, conforme sugerido pelo Transact Charlie, é uma boa idéia e economizará muitas dores de cabeça e problemas ao longo do tempo - mas existem coisas como tabelas de interface , que suportam integração com sistemas externos, e tabelas de relatório , que suportam coisas como analíticas em processamento; e esses tipos de tabelas não devem necessariamente ser normalizados - na verdade, muitas vezes é muito, muito mais conveniente e com desempenho para eles não serem .
Nesse caso, acho que a proposta do Transact Charlie para suas tabelas operacionais é boa.
Mas eu adicionaria um índice (não necessariamente exclusivo) ao CompetitorName na tabela Competitors para oferecer suporte a junções eficientes no CompetitorName para fins de integração (carregamento de dados de fontes externas) e colocaria uma tabela de interface na combinação: CompetitionResults.
Os resultados da competição devem conter quaisquer dados que os resultados da competição contenham. O objetivo de uma tabela de interface como esta é tornar o mais rápido e fácil possível truncá-lo e recarregá-lo de uma planilha do Excel ou de um arquivo CSV, ou de qualquer forma em que você tenha esses dados.
Essa tabela de interface não deve ser considerada parte do conjunto normalizado de tabelas operacionais. Em seguida, você pode ingressar no CompetitionResults, conforme sugerido por Richard, para inserir registros nos concorrentes que ainda não existem e atualizar os que existem (por exemplo, se você realmente tiver mais informações sobre os concorrentes, como o número de telefone ou endereço de email).
Uma coisa que eu observaria - na realidade, o nome do concorrente, parece-me, é muito improvável que seja único em seus dados . Em 200.000 concorrentes, você pode muito bem ter 2 ou mais David Smiths, por exemplo. Por isso, recomendo que você colete mais informações dos concorrentes, como número de telefone ou endereço de e-mail ou algo com maior probabilidade de ser único.
Sua tabela operacional, Concorrentes, deve ter apenas uma coluna para cada item de dados que contribui para uma chave natural composta; por exemplo, ele deve ter uma coluna para um endereço de email principal. Mas a tabela de interface deve ter um slot para antigos e novos valores para um endereço de email principal, para que o valor antigo possa ser usado para procurar o registro nos Concorrentes e atualizar essa parte para o novo valor.
Portanto, CompetitionResults deve ter alguns campos "antigos" e "novos" - oldEmail, newEmail, oldPhone, newPhone, etc. Dessa forma, você pode formar uma chave composta, em Concorrentes, em Nome do concorrente, E-mail e Telefone.
Então, quando você tiver alguns resultados de competição, poderá truncar e recarregar sua tabela CompetitionResults da planilha do Excel ou o que tiver, e executar uma inserção única e eficiente para inserir todos os novos concorrentes na tabela Competidores e atualizar uma atualização eficiente para atualizar todas as informações sobre os concorrentes existentes nos resultados da competição. E você pode fazer uma única inserção para inserir novas linhas na tabela CompetitionCompetitors. Essas coisas podem ser feitas em um procedimento armazenado ProcessCompetitionResults, que pode ser executado após o carregamento da tabela CompetitionResults.
Essa é uma espécie de descrição rudimentar do que eu vi repetidamente no mundo real com Oracle Applications, SAP, PeopleSoft e uma lista completa de outros pacotes de software corporativo.
Um último comentário que eu faria é o que fiz antes no SO: Se você criar uma chave estrangeira que garanta a existência de um Concorrente na tabela Concorrentes antes de poder adicionar uma linha com esse Concorrente a CompetitionCompetitors, verifique se chave estrangeira está definida para cascata atualizações e exclusões . Dessa forma, se você precisar excluir um concorrente, poderá fazê-lo e todas as linhas associadas a esse concorrente serão excluídas automaticamente. Caso contrário, por padrão, a chave estrangeira exigirá que você exclua todas as linhas relacionadas dos CompetitionCompetitors antes de permitir que você exclua um Concorrente.
(Algumas pessoas pensam que chaves estrangeiras não em cascata são uma boa precaução de segurança, mas minha experiência é que elas são apenas uma dor no traseiro que, na maioria das vezes, são simplesmente resultado de uma supervisão e criam um monte de trabalho Para lidar com pessoas que excluem acidentalmente coisas, é por isso que você tem coisas como "tem certeza" e vários tipos de backups regulares e fontes de dados redundantes.É muito, muito mais comum querer excluir um concorrente, cujos dados são todos errei por exemplo, do que excluir acidentalmente um e depois dizer "Ah, não! Eu não pretendia fazer isso! E agora não tenho os resultados de suas competições! Aaaahh!" Este último certamente é bastante comum, então , você precisa estar preparado para isso, mas o primeiro é muito mais comum,portanto, a melhor e mais fácil maneira de se preparar para a primeira, imo, é apenas fazer com que as chaves estrangeiras façam atualizações e exclusões em cascata.)
NVARCHAR(64)
coluna sua chave primária (e, portanto: cluster) !! Primeiro de tudo - é uma chave muito ampla - até 128 bytes; e segundo: o tamanho variável - novamente: não é o ideal ... Essa é a pior escolha que você pode ter - seu desempenho será um inferno, e a fragmentação de tabela e índice estará em 99,9% o tempo todo .....