Digamos que existam duas tabelas:
Aluno:
AlunoID(Chave Primária)
Nome
StudentTeams:
StudentID (Chave Primária, Chave Estrangeira)
TeamName
StudentID na tabela StudentTeams faz referência à chave primária da tabela Student. Quais seriam os prós e contras de tal estrutura em termos de integridade relacional?
Apenas para esclarecer: Cada aluno pode ter 0 ou 1 valor TeamName associado, com esta configuração.
Ter StudentTeams sem StudentID como chave estrangeira permitiria registros com IDs de aluno inválidos, então isso é presumivelmente um profissional. Da mesma forma, se StudentID não fosse a chave primária de StudentTeams, um aluno poderia ser anexado a vários nomes de equipe, também presumivelmente um profissional (supondo-se que essas sejam suas regras de negócios).
No entanto, se essa for literalmente a estrutura da tabela, seria melhor que TeamName fosse um campo na tabela Student, com valores NULL permitidos. Cada aluno pode ter 0 ou 1 valores TeamName e nenhum relacionamento (ou tabela) separado é necessário. Então, isso é um contra.
Na minha experiência, só vi algumas situações em que fazia sentido ter TableA com uma chave primária de A_ID e, em seguida, ter TableB que usa A_ID como chave primária e estrangeira:
Desempenho : Se a Tabela A for usada em muitos lugares, por muitas partes da aplicação, e os dados na Tabela B forem usados apenas em uma parte isolada da aplicação (um conjunto de comandos que apenas 2% da base de usuários tem acesso, ou que são usados apenas no final do ano) e cada linha na Tabela B for grande (por exemplo, se Student.Name tiver, em média, 40 caracteres e StudentTeams.TeamName tiver, em média, 4.000 caracteres), as consultas que don't need TeamName pode ter um desempenho muito mais rápido se não estiver na tabela Student.
Tabela paralela : Se a estrutura da TabelaA não estiver sob seu controle, então você não pode adicionar TeamName a ela, mantendo a TabelaB como uma "tabela paralela" (meu próprio termo; uma tabela separada que só terá uma linha se houver uma linha correspondente na TabelaA ) pode ser a única maneira de fazer as coisas. Certa vez, configurei várias dessas tabelas, quando precisei criar um aplicativo que usasse dados do aplicativo de um fornecedor de terceiros, mas onde nosso aplicativo precisava fornecer dados adicionais que não existiam no aplicativo do fornecedor. A chave estrangeira é necessária, pois pode manter suas informações devidamente vinculadas aos dados do fornecedor (atualizações e exclusões em cascata), sem modificar o aplicativo do fornecedor.
Separação lógica: Se os dados na Tabela A e na Tabela B estiverem relacionados, mas estiverem nitidamente divididos em propósito, pode fazer sentido armazená-los em tabelas separadas. Assim como no exemplo anterior, tornar a chave primária da TabelaA a chave primária e a chave estrangeira na TabelaB garante que você só terá uma entrada da TabelaB se a entrada da TabelaA existir, e você terá que eliminar a linha da TabelaB para excluir a linha da TabelaA. Trabalhei com um sistema com uma tabela Task (com uma lista de trabalho a ser feito) e uma tabela TaskHistory separada (com informações sobre as condições em que a tarefa foi realizada, consumíveis usados pela tarefa etc.). Isso pode simplificar as regras de negócios; um campo pode ser NOT NULL em TaskHistory, mesmo que não possa ser preenchido até que a tarefa seja concluída; se o campo estivesse na tabela de tarefas, uma regra de negócios especial teria que existir, garantindo que determinados campos não sejam NULL quando a tarefa atingiu o status concluído. Observe que isso geralmente será uma mistura de lógica e desempenho: havia várias consultas no aplicativo que só precisavam atingir a tabela Task.
Requisitos Relacionais Adicionais : Conforme observado por ypercubeᵀᴹ nos comentários, pode-se usar isso para permitir que uma terceira tabela use o StudentID da tabela StudentTeams como uma chave estrangeira, garantindo que a terceira tabela seja vinculada apenas aos alunos que estavam em uma equipe. Pessoalmente, não tenho certeza se implementaria uma estrutura dessa maneira. Isso pode causar confusão quanto ao significado de StudentID; ele sempre vincularia de volta a um registro Student, mas nem sempre vincularia a um registro StudentTeam (embora, reconhecidamente, no contexto desta terceira tabela, ele sempre vincularia a um Student e a um StudentTeam). Eu estaria inclinado a criar um valor StudentTeamID em StudentTeams e vinculá-lo, pois seu significado seria imediatamente claro (apenas vincularia alunos em uma equipe).
StudentTeams é um nome ruim como no plural.
Com esse design, um aluno pode estar em 0 ou 1 equipe.
Se vários alunos estiverem na mesma equipe (TeamName) repete. Dois alunos podem estar na mesma equipe, mas alguém pode inserir TeamName incorretamente para que você não saiba.
eu também faria
Ele fará exatamente o que você tem agora - 0 ou 1 TeamName
Tabela de equipe e uma tabela de junção
Equipe: Nome do
ID (PK)
StudentTeam:
SudentID (PK, FK para Student.ID)
TeamID (FK para Team.ID)
Se você deseja permitir que um aluno esteja em mais de 1 equipe, basta adicionar TeamID ao PK.
Ou você pode pular StudentTeam e colocar TeamID na tabela de alunos. Pelo menos você só insere TeamName uma vez.
Aluno:
ID (PK)
Nome
TeamID (FK para Team.ID) permitir nulo