none
Chave primária única x Chave primária composta RRS feed

  • Pergunta

  • Uma situação, duas formas.
    Uma: Chave primaria única.

    Outra: Chave primária dupla.

    A situação é a seguinte: Tenho o seguinte relacionamento: TASK.PROJECT_ID <-> PROJECT.ID

    Cada TASK está em um único PROJECT, cada PROJECT pode ter inúmeras TASK's.

    Por uma questão organizacional, acredito que seria melhor, ter como chave primária em TASK, tanto o TASK.ID como o TASK.PROJECT_ID.

    Mas já escutei por diversas vezes que isso é totalmente anti-performático.

    E aí, será que alguém tem bons argumentos para ficar de um lado ou outro?

    Grato,
    quinta-feira, 12 de abril de 2012 17:41

Respostas

  • Boa Tarde,

    Essa é uma dúvida tão interessante quando discutir chaves naturais vs chaves artificiais. Modelagem de dados é um assunto polêmico onde muitas vezes não se tem apenas uma única resposta certa e muitas vezes, o que é certo em um caso pode ser inadequado em outro e essa discussão se encaixa muito nisso.

    Pelas regras de normalização (a segunda forma normal especificamente), devemos eliminar dependências parciais da chave. Ela deve ser mínima em si só. Isso significa que se ID_Task é suficiente para tornar a linha única, não faz sentido colocar outras colunas, pois, isso introduziria as dependências parciais. É exatamente nessa linha que acredito que o Fabrizzio esteja defendendo o seu ponto de vista.

    De fato, se for apenas colocar uma ou duas colunas na chave, não fará nenhum sentido colocar mais colunas na chave. Colocar colunas desnecessárias na chave incorre em um índice mais largo, maior e mais sujeito à fragmentações e se ela não tem utilidade, não faz sentido gastar recursos à troco de nada.

    Entretanto, colocar as duas colunas como chave teria muito utilidade se houver alguma tabela filha que se relacione com tarefa. Digamos por exemplo que um projeto tenha várias tarefas e que uma tarefa possa ser executada por várias pessoas e que você queira saber o nome das pessoas que estão executando as tarefas de um determinado projeto. Se a chave for simples, você terá que fazer um JOIN com umas quatro tabelas (Projeto, Tarefas, Tarefas_Pessoas e Pessoas). Se a chave for composta (Projeto e Tarefa), você terá que fazer um JOIN com três tabelas (Projeto, Tarefa_Pessoas e Pessoas). Isso significa que o desempenho das consultas pode ser mais interessante (ainda que incorra em algum outro tipo de penalidade).

    Para tornar a discussão mais interessante, eu sugiro o link do artigo abaixo:

    Modelagem de Dados: Chaves Simples e Chaves Compostas
    http://www.plugmasters.com.br/sys/materias/349/1/Modelagem-de-Dados%3A-Chaves-Simples-e-Chaves-Compostas

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    • Sugerido como Resposta Gustavo Maia Aguiar quinta-feira, 12 de abril de 2012 19:14
    • Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    • Não Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    • Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    quinta-feira, 12 de abril de 2012 19:14

Todas as Respostas

  • Rafael,

    Na verdade, não vejo misterios em sua modelagem, e ela, de forma simplificada claro, ficaria assim:

    CREATE TABLE PROJETO

    (Id_Projeto INT IDENTITY(1,1) PRIMARY KEY)

    CREATE TABLE TASKS

    (Id_Task INT IDENTITY(1,1) PRIMARY KEY,

    Id_Projeto INT REFERENCES Projeto(Id_Projeto))

    Sem misterio algum, estamos falando de uma modelagem 1-N comum....


    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com

    quinta-feira, 12 de abril de 2012 18:14
    Moderador
  • A dúvida é: Vou perder muita performance caso deixe as duas chaves como primária?
    quinta-feira, 12 de abril de 2012 18:20
  • Rafael,

    O unico motivo que vejo para voce deixar os 2 ID como chave primaria é criando uma tabela MTM intermediaria, aonde voce teria atividades pre definidas e projetos, aonde um projeto tem N atividades, assim como uma atividade pode estar em N projetos, não só na modelagem atual colocar os 2 IDs como primario, mas isso não tem logica e não fara sentido nenhum! principalmente devido ao fato do Id_Task ser um identity, nunca haveria possibilidade de uma inserção duplicada acontecer.


    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com

    quinta-feira, 12 de abril de 2012 18:24
    Moderador
  • Boa Tarde,

    Essa é uma dúvida tão interessante quando discutir chaves naturais vs chaves artificiais. Modelagem de dados é um assunto polêmico onde muitas vezes não se tem apenas uma única resposta certa e muitas vezes, o que é certo em um caso pode ser inadequado em outro e essa discussão se encaixa muito nisso.

    Pelas regras de normalização (a segunda forma normal especificamente), devemos eliminar dependências parciais da chave. Ela deve ser mínima em si só. Isso significa que se ID_Task é suficiente para tornar a linha única, não faz sentido colocar outras colunas, pois, isso introduziria as dependências parciais. É exatamente nessa linha que acredito que o Fabrizzio esteja defendendo o seu ponto de vista.

    De fato, se for apenas colocar uma ou duas colunas na chave, não fará nenhum sentido colocar mais colunas na chave. Colocar colunas desnecessárias na chave incorre em um índice mais largo, maior e mais sujeito à fragmentações e se ela não tem utilidade, não faz sentido gastar recursos à troco de nada.

    Entretanto, colocar as duas colunas como chave teria muito utilidade se houver alguma tabela filha que se relacione com tarefa. Digamos por exemplo que um projeto tenha várias tarefas e que uma tarefa possa ser executada por várias pessoas e que você queira saber o nome das pessoas que estão executando as tarefas de um determinado projeto. Se a chave for simples, você terá que fazer um JOIN com umas quatro tabelas (Projeto, Tarefas, Tarefas_Pessoas e Pessoas). Se a chave for composta (Projeto e Tarefa), você terá que fazer um JOIN com três tabelas (Projeto, Tarefa_Pessoas e Pessoas). Isso significa que o desempenho das consultas pode ser mais interessante (ainda que incorra em algum outro tipo de penalidade).

    Para tornar a discussão mais interessante, eu sugiro o link do artigo abaixo:

    Modelagem de Dados: Chaves Simples e Chaves Compostas
    http://www.plugmasters.com.br/sys/materias/349/1/Modelagem-de-Dados%3A-Chaves-Simples-e-Chaves-Compostas

    [ ]s,

    Gustavo Maia Aguiar
    Blog: http://gustavomaiaaguiar.wordpress.com
    Vídeos:http://www.youtube.com/user/gmasql


    Classifique as respostas. O seu feedback é imprescindível

    • Sugerido como Resposta Gustavo Maia Aguiar quinta-feira, 12 de abril de 2012 19:14
    • Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    • Não Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    • Marcado como Resposta Rafael Schadeck quinta-feira, 12 de abril de 2012 19:48
    quinta-feira, 12 de abril de 2012 19:14