O SQL Server oferece suporte a tabelas e índices particionados. Quando uma tabela ou índice particionado é particionado, seus dados são divididos em unidades que podem ser distribuídas por mais de um grupo de arquivos.
Portanto, para criar uma tabela particionada no SQL Server, primeiro você precisa criar os grupos de arquivos que conterão cada partição. Você também precisa criar uma função de partição e um esquema de partição.
Então fica assim:
- Criar grupos de arquivos
- Criar uma função de partição
- Criar um esquema de partição
- Crie a tabela particionada
Abaixo está um exemplo de como usar essas etapas para criar uma tabela com quatro partições.
Criar grupos de arquivos
Primeiro, adicionamos quatro grupos de arquivos ao banco de dados chamado Test e especifique o arquivo físico para cada um desses grupos de arquivos.
ALTER DATABASE Test
ADD FILEGROUP MoviesFg1;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg2;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg3;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg4;
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg1dat,
FILENAME = '/var/opt/mssql/data/MoviesFg1dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg1;
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg2dat,
FILENAME = '/var/opt/mssql/data/MoviesFg2dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg2;
GO
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg3dat,
FILENAME = '/var/opt/mssql/data/MoviesFg3dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg3;
GO
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg4dat,
FILENAME = '/var/opt/mssql/data/MoviesFg4dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg4;
GO
Você precisará alterar esse código, dependendo de seus requisitos. Você também precisará alterar os caminhos de arquivo para se adequar ao seu ambiente. Por exemplo, se você estiver no Windows, seu caminho pode se parecer mais com
D:\mssql\data\MoviesFg4dat.ndf
. Além disso, se você precisar de mais partições, adicione mais grupos de arquivos aqui. Por outro lado, se você precisar de menos partições, especifique menos grupos de arquivos aqui.
Criar uma função de partição
Em seguida, criamos uma função de partição chamada MoviesPartitionFunction que irá particionar a tabela em quatro partições.
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO
O int parte especifica o tipo de dados da coluna usada para particionamento.
Todos os tipos de dados são válidos para uso como colunas de particionamento, exceto texto , ntext , imagem , xml , carimbo de data e hora , varchar(max) , nvarchar(max) , varbinary(max) , tipos de dados de alias ou tipos de dados CLR definidos pelo usuário.
Aqui, eu uso três valores de limite (1,
100
e 1000
) para especificar quatro partições. Esses valores de limite devem corresponder ou ser implicitamente conversíveis para o tipo de dados especificado entre parênteses após o nome da função de partição. Dados esses valores de limite e o fato de eu especificar um
RANGE LEFT
partição, as quatro partições manterão os valores especificados na tabela a seguir. Partição | Valores |
---|---|
1 | <= 1 |
2 | > 1 E <= 100 |
3 | > 100 E <=1000 |
4 | > 1000 |
Se eu tivesse especificado um
RANGE RIGHT
partição, a divisão seria um pouco diferente, conforme descrito na tabela a seguir. Partição | Valores |
---|---|
1 | < 1 |
2 | >= 1 E < 100 |
3 | >= 100 E < 1000 |
4 | >= 1000 |
O mesmo conceito se aplica se a coluna de particionamento usar outros tipos de dados, como valores de data/hora.
Criar um esquema de partição
Em seguida, precisamos criar um esquema de partição.
Um esquema de partição mapeia as partições de uma tabela ou índice particionado para os novos grupos de arquivos.
No nosso caso, o código ficará assim:
CREATE PARTITION SCHEME MoviesPartitionScheme
AS PARTITION MoviesPartitionFunction
TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);
GO
Observe que fazemos referência à função de partição que criamos na etapa anterior. Também referenciamos os grupos de arquivos que criamos na primeira etapa.
Criar a tabela particionada
Finalmente, podemos criar a tabela particionada.
CREATE TABLE Movies (
MovieId int IDENTITY PRIMARY KEY,
MovieName varchar(60)
)
ON MoviesPartitionScheme (MovieId);
GO
A única diferença entre isso e criar uma tabela não particionada é que ao criar uma tabela particionada, usamos o
ON
argumento para especificar um esquema de partição a ser usado. No nosso caso, especificamos o esquema de partição que criamos na etapa anterior e especificamos o MovieId coluna como a coluna de particionamento. Você notará que o MovieId coluna tem um tipo de dados de int , que corresponde aos valores de limite que especificamos ao criar a função de partição.
Observe que, se você usar uma coluna computada em uma função de partição, ela deverá ser marcada explicitamente como
PERSISTED
. Verifique a função de partição
Você pode usar as
sys.partition_functions
view para retornar todas as funções de partição. SELECT * FROM sys.partition_functions;
Resultado (usando saída vertical):
name | MoviesPartitionFunction function_id | 65536 type | R type_desc | RANGE fanout | 4 boundary_value_on_right | 0 is_system | 0 create_date | 2020-10-10 05:37:41.330 modify_date | 2020-10-10 05:37:41.330
Verifique o esquema de partição
Você pode usar
sys.partition_schemes
para verificar o esquema de partição. SELECT * FROM sys.partition_schemes;
Resultado (usando saída vertical):
name | MoviesPartitionScheme data_space_id | 65601 type | PS type_desc | PARTITION_SCHEME is_default | 0 is_system | 0 function_id | 65536
Como alternativa, você pode usar a consulta a seguir para retornar outros detalhes, como esquema, tabela, índice etc.
SELECT
object_schema_name(i.object_id) AS [Schema],
object_name(i.object_id) AS [Object],
i.name AS [Index],
s.name AS [Partition Scheme]
FROM sys.indexes i
INNER JOIN sys.partition_schemes s ON i.data_space_id = s.data_space_id;
Resultado (usando saída vertical):
Schema | dbo Object | Movies Index | PK__Movies__4BD2941A0ED85ACA Partition Scheme | MoviesPartitionScheme
Verifique a tabela particionada
Você pode executar o
sys.dm_db_partition_stats
view para retornar informações de página e contagem de linhas para cada partição no banco de dados atual. Mas executar isso antes de inserir qualquer dado na tabela fará com que a maioria das estatísticas seja zero.
Então eu vou inserir os dados primeiro.
INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;
Resultado:
(4079 rows affected)
Podemos ver que foram inseridas 4.079 linhas.
Agora vamos consultar o
sys.dm_db_partition_stats
visualizar. SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultado:
+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+ | partition_id | object_id | index_id | partition_number | in_row_data_page_count | in_row_used_page_count | in_row_reserved_page_count | lob_used_page_count | lob_reserved_page_count | row_overflow_used_page_count | row_overflow_reserved_page_count | used_page_count | reserved_page_count | row_count | |-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------| | 72057594048413696 | 2030630277 | 1 | 1 | 1 | 2 | 9 | 0 | 0 | 0 | 0 | 2 | 9 | 1 | | 72057594048479232 | 2030630277 | 1 | 2 | 1 | 2 | 9 | 0 | 0 | 0 | 0 | 2 | 9 | 99 | | 72057594048544768 | 2030630277 | 1 | 3 | 3 | 5 | 25 | 0 | 0 | 0 | 0 | 5 | 25 | 900 | | 72057594048610304 | 2030630277 | 1 | 4 | 10 | 12 | 33 | 0 | 0 | 0 | 0 | 12 | 33 | 3079 | +-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+
Essa visualização retorna muitas colunas, então vamos restringir as colunas a apenas algumas.
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultado:
+--------------------+-------------+ | partition_number | row_count | |--------------------+-------------| | 1 | 1 | | 2 | 99 | | 3 | 900 | | 4 | 3079 | +--------------------+-------------+
Podemos ver como as linhas são alocadas nas partições. Eles são alocados exatamente como especificamos na função de partição. As linhas totalizam 4.079, que é exatamente quantas linhas inserimos.
No entanto, vale a pena notar que a documentação da Microsoft realmente afirma que esta coluna é apenas um aproximado contagem das linhas em cada partição.
Prática recomendada
A Microsoft recomenda que sempre mantenhamos partições vazias em ambas as extremidades do intervalo de partição.
Isso é no caso de você precisar dividir ou mesclar as partições no futuro.
O motivo dessa recomendação é garantir que a divisão da partição e a mesclagem da partição não incorram em nenhuma movimentação inesperada de dados.
Portanto, dados os dados no meu exemplo, eu poderia alterar a função de partição para algo assim:
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO
Ou se eu antecipar mais de 10.000 linhas, posso usar um número maior (ou criar mais partições).
Se eu recriasse todas as etapas novamente, para criar minha tabela particionada, minhas estatísticas de partição ficariam assim:
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultado:
+--------------------+-------------+ | partition_number | row_count | |--------------------+-------------| | 1 | 0 | | 2 | 100 | | 3 | 3979 | | 4 | 0 | +--------------------+-------------+
Agora meus dados estão concentrados nas duas partições do meio e as partições nas duas extremidades estão vazias.