Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come creare una chiave primaria in SQL Server (esempi T-SQL)

Questo articolo illustra come creare una chiave primaria in SQL Server durante la creazione di una tabella usando Transact-SQL.

Una chiave primaria è una o più colonne che sono state configurate come identificatore univoco per una determinata tabella. Le chiavi primarie possono essere utilizzate per rafforzare l'integrità dei dati nella tabella.

Una tabella può avere solo una chiave primaria e le chiavi primarie possono essere aggiunte solo a colonne definite come NOT NULL .

Questo articolo mostra come creare una chiave primaria in un nuovo tabella (ovvero durante la creazione della tabella). Se devi creare una chiave primaria in un esistente tabella, vedere Come aggiungere una chiave primaria a una tabella esistente in SQL Server.

Esempio 1:creare una tabella con una chiave primaria

Per prima cosa creerò un database di test:

CREATE DATABASE PK_Test;

Ora crea una nuova tabella che includa un vincolo di chiave primaria:

USE PK_Test;

CREATE TABLE Colors
(
    ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    ColorName varchar(50)
);

Questo ha creato una nuova tabella chiamata Colors che ha un vincolo di chiave primaria sul suo ColorId colonna.

Esempio 2:verifica del vincolo della chiave primaria

Possiamo eseguire il codice seguente per restituire un elenco di vincoli di chiave primaria nel database:

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Risultato:

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__Colors__8DA7674DD34F4585 | PK     | 1                 | 1                 |
+------------------------------+--------+-------------------+-------------------+

Ho ristretto le colonne per questo esempio. Il sys.key_constraints la vista di sistema restituisce più colonne di questa. Puoi sempre usare il * carattere jolly per restituire tutte le colonne, se lo desideri.

Possiamo vedere dal risultato della query che questo database ha solo una chiave primaria (quella che abbiamo appena creato).

In questo caso la chiave primaria è stata nominata automaticamente dal sistema. Hai anche la possibilità di fornire il tuo nome (ne parleremo più avanti).

Esempio 3:verifica dell'indice

Per impostazione predefinita, quando si crea la chiave primaria viene creato un indice cluster. È possibile specificare l'indice cluster in modo esplicito o lasciarlo creare automaticamente. Hai anche la possibilità di specificare un indice non cluster.

Ecco una query che restituisce l'indice che è stato creato automaticamente quando ho creato la chiave primaria sopra:

SELECT *
FROM sys.indexes
WHERE name = 'PK__Colors__8DA7674DD34F4585';

Risultato (usando l'output verticale):

object_id                  | 885578193
name                       | PK__Colors__8DA7674DD34F4585
index_id                   | 1
type                       | 1
type_desc                  | CLUSTERED
is_unique                  | 1
data_space_id              | 1
ignore_dup_key             | 0
is_primary_key             | 1
is_unique_constraint       | 0
fill_factor                | 0
is_padded                  | 0
is_disabled                | 0
is_hypothetical            | 0
is_ignored_in_optimization | 0
allow_row_locks            | 1
allow_page_locks           | 1
has_filter                 | 0
filter_definition          | NULL
compression_delay          | NULL
suppress_dup_key_messages  | 0
auto_created               | 0

In questo caso ho ristretto i risultati solo alla riga che contiene lo stesso nome della chiave primaria che ho appena creato. Puoi sempre rimuovere il WHERE clausola se hai bisogno di più risultati da restituire.

Possiamo vedere che questo indice ha un type_desc di CLUSTERED .

Esempio 4:denominazione della chiave primaria

La chiave primaria che abbiamo creato sopra è stata nominata automaticamente dal sistema. Puoi fornire il tuo nome se preferisci.

Ecco un esempio di specifica di un nome per la chiave primaria. In questo caso specifico anche un indice non cluster.

USE PK_Test;

CREATE TABLE Cats
(
    CatId int IDENTITY (1,1) NOT NULL, 
       CONSTRAINT PK_Cats_CatId PRIMARY KEY NONCLUSTERED (CatId),
    CatName varchar(50)
);

In questo caso utilizzo il CONSTRAINT opzionale parola chiave per indicare l'inizio della definizione della chiave primaria, seguita dal nome che ho scelto per la chiave primaria. Uso anche il NONCLUSTERED parola chiave per specificare un indice non cluster.

Controlla la chiave primaria:

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Risultato:

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__Colors__8DA7674DD34F4585 | PK     | 1                 | 1                 |
| PK_Cats_CatId                | PK     | 2                 | 0                 |
+------------------------------+--------+-------------------+-------------------+

Controlla l'indice:

SELECT *
FROM sys.indexes
WHERE name = 'PK_Cats_CatId';

Risultato (usando l'output verticale):

object_id                  | 917578307
name                       | PK_Cats_CatId
index_id                   | 2
type                       | 2
type_desc                  | NONCLUSTERED
is_unique                  | 1
data_space_id              | 1
ignore_dup_key             | 0
is_primary_key             | 1
is_unique_constraint       | 0
fill_factor                | 0
is_padded                  | 0
is_disabled                | 0
is_hypothetical            | 0
is_ignored_in_optimization | 0
allow_row_locks            | 1
allow_page_locks           | 1
has_filter                 | 0
filter_definition          | NULL
compression_delay          | NULL
suppress_dup_key_messages  | 0
auto_created               | 0

Quindi possiamo vedere che questa volta il type_desc è NONCLUSO .

Nota che quando crei una tabella, CLUSTERED può essere specificato per un solo vincolo. Se è specificato per un UNIQUE vincolo e una PRIMARY KEY viene inoltre specificato il vincolo, la PRIMARY KEY il valore predefinito è NONCLUSTERED .

Esempio 5:creare una chiave primaria su una colonna nullable

È possibile creare una chiave primaria solo per le colonne definite come NOT NULL . Se provi a creare una chiave primaria su una colonna impostata su NULL , riceverai un errore.

Tuttavia, se non specifichi l'annullamento dei valori, la colonna viene impostata su NOT NULL per impostazione predefinita.

Per dimostrarlo, creiamo un'altra tabella, ma questa volta la imposteremo su NULL :

USE PK_Test;

CREATE TABLE Dogs
(
    DogId int IDENTITY (1,1) NULL PRIMARY KEY,
    DogName varchar(50)
);

Risultato:

Msg 8147, Level 16, State 1, Line 3
Could not create IDENTITY attribute on nullable column 'DogId', table 'Dogs'.
Msg 8111, Level 16, State 1, Line 3
Cannot define PRIMARY KEY constraint on nullable column in table 'Dogs'.
Msg 1750, Level 16, State 0, Line 3
Could not create constraint or index. See previous errors.

Come previsto, otteniamo un errore.

Rimuoviamo NULL dalla definizione della tabella e riprovare:

USE PK_Test;

CREATE TABLE Dogs
(
    DogId int IDENTITY (1,1) PRIMARY KEY,
    DogName varchar(50)
);

Risultato:

Commands completed successfully.
Total execution time: 00:00:00.015

Questa volta la tabella è stata creata correttamente.

Diamo un'occhiata:

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'DogId';

Risultato:

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Dogs    | DogId    | 0             | 1             |
+---------+----------+---------------+---------------+

Quindi possiamo vedere che non è nullable, perché is_nullable flag è impostato su 0 .

Esempio 6 – Chiave primaria su più colonne

Puoi anche creare una chiave primaria su più colonne. Le chiavi primarie multicolonna sono anche note come chiavi primarie composite. Per creare una chiave primaria composta, separa semplicemente le colonne con una virgola durante la definizione della chiave.

In questo modo:

CONSTRAINT PK_Name PRIMARY KEY (Column1, Column2)

Ecco un esempio di una situazione in cui potrebbe essere utilizzata una chiave primaria multicolonna:

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

In questo esempio, il BandMember la tabella ha una chiave primaria multicolonna. In questo caso ogni colonna della chiave primaria è anche una chiave esterna alla chiave primaria di un'altra tabella, ma questo non è un requisito.

Vedere Come creare una chiave primaria composita in SQL Server per una spiegazione più dettagliata di questo esempio.

Vedi anche Come creare una chiave esterna composita in SQL Server per un esempio che fa un ulteriore passo avanti con una chiave esterna multicolonna che fa riferimento alla chiave primaria composita sopra.