Usare IDENTITY per creare chiavi surrogate nel pool SQL dedicato
In questo articolo sono disponibili raccomandazioni ed esempi per l'uso della IDENTITY
proprietà per creare chiavi surrogate nelle tabelle nel pool SQL dedicato.
Che cos'è una chiave surrogata?
Una chiave surrogata in una tabella è una colonna con un identificatore univoco per ogni riga. La chiave non viene generata dai dati della tabella. I progettisti di modelli di dati preferiscono creare chiavi surrogate nelle tabelle durante la progettazione dei modelli per i data warehouse. È possibile usare la IDENTITY
proprietà per raggiungere questo obiettivo in modo semplice ed efficace senza influire sulle prestazioni del carico.
Nota
In Azure Synapse Analytics:
- Il valore IDENTITY aumenta autonomamente in ogni distribuzione e non si sovrappone ai valori IDENTITY di altre distribuzioni. Il valore IDENTITY in Synapse non è garantito che sia univoco se l'utente inserisce in modo esplicito un valore duplicato con
SET IDENTITY_INSERT ON
o invia nuovamente IDENTITY. Per i dettagli, vedere CREATE TABLE (Transact-SQL) IDENTITY (proprietà). - UPDATE nella colonna di distribuzione non garantisce che il valore IDENTITY sia univoco. Usare DBCC CHECKIDENT (Transact-SQL) dopo UPDATE sulla colonna di distribuzione per verificare l'univocità.
Creare una tabella con una colonna IDENTITY
La IDENTITY
proprietà è progettata per aumentare il numero di istanze in tutte le distribuzioni nel pool SQL dedicato senza influire sulle prestazioni di carico. Pertanto, l'implementazione di è orientata al raggiungimento di IDENTITY
questi obiettivi.
È possibile definire una tabella come con la proprietà quando si crea per IDENTITY
la prima volta la tabella usando una sintassi simile all'istruzione seguente:
CREATE TABLE dbo.T1
( C1 INT IDENTITY(1,1) NOT NULL,
C2 INT NULL
)
WITH
( DISTRIBUTION = HASH(C2),
CLUSTERED COLUMNSTORE INDEX
);
È quindi possibile usare INSERT..SELECT
per popolare la tabella.
Nella parte restante di questa sezione vengono evidenziate le sfumature dell'implementazione per comprenderle in modo più completo.
Allocazione dei valori
La IDENTITY
proprietà non garantisce l'ordine in cui i valori surrogati vengono allocati a causa dell'architettura distribuita del data warehouse. La IDENTITY
proprietà è progettata per aumentare il numero di istanze in tutte le distribuzioni nel pool SQL dedicato senza influire sulle prestazioni di carico.
L'esempio seguente è una dimostrazione:
CREATE TABLE dbo.T1
( C1 INT IDENTITY(1,1) NOT NULL,
C2 VARCHAR(30) NULL
)
WITH
( DISTRIBUTION = HASH(C2),
CLUSTERED COLUMNSTORE INDEX
);
INSERT INTO dbo.T1
VALUES (NULL);
INSERT INTO dbo.T1
VALUES (NULL);
SELECT *
FROM dbo.T1;
DBCC PDW_SHOWSPACEUSED('dbo.T1');
Nell'esempio precedente due righe raggiungono la distribuzione 1. La prima riga ha il valore surrogato 1 nella colonna C1
e la seconda riga ha il valore surrogato 61. Entrambi questi valori sono stati generati dalla IDENTITY
proprietà . Tuttavia, l'allocazione dei valori non è contigua. Questo comportamento è impostato a livello di progettazione.
Dati asimmetrici
L'intervallo di valori per il tipo di dati è distribuito uniformemente tra le distribuzioni. Nel caso di una tabella distribuita con dati asimmetrici, l'intervallo di valori disponibili per il tipo di dati può esaurirsi in modo anomalo. Ad esempio, se tutti i dati vengono destinati a una singola distribuzione, la tabella ha effettivamente accesso solo a un sessantesimo dei valori del tipo di dati. Per questo motivo, la IDENTITY
proprietà è limitata solo ai INT
tipi di dati e BIGINT
.
SELECT..INTO
Quando una colonna esistente IDENTITY
viene selezionata in una nuova tabella, la nuova colonna eredita la IDENTITY
proprietà, a meno che non venga soddisfatta una delle condizioni seguenti:
- L'istruzione
SELECT
contiene un join. - Più
SELECT
istruzioni vengono unite tramiteUNION
. - La
IDENTITY
colonna è elencata più volte nell'elencoSELECT
. - La
IDENTITY
colonna fa parte di un'espressione.
Se una di queste condizioni è vera, la colonna viene creata NOT NULL
invece di ereditare la IDENTITY
proprietà .
CREATE TABLE AS SELECT
CREATE TABLE AS SELECT
(CTAS) segue lo stesso comportamento di SQL Server documentato per SELECT..INTO
. Tuttavia, non è possibile specificare una IDENTITY
proprietà nella definizione di colonna della CREATE TABLE
parte dell'istruzione . Non è inoltre possibile usare la IDENTITY
funzione nella SELECT
parte di CTAS. Per popolare una tabella, è necessario usare l'istruzione CREATE TABLE
per definire la tabella, seguita da INSERT..SELECT
per popolarla.
Inserire valori espliciti in una colonna IDENTITY
Il pool SQL dedicato supporta la sintassi SET IDENTITY_INSERT <your table> ON|OFF
. È possibile usare questa sintassi per inserire in modo esplicito i valori nella IDENTITY
colonna.
Molti progettisti di modelli di dati preferiscono usare valori negativi predefiniti per alcune righe nelle dimensioni. Un esempio è la riga di membro -1 o sconosciuta.
Lo script successivo illustra come aggiungere in modo esplicito questa riga usando SET IDENTITY_INSERT
:
SET IDENTITY_INSERT dbo.T1 ON;
INSERT INTO dbo.T1
( C1,
C2
)
VALUES (-1,'UNKNOWN');
SET IDENTITY_INSERT dbo.T1 OFF;
SELECT *
FROM dbo.T1;
Caricare i dati
La presenza della IDENTITY
proprietà ha alcune implicazioni per il codice di caricamento dei dati. In questa sezione vengono illustrati alcuni modelli di base per il caricamento dei dati in tabelle tramite IDENTITY
.
Per caricare i dati in una tabella e generare una chiave surrogata usando IDENTITY
, creare la tabella e quindi usare INSERT..SELECT
o INSERT..VALUES
per eseguire il caricamento.
L'esempio seguente illustra il modello di base:
--CREATE TABLE with IDENTITY
CREATE TABLE dbo.T1
( C1 INT IDENTITY(1,1),
C2 VARCHAR(30)
)
WITH
( DISTRIBUTION = HASH(C2),
CLUSTERED COLUMNSTORE INDEX
);
--Use INSERT..SELECT to populate the table from an external table
INSERT INTO dbo.T1
(C2)
SELECT C2
FROM ext.T1;
SELECT *
FROM dbo.T1;
DBCC PDW_SHOWSPACEUSED('dbo.T1');
Nota
Non è possibile usare CREATE TABLE AS SELECT
attualmente durante il caricamento dei dati in una tabella con una IDENTITY
colonna.
Per altre informazioni sul caricamento dei dati, vedere Progettazione ELT (Extract, Load, Transform) per il pool SQL dedicato e Procedure consigliate per il caricamento.
Visualizzazioni di sistema
È possibile utilizzare la vista del catalogo sys.identity_columns per identificare una colonna con la IDENTITY
proprietà .
Per comprendere meglio lo schema del database, questo esempio mostra come integrare sys.identity_columns
con altre viste del catalogo di sistema:
SELECT sm.name
, tb.name
, co.name
, CASE WHEN ic.column_id IS NOT NULL
THEN 1
ELSE 0
END AS is_identity
FROM sys.schemas AS sm
JOIN sys.tables AS tb ON sm.schema_id = tb.schema_id
JOIN sys.columns AS co ON tb.object_id = co.object_id
LEFT JOIN sys.identity_columns AS ic ON co.object_id = ic.object_id
AND co.column_id = ic.column_id
WHERE sm.name = 'dbo'
AND tb.name = 'T1'
;
Limiti
La IDENTITY
proprietà non può essere usata:
- Quando il tipo di dati della colonna non
INT
è oBIGINT
- Quando la colonna è anche la chiave di distribuzione
- Quando la tabella è una tabella esterna
Le funzioni correlate seguenti non sono supportate nel pool SQL dedicato:
Attività comuni
È possibile usare il codice di esempio seguente per eseguire attività comuni quando si usano IDENTITY
colonne.
La colonna C1 è in IDENTITY
tutte le attività seguenti.
Individuare il valore massimo allocato per una tabella
Usare la funzione MAX()
per determinare il valore massimo allocato per una tabella distribuita:
SELECT MAX(C1)
FROM dbo.T1
Trovare il valore di seeding e incremento per la proprietà IDENTITY
È possibile usare le viste del catalogo per individuare i valori di configurazione di incremento e seeding di IDENTITY per una tabella usando la query seguente:
SELECT sm.name
, tb.name
, co.name
, ic.seed_value
, ic.increment_value
FROM sys.schemas AS sm
JOIN sys.tables AS tb ON sm.schema_id = tb.schema_id
JOIN sys.columns AS co ON tb.object_id = co.object_id
JOIN sys.identity_columns AS ic ON co.object_id = ic.object_id
AND co.column_id = ic.column_id
WHERE sm.name = 'dbo'
AND tb.name = 'T1'
;