Por que usar várias colunas como chaves primárias (chave primária composta)

109

Este exemplo foi retirado de w3schools .

CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)

Meu entendimento é que ambas as colunas juntas ( P_Ide LastName) representam uma chave primária para a tabela Persons. Isso está correto?

  • Por que alguém iria querer usar várias colunas como chaves primárias em vez de uma única coluna?
  • Quantas colunas podem ser usadas juntas como uma chave primária em uma determinada tabela?
rockbala
fonte
... agora também há uma resposta para a 2ª pergunta
Wolf
1
@Martijn Peters. Por que a resposta foi excluída?
PerformanceDBA

Respostas:

119

Seu entendimento está correto.

Você faria isso em muitos casos. Um exemplo é em um relacionamento como OrderHeadere OrderDetail. O PK em OrderHeaderpode ser OrderNumber. O PK in OrderDetailpode ser OrderNumberAND LineNumber. Se fosse qualquer um dos dois, não seria único, mas a combinação dos dois é garantidamente única.

A alternativa é usar uma chave primária gerada (não inteligente), por exemplo neste caso OrderDetailId. Mas nem sempre você veria o relacionamento com tanta facilidade. Algumas pessoas preferem uma maneira; alguns preferem o outro caminho.

MJB
fonte
2
Isso é útil se eu estiver usando branch_id e usando replicação entre dois bancos de dados, resolverá duplicatas de ids? !!
Mhmd
11
Observe que em muitos casos de uso de uma chave primária gerada, você frequentemente ainda deseja uma chave exclusiva nos valores compostos.
Bacon Bits de
Elabore em "Algumas pessoas preferem uma maneira; outras preferem a outra".
Nome de usuário
1
Fundamentos elaborados? Não tem certeza do que dizer. Conheci pessoas que preferem ter vários campos concatenados como uma chave porque é mais fácil intuitivamente entender o que eles estão vendo. Conheci outros que preferem apenas atribuir uma chave exclusiva para cada linha porque é mais fácil e rápido de digitar. É isso que você está perguntando?
MJB
Essa mensagem era para @Username. Eu esqueci de direcionar.
MJB
26

Outro exemplo de chaves primárias compostas é o uso de tabelas de associação. Suponha que você tenha uma mesa de pessoa que contém um conjunto de pessoas e uma mesa de grupo que contém um conjunto de grupos. Agora você deseja criar um relacionamento de muitos para muitos na pessoa e no grupo. Isso significa que cada pessoa pode pertencer a vários grupos. Aqui está como seria a estrutura da tabela usando uma chave primária composta.

Create Table Person(
PersonID int Not Null,
FirstName varchar(50),
LastName varchar(50),
Constraint PK_Person PRIMARY KEY (PersonID))

Create Table Group (
GroupId int Not Null,
GroupName varchar(50),
Constraint PK_Group PRIMARY KEY (GroupId))

Create Table GroupMember (
GroupId int Not Null,
PersonId int Not Null,
CONSTRAINT FK_GroupMember_Group FOREIGN KEY (GroupId) References Group(GroupId),
CONSTRAINT FK_GroupMember_Person FOREIGN KEY (PersonId) References Person(PersonId),
CONSTRAINT PK_GroupMember PRIMARY KEY (GroupId, PersonID))
John Hartsock
fonte
ótima explicação: acho que a necessidade de atributos para relações m-para-n (em uma fasion normalizada) é a chave.
Wolf
talvez adicionar um pouco de explicação sobre o benefício seria ainda melhor
Martian2049
10

O exemplo W3Schools não diz quando você deve usar chaves primárias compostas, e apenas fornece sintaxe de exemplo usando a mesma tabela de exemplo para outras chaves.

A escolha do exemplo talvez o esteja enganando ao combinar uma chave sem sentido (P_Id) e uma chave natural (Sobrenome). Esta estranha escolha de chave primária diz que as linhas a seguir são válidas de acordo com o esquema e são necessárias para identificar um aluno de maneira única. Intuitivamente, isso não faz sentido.

1234     Jobs
1234     Gates

Leitura adicional: O grande debate da chave primária ou apenas Google meaningless primary keysou até mesmo examinar esta questão do SO

FWIW - Meus 2 centavos são evitar chaves primárias com várias colunas e usar um único campo de id gerado (chave substituta) como a chave primária e adicionar restrições adicionais (exclusivas) quando necessário.

Robert Paulson
fonte
1
1) o link "grande debate da chave primária" é particularmente estúpido, a informação é egoísta e falsa. 2) O índice nas colunas que tornam a linha única não pode ser evitado. Um ID "substituto" com um índice é sempre uma coluna adicional e um índice adicional. Bastante bobo porque é redundante. E mais lento.
PerformanceDBA em
2
O "grande debate da chave primária" não é estúpido. É um problema muito válido para desenvolvedores que não são desenvolvedores sql ou DBA's sql e não passam todo o tempo em sql. Mesmo em sql puro, prefiro ter uma chave gerada automaticamente sem sentido como a chave primária ao ingressar, do que ter que me lembrar de passar n bits de dados para ser a chave natural. Você é bem-vindo ao seu ponto de vista, mas gostaríamos de não ser tão desdenhosos.
Robert Paulson de
4

Use uma chave composta (uma chave com mais de um atributo) sempre que quiser garantir a exclusividade de uma combinação de vários atributos. Uma única chave de atributo não teria o mesmo resultado.

nvogel
fonte
1
Quanto a garantir uma chave única, você pode contar com a combinação de dois atributos para formar uma chave que logicamente não pode ser duplicada. Pessoa e data de graduação de um conjunto de dados maior seriam um exemplo.
João Marcos
3

Sim, ambos formam a chave primária. Especialmente em tabelas onde você não tem uma chave substituta , pode ser necessário especificar vários atributos como o identificador único para cada registro (mau exemplo: uma tabela com nome e sobrenome pode exigir que a combinação deles seja único).

ig0774
fonte
3

Várias colunas em uma chave, em geral, terão um desempenho pior do que uma chave substituta. Prefiro ter uma chave substituta e um índice exclusivo em uma chave com várias colunas. Dessa forma, você pode ter um melhor desempenho e a exclusividade necessária é mantida. E ainda melhor, quando um dos valores dessa chave muda, você não precisa atualizar um milhão de entradas filho em 215 tabelas filho.

HLGEM
fonte
1
1) Desempenho. Não em uma plataforma SQL (talvez em "sql" se freeware). 2) A preferência é irrelevante. O que as tabelas exigem, para integridade, é relevante. 3) Um ID "substituto" com um índice é sempre uma coluna adicional e um índice adicional . Isso seria mais lento, em qualquer plataforma. Com relação ao desempenho, você se contradiz. 4) Se você não sabe como atualizar os míticos "milhões de entradas filho em 215 tabelas filho" adequadamente , faça uma pergunta.
PerformanceDBA
2
Não concordo com a afirmação 'Várias colunas em uma chave, em geral, têm um desempenho pior do que uma chave substituta'. Freqüentemente, uma consulta extra é necessária para obter a chave substituta de um relacionamento quando você a considera. Nesse ponto, é uma viagem completa extra de desempenho mais lento.
ttugates
3

Sua segunda pergunta

Quantas colunas podem ser usadas juntas como uma chave primária em uma determinada tabela?

é específico da implementação: é definido no DBMS real que está sendo usado. [1], [2], [3] Você deve inspecionar as especificações técnicas do sistema de banco de dados usado. Alguns são muito detalhados, outros não. Pesquisar na web sobre essas limitações pode ser difícil porque a terminologia varia. O termo chave primária composta deve ser obrigatório;)

Se você não conseguir encontrar informações explícitas, tente criar um banco de dados de teste para garantir que você pode esperar um tratamento estável (e específico) das violações de limite (que são esperadas). Tome cuidado para obter as informações corretas sobre isso: às vezes, os limites são acumulados e você verá resultados diferentes com layouts de banco de dados diferentes.


Lobo
fonte
2

Usar uma chave primária em várias tabelas é útil quando você está usando uma tabela intermediária em um banco de dados relacional.

Usarei um banco de dados que criei uma vez como exemplo e, especificamente, três tabelas dentro dessa tabela. Eu criei um banco de dados para um webcomic há alguns anos. Uma mesa era chamada de "quadrinhos" - uma lista de todos os quadrinhos, seus títulos, nome do arquivo de imagem etc. A chave primária era "comicnum".

A segunda tabela era "personagens" - seus nomes e uma breve descrição. A chave primária estava em "charname".

Já que cada quadrinho - com algumas exceções - tinha vários personagens e cada personagem aparecia em vários quadrinhos, era impraticável colocar uma coluna em "personagens" ou "quadrinhos" para refletir isso. Em vez disso, criei uma terceira tabela chamada "comicchars", uma lista de quais personagens apareciam em quais gibis. Como essa tabela basicamente unia as duas tabelas, ela precisava de apenas duas colunas: charname e comicnum, e a chave primária estava em ambas.

Sr. Homem Inicial
fonte
1

Criamos chaves primárias compostas para garantir os valores da coluna de exclusividade que compõem um único registro. É uma restrição que ajuda a evitar a inserção de dados que não devem ser duplicados.

ou seja: se todos os IDs de estudante e números de certidão de nascimento forem atribuídos exclusivamente a uma única pessoa. Então, seria uma boa ideia fazer com que a chave primária de uma pessoa fosse uma composição de carteira de estudante e número de certidão de nascimento, pois isso evitaria que você inserisse acidentalmente duas pessoas com carteira de estudante diferente e a mesma certidão de nascimento.

kiwicomb123
fonte