SQL Server understøtter partitionerede tabeller og indekser. Når en opdelt tabel eller et opdelt indeks er opdelt, opdeles dens data i enheder, der kan spredes på tværs af mere end én filgruppe.
Derfor, for at oprette en partitioneret tabel i SQL Server, skal du først oprette den eller de filgrupper, der skal indeholde hver partition. Du skal også oprette en partitionsfunktion og et partitionsskema.
Så det går sådan her:
- Opret filgrupper
- Opret en partitionsfunktion
- Opret et partitionsskema
- Opret den partitionerede tabel
Nedenfor er et eksempel på brug af disse trin til at oprette en tabel med fire partitioner.
Opret filgrupper
Først tilføjer vi fire filgrupper til databasen kaldet Test , og angiv derefter den fysiske fil for hver af disse filgrupper.
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
Du bliver nødt til at ændre denne kode, afhængigt af dine krav. Du skal også ændre filstierne, så de passer til dit miljø. For eksempel, hvis du bruger Windows, kan din sti måske ligne D:\mssql\data\MoviesFg4dat.ndf
.
Hvis du har brug for flere partitioner, tilføj flere filgrupper her. Omvendt, hvis du har brug for færre partitioner, skal du angive færre filgrupper her.
Opret en partitionsfunktion
Dernæst opretter vi en partitionsfunktion kaldet MoviesPartitionFunction der vil opdele tabellen i fire partitioner.
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO
int part specificerer datatypen for den kolonne, der bruges til partitionering.
Alle datatyper er gyldige til brug som partitioneringskolonner, undtagen tekst , ntekst , billede , xml , tidsstempel , varchar(max) , nvarchar(max) , varbinary(max) , alias datatyper eller CLR brugerdefinerede datatyper.
Her bruger jeg tre grænseværdier (1, 100
og 1000
) for at angive fire partitioner. Disse grænseværdier skal enten matche eller være implicit konverterbare til den datatype, der er angivet i parentes efter partitionsfunktionens navn.
Givet disse grænseværdier, og det faktum, at jeg specificerede en RANGE LEFT
partition, vil de fire partitioner indeholde værdier som angivet i følgende tabel.
Partition | Værdier |
---|---|
1 | <= 1 |
2 | > 1 OG <= 100 |
3 | > 100 OG <=1000 |
4 | > 1000 |
Hvis jeg havde angivet en RANGE RIGHT
partition, ville opdelingen være lidt anderledes, som skitseret i følgende tabel.
Partition | Værdier |
---|---|
1 | < 1 |
2 | >= 1 OG < 100 |
3 | >= 100 OG < 1000 |
4 | >= 1000 |
Det samme koncept gælder, hvis partitioneringskolonnen bruger andre datatyper, såsom dato/tidsværdier.
Opret et partitionsskema
Dernæst skal vi oprette et partitionsskema.
Et partitionsskema kortlægger partitionerne i en opdelt tabel eller indeks til de nye filgrupper.
I vores tilfælde vil koden se sådan ud:
CREATE PARTITION SCHEME MoviesPartitionScheme
AS PARTITION MoviesPartitionFunction
TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);
GO
Bemærk, at vi refererer til partitionsfunktionen, som vi oprettede i det foregående trin. Vi henviser også til de filgrupper, som vi oprettede i det første trin.
Opret den opdelte tabel
Endelig kan vi oprette den partitionerede tabel.
CREATE TABLE Movies (
MovieId int IDENTITY PRIMARY KEY,
MovieName varchar(60)
)
ON MoviesPartitionScheme (MovieId);
GO
Den eneste forskel mellem dette og oprettelse af en uopdelt tabel er, at når vi opretter en opdelt tabel, bruger vi ON
argument for at angive et partitionsskema, der skal bruges. I vores tilfælde angiver vi det partitionsskema, vi oprettede i det forrige trin, og specificerer MovieId kolonne som partitioneringskolonne.
Du vil bemærke, at MovieId kolonne har en datatype på int , som matcher de grænseværdier, som vi specificerede, da vi oprettede partitionsfunktionen.
Bemærk, at hvis du bruger en beregnet kolonne i en partitionsfunktion, skal den udtrykkeligt markeres med PERSISTED
.
Tjek partitionsfunktionen
Du kan bruge sys.partition_functions
view for at returnere alle partitionsfunktioner.
SELECT * FROM sys.partition_functions;
Resultat (ved hjælp af lodret output):
Tjek partitionsskemaet
Du kan bruge sys.partition_schemes
for at kontrollere partitionsskemaet.
SELECT * FROM sys.partition_schemes;
Resultat (ved hjælp af lodret output):
Alternativt kan du bruge følgende forespørgsel til at returnere andre detaljer, såsom skema, tabel, indeks osv.
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;
Resultat (ved hjælp af lodret output):
Tjek den opdelte tabel
Du kan køre sys.dm_db_partition_stats
visning for at returnere side- og rækkeoplysninger for hver partition i den aktuelle database.
Men at køre det, før du indsætter data i tabellen, vil resultere i, at de fleste statistikker er nul.
Så jeg vil først indsætte data.
INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;
Resultat:
(4079 rækker påvirket)
Vi kan se, at der blev indsat 4.079 rækker.
Lad os nu forespørge sys.dm_db_partition_stats
se.
SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultat:
+--------------------+-------------+---------------- +--------------------+--------------------------------+- --------------------------+------------------------ ------+--------------------------+--------------------- --------+--------------------------------+-------- ----------------------------+--------------------+- ----------------------+-------------+| partition_id | objekt-id | index_id | partitionsnummer | 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 | brugt_sideantal | reserverede_sideantal | række_antal ||-------------------+-------------+------------+ --------------------+----------------------------------+-- --------------------+------------------------- -----+--------------------------+---------------------- -------+--------------------------------+--------- --------------------------+--------------------+-- --------------------+-------------|| 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 |+--------------------+-------------+------------+ --------------------+----------------------------------+-- --------------------+------------------------- -----+--------------------------+---------------------- -------+--------------------------------+--------- --------------------------+--------------------+-- --------------------+-------------+
Denne visning returnerer mange kolonner, så lad os indsnævre kolonnerne til kun et par.
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultat:
+---------------------+----------+| partitionsnummer | række_antal ||---------------------+--------|| 1 | 1 || 2 | 99 || 3 | 900 || 4 | 3079 |+---------------------+-------------+
Vi kan se, hvordan rækkerne er fordelt på tværs af partitionerne. De er tildelt nøjagtigt som vi specificerede i partitionsfunktionen. Rækkerne i alt 4.079, hvilket er præcis hvor mange rækker vi indsatte.
Det er dog værd at bemærke, at Microsoft-dokumentationen faktisk angiver, at denne kolonne kun er en ca. antal rækker i hver partition.
Bedste praksis
Microsoft anbefaler, at vi altid holder tomme partitioner i begge ender af partitionsområdet.
Dette er tilfældet, hvis du skal enten opdele eller flette partitionerne i fremtiden.
Årsagen til denne anbefaling er at garantere, at partitionsopdelingen og partitionens fletning ikke medfører nogen uventet databevægelse.
Derfor, givet dataene i mit eksempel, kunne jeg ændre partitionsfunktionen til at se sådan ud:
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO
Eller hvis jeg forventer mere end 10.000 rækker, kunne jeg bruge et større antal (eller oprette flere partitioner).
Hvis jeg skulle genskabe alle trinene igen, for at oprette min partitionerede tabel, ville min partitionsstatistik se sådan ud:
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultat:
+---------------------+----------+| partitionsnummer | række_antal ||---------------------+--------|| 1 | 0 || 2 | 100 || 3 | 3979 || 4 | 0 |+--------------------+-------------+
Nu er mine data koncentreret i de to midterste partitioner, og partitionerne i begge ender er tomme.