Uma chave primária composta é uma chave primária que consiste em várias colunas. A Microsoft geralmente se refere a elas como chaves primárias de várias colunas em sua documentação.
Este artigo fornece um exemplo de criação de uma chave primária composta usando Transact-SQL no SQL Server.
Você pode criar uma chave primária composta da mesma forma que criaria uma única chave primária, exceto que, em vez de especificar apenas uma coluna, você fornece o nome de duas ou mais colunas, separadas por uma vírgula.
Assim:
CONSTRAINT PK_Name PRIMARY KEY (Coluna1, Coluna2)
Exemplo 1 – Criar uma chave primária composta
Aqui está um exemplo de um banco de dados usando uma chave primária composta.
Para os propósitos deste exemplo, criarei um banco de dados chamado PK_Test :
CRIAR BANCO DE DADOS PK_Test;
Agora que o banco de dados foi criado, vamos em frente e criar as tabelas.
USE PK_Test;CREATE TABLE Musician (MusicianId int NOT NULL,FirstName varchar(60),LastName varchar(60),CONSTRAINT PK_Musician PRIMARY KEY (MusicianID));CREATE TABLE Band (BandId int NOT NULL,BandName varchar(255) ,CONSTRAINT PK_Band PRIMARY KEY (BandId));CREATE TABLE BandMember (MusicianId int NOT NULL,BandId int NOT NULL,CONSTRAINT PK_BandMember PRIMARY KEY (MusicianID, BandId),CONSTRAINT FK_BandMember_Band FOREIGN KEY (BandId) REFERENCES Band(BandId),CONSTRAINT FK_BandForEIGN KEY (BandId) REFERENCES Band(BandId),CONSTRAINT FK_Band KEY (MusicianId) REFERÊNCIAS Musician(MusicianId));
Neste exemplo, o
BandMember
tabela tem uma chave primária de várias colunas. Nesse caso, cada coluna na chave primária também é uma chave estrangeira para a chave primária de outra tabela, mas isso não é um requisito. O raciocínio por trás do design do banco de dados acima é que um músico poderia ser membro de muitas bandas. Além disso, cada banda pode ter muitos músicos. Portanto, temos uma relação de muitos para muitos. É por isso que o
BandMember
a tabela é criada – ela é usada como uma tabela de referência cruzada entre o Musician
tabela e a Band
tabela. Este caso em particular suporta uma chave primária composta, porque um músico ser membro de uma banda deve ser uma ocorrência única. Em outras palavras, não queremos várias filas com um músico sendo membro da mesma banda. Isso violaria a integridade dos dados. Também pode causar estragos ao tentar manter a integridade referencial mesmo que criemos um relacionamento entre esta tabela e outra (o que fazemos aqui).
Exemplo 2 – Inserir dados
Tendo acabado de executar o código acima, agora posso carregar o banco de dados com dados:
INSERT INTO MusicianVALUES ( 1, 'Ian', 'Paice' ),( 2, 'Roger', 'Glover' ),( 3, 'Richie', 'Blackmore' ),( 4, 'Rod', ' Evans' ),( 5, 'Ozzy', 'Osbourne' );INSERT INTO BandVALUES ( 1, 'Deep Purple' ),( 2, 'Rainbow' ),( 3, 'Whitesnake' ),( 4, 'Iron Maiden' ' );INSERT INTO BandMemberVALUES ( 1, 1 ),( 1, 3 ),( 2, 1 ),( 2, 2 ),( 3, 1 ),( 3, 2 ),( 4, 1 );Exemplo 3 – Consulta básica
Agora que os dados estão em nosso banco de dados, vamos executar uma consulta para retornar alguns desses dados.
Aqui está uma consulta básica:
SELECT CONCAT(m.FirstName, ' ', m.LastName) AS 'Músico', b.BandName AS 'Band'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Banda b ON b.BandId =bm .BandId AND m.MusicianId =bm.MusicianId;
Resultado:
+------------------+-------------+| Músico | Banda ||------------------+-------------|| Ian Paice | Roxo Profundo || Ian Paice | Cobra-branca || Roger Glover | Roxo Profundo || Roger Glover | Arco-íris || Richie Blackmore | Roxo Profundo || Richie Blackmore | Arco-íris || Rod Evans | Deep Purple |+------------------+-------------+
Então, como esperado, isso retorna apenas os músicos e bandas que possuem uma entrada noBandMember
tabela de referência.
Exemplo 4 – Consulta ligeiramente modificada
Aqui está uma versão modificada da consulta acima que apresenta os resultados de uma maneira diferente:
SELECT b.BandName AS 'Band', STRING_AGG(CONCAT(m.FirstName, ' ', m.LastName), ', ') AS 'Musicians'FROM Musician mJOIN BandMember bm ON m.MusicianId =bm.MusicianIdJOIN Band b ON b.BandId =bm.BandId AND m.MusicianId =bm.MusicianIdGROUP BY b.BandName;
Resultado:
+-------------+-------------------------------- ------------+| Banda | Músicos ||-------------+--------------------------------- ----------|| Roxo Profundo | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans || Arco-íris | Roger Glover, Richie Blackmore || Cobra-branca | Ian Paice |+-------------+-------------------------------- -----------+
Aqui os resultados são agrupados por banda e todos os músicos de cada banda são exibidos como uma lista separada por vírgulas em um único campo.
Para fazer isso eu uso oSTRING_AGG()
função de concatenar os músicos.
Chave estrangeira composta
O problema com o exemplo acima é que a maioria dos dados está desatualizada. Alguns desses músicos realmente deixaram essas bandas. E alguns foram embora e voltaram mais tarde.
Como podemos lidar com isso?
Poderíamos criar outra tabela de referência para registrar o período de tempo em que cada músico é membro de cada banda. Tal tabela precisaria referenciar oBandMember
tabela por meio de uma chave estrangeira. E como essa tabela tem uma chave primária composta, precisaríamos usar uma chave estrangeira composta na nova tabela que a referencia.
Consulte Como criar uma chave estrangeira composta no SQL Server para obter um exemplo. Esse artigo usa o mesmo exemplo acima, exceto com uma tabela extra com uma chave estrangeira composta que faz referência à chave primária composta acima.