sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo crear una clave principal compuesta en SQL Server (ejemplo de T-SQL)

Una clave principal compuesta es una clave principal que consta de varias columnas. Microsoft suele referirse a ellas como claves primarias de varias columnas en su documentación.

Este artículo proporciona un ejemplo de cómo crear una clave principal compuesta mediante Transact-SQL en SQL Server.

Puede crear una clave principal compuesta de la misma manera que crearía una clave principal única, excepto que en lugar de especificar solo una columna, proporcione el nombre de dos o más columnas, separadas por una coma.

Así:

CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)

Ejemplo 1:crear una clave principal compuesta

Este es un ejemplo de una base de datos que utiliza una clave principal compuesta.

A los efectos de este ejemplo, crearé una base de datos llamada PK_Test :

CREATE DATABASE PK_Test;

Ahora que se creó la base de datos, sigamos adelante y creemos las tablas.

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_BandMember_Musician FOREIGN KEY (MusicianId) REFERENCES Musician(MusicianId)
);

En este ejemplo, el BandMember la tabla tiene una clave principal de varias columnas. En este caso, cada columna de la clave principal también es una clave externa a la clave principal de otra tabla, pero esto no es un requisito.

El razonamiento detrás del diseño de la base de datos anterior es que un músico podría ser miembro de muchas bandas. Además, cada banda puede tener muchos músicos. Así que tenemos una relación de muchos a muchos. Esta es la razón por la que BandMember se crea la tabla:se utiliza como tabla de referencias cruzadas entre el Musician tabla y la Band mesa.

Este caso particular admite una clave primaria compuesta, porque el hecho de que un músico sea miembro de una banda debería ser una ocurrencia única. En otras palabras, no querríamos múltiples filas con un músico siendo miembro de la misma banda. Eso violaría la integridad de los datos. También podría causar estragos al tratar de mantener la integridad referencial en el caso de que alguna vez creemos una relación entre esta tabla y otra (lo que hacemos aquí).

Ejemplo 2:Insertar datos

Después de ejecutar el código anterior, ahora puedo cargar la base de datos con datos:

INSERT INTO Musician
VALUES 
( 1, 'Ian', 'Paice' ),
( 2, 'Roger', 'Glover' ),
( 3, 'Richie', 'Blackmore' ),
( 4, 'Rod', 'Evans' ),
( 5, 'Ozzy', 'Osbourne' );

INSERT INTO Band
VALUES 
( 1, 'Deep Purple' ),
( 2, 'Rainbow' ),
( 3, 'Whitesnake' ),
( 4, 'Iron Maiden' );

INSERT INTO BandMember
VALUES 
( 1, 1 ),
( 1, 3 ),
( 2, 1 ),
( 2, 2 ),
( 3, 1 ),
( 3, 2 ),
( 4, 1 );

Ejemplo 3:consulta básica

Ahora que los datos están en nuestra base de datos, ejecutemos una consulta para devolver algunos de esos datos.

Aquí hay una consulta básica:

SELECT 
  CONCAT(m.FirstName, ' ', m.LastName) AS 'Musician',
  b.BandName AS 'Band'
FROM Musician m
JOIN BandMember bm
  ON m.MusicianId = bm.MusicianId
JOIN Band b 
  ON b.BandId = bm.BandId AND m.MusicianId = bm.MusicianId;

Resultado:

+------------------+-------------+
| Musician         | Band        |
|------------------+-------------|
| Ian Paice        | Deep Purple |
| Ian Paice        | Whitesnake  |
| Roger Glover     | Deep Purple |
| Roger Glover     | Rainbow     |
| Richie Blackmore | Deep Purple |
| Richie Blackmore | Rainbow     |
| Rod Evans        | Deep Purple |
+------------------+-------------+

Entonces, como era de esperar, esto solo devuelve aquellos músicos y bandas que tienen una entrada en BandMember tabla de referencia.

Ejemplo 4:consulta ligeramente modificada

Aquí hay una versión modificada de la consulta anterior que presenta los resultados de una manera diferente:

SELECT 
  b.BandName AS 'Band',
  STRING_AGG(CONCAT(m.FirstName, ' ', m.LastName), ', ') AS 'Musicians'
FROM Musician m
JOIN BandMember bm
  ON m.MusicianId = bm.MusicianId
JOIN Band b 
  ON b.BandId = bm.BandId AND m.MusicianId = bm.MusicianId
GROUP BY b.BandName;

Resultado:

+-------------+------------------------------------------------------+
| Band        | Musicians                                            |
|-------------+------------------------------------------------------|
| Deep Purple | Ian Paice, Roger Glover, Richie Blackmore, Rod Evans |
| Rainbow     | Roger Glover, Richie Blackmore                       |
| Whitesnake  | Ian Paice                                            |
+-------------+------------------------------------------------------+

Aquí los resultados se agrupan por banda y todos los músicos de cada banda se muestran como una lista separada por comas en un solo campo.

Para hacer esto, uso el STRING_AGG() Función para concatenar los músicos.

Clave foránea compuesta

El problema con el ejemplo anterior es que la mayoría de los datos están desactualizados. Algunos de estos músicos han dejado esas bandas. Y algunos se fueron y luego regresaron en una fecha posterior.

¿Cómo podemos lidiar con esto?

Podríamos crear otra tabla de referencia para registrar el período de tiempo que cada músico es miembro de cada banda. Dicha tabla necesitaría hacer referencia al BandMember tabla a través de una clave foránea. Y dado que esta tabla tiene una clave principal compuesta, necesitaríamos usar una clave externa compuesta en la nueva tabla que hace referencia a ella.

Consulte Cómo crear una clave externa compuesta en SQL Server para ver un ejemplo. Ese artículo utiliza el mismo ejemplo que el anterior, excepto con una tabla adicional con una clave externa compuesta que hace referencia a la clave primaria compuesta anterior.