I SQL Server kan du byta partitioner in och ut från en partitionerad tabell.
Du kan göra detta med ALTER TABLE
påstående. I grund och botten går det så här:
ALTER TABLE OldTable
SWITCH TO NewTable PARTITION x
Detta växlar partitionen för OldTable
till partitionen x
av NewTable
(där x
är partitionsnumret).
Exempel
Innan vi börjar byta in, låt oss sätta upp två tabeller. En (kallad OrdersOld
) kommer att innehålla data som vi vill "växla in" till den andra tabellen (kallas OrdersNew
).
Vi kommer att partitionera OrdersNew
i fyra partitioner.
-- 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;
Resultat:
+-------------+ | OrdersOld | |-------------| | 5 | +-------------+ +-------------+ | OrdersNew | |-------------| | 0 | +-------------+
Så som det ser ut just nu, OrdersOld
innehåller 5 rader och OrdersNew
är tom.
Dags att byta in data.
ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;
Resultat:
Commands completed successfully.
Data har nu växlats till partition 3 i destinationstabellen.
Låt oss kontrollera båda tabellerna igen.
SELECT COUNT(*) AS OrdersOld
FROM OrdersOld;
SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;
Resultat:
+-------------+ | OrdersOld | |-------------| | 0 | +-------------+ +-------------+ | OrdersNew | |-------------| | 5 | +-------------+
Den här gången OrdersOld
är tom och OrdersNew
innehåller 5 rader.
Vi kan också köra följande fråga för att kontrollera den faktiska partitionen som data finns i.
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];
Resultat:
+-------------+--------------+--------+ | Partition | Filegroup | Rows | |-------------+--------------+--------| | 1 | OrdersNewFg1 | 0 | | 2 | OrdersNewFg2 | 0 | | 3 | OrdersNewFg3 | 5 | | 4 | OrdersNewFg4 | 0 | +-------------+--------------+--------+
Som förväntat är alla 5 rader allokerade till partition 3, i OrdersNewFg3
filgrupp.
Vanliga fel
Fel 4982
I mitt exempel ovan kommer du att märka att jag skapade en CHECK
begränsning när du skapar OrdersOld
bord.
Om du får felmeddelande 4982 (ALTER TABLE SWITCH statement failed...
), kan det vara så att du inte skapade en CHECK
begränsning på källtabellen.
Eller så kan det vara så att du skapade en CHECK
begränsning, men den tvingar inte fram värden mellan intervallet för inkopplingspartitionen.
Du måste se till att inkopplingsvärdena faktiskt ligger inom det intervall som definieras av partitionen, och SQL Server kommer att leta efter en CHECK
begränsning på källtabellen som verifierar detta.
Fel 4939
Ett annat vanligt är fel 4939 (ALTER TABLE SWITCH statement failed...
).
Om du får det här felet beror det förmodligen på att du försöker byta till en partition som använder en annan filgrupp än källtabellen.
Ett av kraven för att byta partitioner är att både källtabellen eller partitionen och måltabellen eller partitionen måste finnas i samma filgrupp.
För att åtgärda detta fel, se till att källtabellen använder samma filgrupp som målpartitionen.
Byter ut
Se Byta ut en partition i SQL Server för hur man byter ut en partition.