No SQL Server, você pode alternar entre partições de uma tabela particionada.
Você pode fazer isso com o
ALTER TABLE
demonstração. Basicamente, fica assim:ALTER TABLE OldTable
SWITCH TO NewTable PARTITION x
Isso muda a partição para
OldTable
na partição x
de NewTable
(onde x
é o número da partição). Exemplo
Antes de começarmos a mudar, vamos configurar duas tabelas. Um (chamado
OrdersOld
) conterá os dados que queremos “trocar” para a outra tabela (chamada OrdersNew
). Vamos particionar
OrdersNew
em quatro partições. -- Create filegroups
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg1;
GO
ALTER DATABASE Test ADD FILE (
NAME = OrdersNewFg1dat,
FILENAME = '/var/opt/mssql/data/OrdersNewFg1dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP OrdersNewFg1;
GO
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg2;
GO
ALTER DATABASE Test ADD FILE (
NAME = OrdersNewFg2dat,
FILENAME = '/var/opt/mssql/data/OrdersNewFg2dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP OrdersNewFg2;
GO
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg3;
GO
ALTER DATABASE Test ADD FILE (
NAME = OrdersNewFg3dat,
FILENAME = '/var/opt/mssql/data/OrdersNewFg3dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP OrdersNewFg3;
GO
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg4;
GO
ALTER DATABASE Test ADD FILE (
NAME = OrdersNewFg4dat,
FILENAME = '/var/opt/mssql/data/OrdersNewFg4dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP OrdersNewFg4;
GO
-- Create a partition function that will result in four partitions
CREATE PARTITION FUNCTION OrdersNewPartitionFunction (date)
AS RANGE RIGHT FOR VALUES (
'20200201',
'20200301',
'20200401'
);
GO
-- Create a partition scheme that maps the partitions to the filegroups
CREATE PARTITION SCHEME OrdersNewPartitionScheme
AS PARTITION OrdersNewPartitionFunction
TO (
OrdersNewFg1,
OrdersNewFg2,
OrdersNewFg3,
OrdersNewFg4
);
GO
-- Create a table that contains the data that we will be switching in.
-- Note that the filegroup matches the filegroup of the partition that we will switch in to.
-- Include CHECK constraint to restrict data to the range specified in the switch-in partition
CREATE TABLE OrdersOld (
OrderDate date NOT NULL,
OrderId int IDENTITY NOT NULL,
OrderDesc varchar(255) NOT NULL,
CONSTRAINT chkDate CHECK (OrderDate >= '20200301' AND OrderDate < '20200401'),
CONSTRAINT PKOrdersOld PRIMARY KEY CLUSTERED(OrderDate, OrderId)
)
ON OrdersNewFg3;
GO
-- Insert data into the OrdersOld table. This is the data we will be switching in to the OrdersNew table.
INSERT INTO OrdersOld(OrderDate, OrderDesc) VALUES
('20200302', 'Cat food'),
('20200315', 'Water bowl'),
('20200318', 'Saddle for camel'),
('20200321', 'Dog biscuits'),
('20200328', 'Bigfoot shoes');
GO
-- Create a partitioned table called OrdersNew that uses the OrderDate column as the partitioning column
CREATE TABLE OrdersNew (
OrderDate date NOT NULL,
OrderId int IDENTITY NOT NULL,
OrderDesc varchar(255) NOT NULL,
CONSTRAINT PKOrdersNew PRIMARY KEY CLUSTERED(OrderDate, OrderId)
)
ON OrdersNewPartitionScheme (OrderDate);
GO
-- Check how many rows are in each table
SELECT COUNT(*) AS OrdersOld
FROM OrdersOld;
SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;
Resultado:
+-------------+ | OrdersOld | |-------------| | 5 | +-------------+ +-------------+ | OrdersNew | |-------------| | 0 | +-------------+
Então, como está agora,
OrdersOld
contém 5 linhas e OrdersNew
está vazia. Hora de mudar os dados.
ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;
Resultado:
Commands completed successfully.
Os dados agora foram alternados com sucesso para a partição 3 da tabela de destino.
Vamos verificar as duas tabelas novamente.
SELECT COUNT(*) AS OrdersOld
FROM OrdersOld;
SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;
Resultado:
+-------------+ | OrdersOld | |-------------| | 0 | +-------------+ +-------------+ | OrdersNew | |-------------| | 5 | +-------------+
Desta vez
OrdersOld
está vazio e OrdersNew
contém 5 linhas. Também podemos executar a seguinte consulta para verificar a partição real em que os dados estão localizados.
SELECT
p.partition_number AS [Partition],
fg.name AS [Filegroup],
p.Rows
FROM sys.partitions p
INNER JOIN sys.allocation_units au
ON au.container_id = p.hobt_id
INNER JOIN sys.filegroups fg
ON fg.data_space_id = au.data_space_id
WHERE p.object_id = OBJECT_ID('OrdersNew')
ORDER BY [Partition];
Resultado:
+-------------+--------------+--------+ | Partition | Filegroup | Rows | |-------------+--------------+--------| | 1 | OrdersNewFg1 | 0 | | 2 | OrdersNewFg2 | 0 | | 3 | OrdersNewFg3 | 5 | | 4 | OrdersNewFg4 | 0 | +-------------+--------------+--------+
Como esperado, todas as 5 linhas são alocadas para a partição 3, no
OrdersNewFg3
grupo de arquivos. Erros comuns
Erro 4982
No meu exemplo acima, você notará que criei um
CHECK
restrição ao criar o OrdersOld
tabela. Se você receber a mensagem de erro 4982 (
ALTER TABLE SWITCH statement failed...
), pode ser que você não tenha criado um CHECK
restrição na tabela de origem. Ou pode ser que você tenha criado um
CHECK
restrição, mas não impõe valores entre o intervalo da partição de comutação. Você precisa garantir que os valores de comutação estejam, de fato, dentro do intervalo definido pela partição, e o SQL Server procurará um
CHECK
restrição na tabela de origem que verifica isso. Erro 4939
Outro comum é o erro 4939 (falha na instrução
ALTER TABLE SWITCH statement failed...
). Se você receber esse erro, provavelmente é porque está tentando alternar para uma partição que usa um grupo de arquivos diferente da tabela de origem.
Um dos requisitos para alternar partições é que tanto a tabela ou partição de origem quanto a tabela ou partição de destino devem estar localizadas no mesmo grupo de arquivos.
Para corrigir esse erro, verifique se a tabela de origem usa o mesmo grupo de arquivos que a partição de destino.
Desligando
Consulte Alternar uma partição no SQL Server para saber como desativar uma partição.