AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 163919
Accepted
SQLserving
SQLserving
Asked: 2017-02-11 10:42:27 +0800 CST2017-02-11 10:42:27 +0800 CST 2017-02-11 10:42:27 +0800 CST

Duas tabelas, uma chave estrangeira e duas chaves primárias

  • 772

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?

database-design foreign-key
  • 2 2 respostas
  • 1451 Views

2 respostas

  • Voted
  1. Best Answer
    RDFozz
    2017-02-11T12:23:31+08:002017-02-11T12:23:31+08:00

    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).

    • 2
  2. paparazzo
    2017-02-14T07:44:21+08:002017-02-14T07:44:21+08:00

    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

    • Adicione TeamName ao aluno e permita null
      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

    • 1

relate perguntas

  • Os índices filtrados podem ajudar a melhorar as consultas baseadas em uma hora inserida ou isso deve ser evitado?

  • Qual é a diferença entre os tipos de dados MySQL VARCHAR e TEXT?

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve