Use IDENTITY para criar chaves substitutas no pool SQL dedicado
Neste artigo, você encontrará recomendações e exemplos para usar a propriedade para criar chaves substitutas IDENTITY
em tabelas no pool SQL dedicado.
O que é uma chave substituta?
Uma chave substituta em uma tabela é uma coluna com um identificador exclusivo para cada linha. A chave não é gerada a partir dos dados da tabela. Os modeladores de dados gostam de criar chaves substitutas em suas tabelas quando projetam modelos de data warehouse. Você pode usar a propriedade para atingir esse objetivo de forma simples e eficaz, sem afetar o desempenho da IDENTITY
carga.
Nota
No Azure Synapse Analytics:
- O valor IDENTITY aumenta por si só em cada distribuição e não se sobrepõe aos valores IDENTITY noutras distribuições. Não é garantido que o valor IDENTITY no Synapse seja exclusivo se o usuário inserir explicitamente um valor duplicado com
SET IDENTITY_INSERT ON
IDENTITY ou repropagar. Para obter detalhes, consulte CREATE TABLE (Transact-SQL) IDENTITY (Property). - UPDATE na coluna de distribuição não garante que o valor IDENTITY seja exclusivo. Use DBCC CHECKIDENT (Transact-SQL) após UPDATE na coluna de distribuição para verificar a exclusividade.
Criar uma tabela com uma coluna IDENTITY
A IDENTITY
propriedade foi projetada para ser dimensionada em todas as distribuições no pool SQL dedicado sem afetar o desempenho da carga. Portanto, a implementação do IDENTITY
é orientada para o alcance desses objetivos.
Você pode definir uma tabela como tendo a IDENTITY
propriedade quando você cria a tabela pela primeira vez usando sintaxe semelhante à seguinte instrução:
CREATE TABLE dbo.T1
( C1 INT IDENTITY(1,1) NOT NULL,
C2 INT NULL
)
WITH
( DISTRIBUTION = HASH(C2),
CLUSTERED COLUMNSTORE INDEX
);
Em seguida, você pode usar INSERT..SELECT
para preencher a tabela.
O restante desta seção destaca as nuances da implementação para ajudá-lo a entendê-las mais completamente.
Atribuição de valores
A IDENTITY
propriedade não garante a ordem em que os valores substitutos são alocados devido à arquitetura distribuída do data warehouse. A IDENTITY
propriedade foi projetada para ser dimensionada em todas as distribuições no pool SQL dedicado sem afetar o desempenho da carga.
O exemplo a seguir é uma ilustração:
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');
No exemplo anterior, duas linhas aterrissaram na distribuição 1. A primeira linha tem o valor substituto de 1 na coluna C1
e a segunda linha tem o valor substituto de 61. Ambos os valores foram gerados pelo IDENTITY
imóvel. No entanto, a alocação dos valores não é contígua. Este comportamento é a predefinição.
Dados distorcidos
O intervalo de valores para o tipo de dados é distribuído uniformemente pelas distribuições. Se uma tabela distribuída tiver dados distorcidos, o intervalo de valores disponível para o tipo de dados poderá ser esgotado prematuramente. Por exemplo, se todos os dados acabarem em uma única distribuição, então efetivamente a tabela terá acesso a apenas um sexagésimo dos valores do tipo de dados. Por esse motivo, a IDENTITY
propriedade é limitada apenas aos BIGINT
INT
tipos de dados.
SELECIONE.. EM
Quando uma coluna existente IDENTITY
é selecionada em uma nova tabela, a nova coluna herda a propriedade, a IDENTITY
menos que uma das seguintes condições seja verdadeira:
- A
SELECT
declaração contém uma junção. - Várias
SELECT
instruções são unidas usandoUNION
. - A
IDENTITY
coluna é listada mais de uma vez naSELECT
lista. - A
IDENTITY
coluna faz parte de uma expressão.
Se qualquer uma dessas condições for verdadeira, a coluna será criada NOT NULL
em vez de herdar a IDENTITY
propriedade.
CREATE TABLE AS SELECT
CREATE TABLE AS SELECT
(CTAS) segue o mesmo comportamento do SQL Server documentado para SELECT..INTO
. No entanto, não é possível especificar uma IDENTITY
propriedade na definição de coluna da CREATE TABLE
parte da instrução. Você também não pode usar a IDENTITY
função na SELECT
parte do CTAS. Para preencher uma tabela, você precisa usar CREATE TABLE
para definir a tabela seguida para INSERT..SELECT
preenchê-la.
Inserir valores explícitos em uma coluna IDENTITY
O pool SQL dedicado oferece suporte à SET IDENTITY_INSERT <your table> ON|OFF
sintaxe. Você pode usar essa sintaxe para inserir valores explicitamente na IDENTITY
coluna.
Muitos modeladores de dados gostam de usar valores negativos predefinidos para determinadas linhas em suas dimensões. Um exemplo é a -1 ou linha de membro desconhecido.
O próximo script mostra como adicionar explicitamente essa linha 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;
Carregar dados
A presença da propriedade tem algumas implicações para o IDENTITY
seu código de carregamento de dados. Esta seção destaca alguns padrões básicos para carregar dados em tabelas usando IDENTITY
.
Para carregar dados em uma tabela e gerar uma chave substituta usando IDENTITY
, crie a tabela e, em seguida, use INSERT..SELECT
ou INSERT..VALUES
execute a carga.
O exemplo a seguir destaca o padrão 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
Não é possível usar CREATE TABLE AS SELECT
atualmente ao carregar dados em uma tabela com uma IDENTITY
coluna.
Para obter mais informações sobre como carregar dados, consulte Projetando extração, carga e transformação (ELT) para pool SQL dedicado e Carregando práticas recomendadas.
Vistas de sistema
Você pode usar a exibição de catálogo sys.identity_columns para identificar uma coluna que tenha a IDENTITY
propriedade.
Para ajudá-lo a entender melhor o esquema do banco de dados, este exemplo mostra como integrar sys.identity_columns
com outras exibições do catálogo do 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'
;
Limitações
A IDENTITY
propriedade não pode ser usada:
- Quando o tipo de dados da coluna não
INT
é ouBIGINT
- Quando a coluna é também a chave de distribuição
- Quando a tabela é uma tabela externa
As seguintes funções relacionadas não são suportadas no pool SQL dedicado:
Tarefas comuns
Você pode usar o código de exemplo a seguir para executar tarefas comuns ao trabalhar com IDENTITY
colunas.
A coluna C1 é a IDENTITY
presente em todas as tarefas seguintes.
Encontrar o valor alocado mais alto para uma tabela
Use a MAX()
função para determinar o maior valor alocado para uma tabela distribuída:
SELECT MAX(C1)
FROM dbo.T1
Encontre a semente e o incremento para a propriedade IDENTITY
Você pode usar as exibições de catálogo para descobrir o incremento de identidade e os valores de configuração de propagação para uma tabela usando a seguinte 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'
;