Uso de IDENTITY para crear claves suplentes en un grupo de SQL dedicado
En este artículo, encontrará recomendaciones y ejemplos para usar la propiedad IDENTITY
para crear claves suplentes en tablas del grupo de SQL dedicado.
¿Qué es una clave suplente?
Una clave suplente en una tabla es una columna con un identificador único para cada fila. La clave no se genera a partir de los datos de la tabla. A los modeladores de datos les gusta crear claves suplentes en las tablas cuando diseñan modelos de almacenamiento de datos. Puede usar la propiedad IDENTITY
para lograr este objetivo de forma sencilla y eficaz sin afectar al rendimiento de la carga.
Nota:
En Azure Synapse Analytics:
- El valor IDENTITY aumenta por sí mismo en cada distribución y no se superpone con los valores IDENTITY de otras distribuciones. No se garantiza que el valor IDENTITY de Synapse sea único si el usuario inserta explícitamente un valor duplicado con
SET IDENTITY_INSERT ON
o vuelve a usar IDENTITY. Para detalles, consulte CREATE TABLE (Transact-SQL) IDENTITY (propiedad). - UPDATE en la columna de distribución no garantiza que el valor IDENTITY sea único. Utilice DBCC CHECKIDENT (Transact-SQL) después de ACTUALIZAR en la columna de distribución para verificar la unicidad.
Creación de una tabla con una columna IDENTITY
La propiedad IDENTITY
está diseñada para escalar horizontalmente en todas las distribuciones del grupo de SQL dedicado sin afectar al rendimiento de la carga. Por lo tanto, la implementación de IDENTITY
está orientada a lograr estos objetivos.
Puede definir una tabla como tener la propiedad IDENTITY
al crear la tabla por primera vez mediante la sintaxis similar a la siguiente instrucción:
CREATE TABLE dbo.T1
( C1 INT IDENTITY(1,1) NOT NULL,
C2 INT NULL
)
WITH
( DISTRIBUTION = HASH(C2),
CLUSTERED COLUMNSTORE INDEX
);
Luego puede usar INSERT..SELECT
para rellenar la tabla.
En el resto de esta sección se resaltan los matices de la implementación para ayudarle a comprenderlos más completamente.
Asignación de valores
La propiedad IDENTITY
no garantiza el orden en que se asignan los valores suplentes debido a la arquitectura distribuida del almacenamiento de datos. La propiedad IDENTITY
está diseñada para escalar horizontalmente en todas las distribuciones del grupo de SQL dedicado sin afectar al rendimiento de la carga.
El ejemplo siguiente sirve de muestra:
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');
En el ejemplo anterior, dos filas quedaron en la distribución 1. La primera fila tiene el valor suplente de 1 en la columna C1
y la segunda fila tiene el valor suplente de 61. Ambos valores se generaron mediante la propiedad IDENTITY
. Sin embargo, la asignación de los valores no es contigua. Este comportamiento es así por diseño.
Datos sesgados
El intervalo de valores del tipo de datos se reparte uniformemente entre las distribuciones. Si una tabla distribuida adolece de datos sesgados, el intervalo de valores disponible para el tipo de datos se puede agotar antes de tiempo. Por ejemplo, si todos los datos terminan en una sola distribución, en la práctica, la tabla tiene acceso a únicamente la sexta parte de los valores del tipo de datos. Por este motivo, la propiedad IDENTITY
se limita solo a los tipos de datos INT
y BIGINT
.
SELECT..INTO
Cuando se selecciona una columna IDENTITY
existente en una nueva tabla, la nueva columna hereda la propiedad IDENTITY
, a menos que se cumpla una de las condiciones siguientes:
- La instrucción
SELECT
contiene una combinación. - Varias instrucciones
SELECT
se unen medianteUNION
. - La columna
IDENTITY
aparece más de una vez en la lista deSELECT
. - La columna
IDENTITY
forma parte de una expresión.
Si alguna de estas condiciones es true, la columna se crea NOT NULL
en lugar de heredar la propiedad IDENTITY
.
CREATE TABLE AS SELECT
CREATE TABLE AS SELECT
(CTAS) sigue el mismo comportamiento de SQL Server que se documenta para SELECT..INTO
. Sin embargo, no se puede especificar una propiedad IDENTITY
en la definición de columna de la parte CREATE TABLE
de la instrucción. Tampoco puede usar la función IDENTITY
en la parte SELECT
de CTAS. Para rellenar una tabla, hay que usar CREATE TABLE
para definir la tabla seguido de INSERT..SELECT
para rellenarla.
Insertar valores explícitos en una columna IDENTITY
El grupo de SQL dedicado admite la sintaxis SET IDENTITY_INSERT <your table> ON|OFF
. Puede usar esta sintaxis para insertar explícitamente valores en la columna IDENTITY
.
A muchos modeladores de datos les gusta usar valores negativos predefinidos para determinadas filas en las dimensiones. Un ejemplo es la fila -1 o miembro desconocido.
El siguiente script muestra cómo agregar explícitamente esta fila mediante 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;
Cargar datos
La presencia de la propiedad IDENTITY
tiene algunas implicaciones en el código de carga de datos. En esta sección se resaltan algunos patrones básicos para cargar datos en tablas mediante IDENTITY
.
Para cargar datos en una tabla y generar una clave suplente mediante IDENTITY
, cree la tabla y, a continuación, use INSERT..SELECT
o INSERT..VALUES
para realizar la carga.
En el siguiente ejemplo se resalta el patrón básico:
--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:
No es posible usar CREATE TABLE AS SELECT
actualmente al cargar datos en una tabla con una columna de IDENTITY
.
Para más información sobre la carga de datos, consulte Diseño de un proceso de extracción, carga y transformación (ELT) para el grupo de SQL dedicado y Procedimientos recomendados para la carga de datos.
Vistas del sistema
Puede usar la vista de catálogo de sys.identity_columns para identificar una columna que tenga la propiedad IDENTITY
.
Para ayudarle a comprender mejor el esquema de la base de datos, en este ejemplo se muestra cómo integrar sys.identity_columns
con otras vistas de catálogo del 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'
;
Limitaciones
No se puede usar la propiedad IDENTITY
:
- Cuando el tipo de datos de columna no se
INT
oBIGINT
- Cuando la columna es también la clave de distribución
- Cuando la tabla es una tabla externa
Las siguientes funciones relacionadas no se admiten en el grupo de SQL dedicado:
Tareas comunes
Puede usar el código de ejemplo siguiente para realizar tareas comunes al trabajar con IDENTITY
columnas.
La columna C1 es el IDENTITY
en todas las tareas siguientes.
Búsqueda del valor más alto asignado en una tabla
Use la función MAX()
para determinar el valor más alto asignado en una tabla distribuida:
SELECT MAX(C1)
FROM dbo.T1
Búsqueda del valor de inicialización e incremento de la propiedad IDENTITY
Puede usar las vistas de catálogo para detectar los valores de configuración de inicialización e incremento de identidad en una tabla mediante la siguiente consulta:
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'
;