sql >> Databasteknik >  >> RDS >> Sqlserver

Skapa en partitionerad tabell i SQL Server (T-SQL)

SQL Server stöder partitionerade tabeller och index. När en partitionerad tabell eller index partitioneras delas dess data in i enheter som kan spridas över mer än en filgrupp.

Därför, för att skapa en partitionerad tabell i SQL Server, måste du först skapa den eller de filgrupper som kommer att hålla varje partition. Du måste också skapa en partitionsfunktion och ett partitionsschema.

Så det går så här:

  1. Skapa filgrupper
  2. Skapa en partitionsfunktion
  3. Skapa ett partitionsschema
  4. Skapa den partitionerade tabellen

Nedan är ett exempel på hur du använder dessa steg för att skapa en tabell med fyra partitioner.

Skapa filgrupper

Först lägger vi till fyra filgrupper till databasen som heter Test , och ange sedan den fysiska filen för var och en av dessa 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 måste ändra den här koden, beroende på dina krav. Du måste också ändra filsökvägarna så att de passar din miljö. Om du till exempel använder Windows kan din sökväg se ut mer som D:\mssql\data\MoviesFg4dat.ndf .

Om du behöver fler partitioner lägg till fler filgrupper här. Omvänt, om du behöver färre partitioner, specificera färre filgrupper här.

Skapa en partitionsfunktion

Därefter skapar vi en partitionsfunktion som heter MoviesPartitionFunction som kommer att dela upp tabellen i fyra partitioner.

CREATE PARTITION FUNCTION MoviesPartitionFunction (int)  
    AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO 

int part specificerar datatypen för kolumnen som används för partitionering.

Alla datatyper är giltiga för användning som partitioneringskolumner, förutom text , ntext , bild , xml , tidsstämpel , varchar(max) , nvarchar(max) , varbinary(max) , alias datatyper eller CLR användardefinierade datatyper.

Här använder jag tre gränsvärden (1, 100 och 1000 ) för att ange fyra partitioner. Dessa gränsvärden måste antingen matcha eller vara implicit konverterbara till den datatyp som anges inom parentes efter partitionsfunktionens namn.

Med tanke på dessa gränsvärden och det faktum att jag angav en RANGE LEFT partition, kommer de fyra partitionerna att hålla värden som specificeras i följande tabell.

Partition Värden
1 <= 1
2 1 OCH <= 100
3 100 OCH <=1000
4 1000

Om jag hade angett en RANGE RIGHT partition, skulle uppdelningen vara något annorlunda, som beskrivs i följande tabell.

Partition Värden
1 1
2 >= 1 OCH < 100
3 >= 100 OCH < 1000
4 >= 1000

Samma koncept gäller om partitioneringskolumnen använder andra datatyper, såsom datum-/tidsvärden.

Skapa ett partitionsschema

Därefter måste vi skapa ett partitionsschema.

Ett partitionsschema mappar partitionerna i en partitionerad tabell eller index till de nya filgrupperna.

I vårt fall kommer koden att se ut så här:

CREATE PARTITION SCHEME MoviesPartitionScheme  
    AS PARTITION MoviesPartitionFunction  
    TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);  
GO 

Observera att vi refererar till partitionsfunktionen som vi skapade i föregående steg. Vi refererar också till filgrupperna som vi skapade i det första steget.

Skapa den partitionerade tabellen

Äntligen kan vi skapa den partitionerade tabellen.

CREATE TABLE Movies (
    MovieId int IDENTITY PRIMARY KEY, 
    MovieName varchar(60)
    )  
    ON MoviesPartitionScheme (MovieId);  
GO 

Den enda skillnaden mellan detta och att skapa en opartitionerad tabell är att när vi skapar en partitionerad tabell använder vi ON argument för att specificera ett partitionsschema att använda. I vårt fall anger vi partitionsschemat som vi skapade i föregående steg och anger MovieId kolumn som partitioneringskolumn.

Du kommer att märka att MovieId kolumnen har datatypen int , som matchar gränsvärdena som vi angav när vi skapade partitionsfunktionen.

Observera att om du använder en beräknad kolumn i en partitionsfunktion, måste den uttryckligen markeras med PERSISTED .

Kontrollera partitionsfunktionen

Du kan använda sys.partition_functions visa för att returnera alla partitionsfunktioner.

SELECT * FROM sys.partition_functions; 

Resultat (med vertikal utdata):

namn | MoviesPartitionFunctionfunction_id | 65536typ | R typ_desc | RANGEfanout | 4gränsvärde_till_höger | 0is_system | 0skapa_datum | 2020-10-10 05:37:41.330modify_date | 2020-10-10 05:37:41.330

Kontrollera partitionsschemat

Du kan använda sys.partition_schemes för att kontrollera partitionsschemat.

SELECT * FROM sys.partition_schemes; 

Resultat (med vertikal utdata):

namn | MoviesPartitionSchemedata_space_id | 65601typ | PStype_desc | PARTITION_SCHEMEis_default | 0is_system | 0funktions-id | 65536

Alternativt kan du använda följande fråga för att returnera andra detaljer, såsom schemat, tabellen, indexet 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 (med vertikal utdata):

Schema | dboObject | MoviesIndex | PK__Movies__4BD2941A0ED85ACAPartitionsschema | MoviesPartitionScheme

Kontrollera den partitionerade tabellen

Du kan köra sys.dm_db_partition_stats visa för att returnera sid- och radräkningsinformation för varje partition i den aktuella databasen.

Men att köra det innan du infogar någon data i tabellen kommer att resultera i att den mesta statistiken blir noll.

Så jag ska infoga data först.

INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies; 

Resultat:

(4079 rader påverkade)

Vi kan se att 4 079 rader infogades.

Låt oss nu fråga sys.dm_db_partition_stats visa.

SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies'); 

Resultat:

+--------------------+-------------+---------------- +--------------------+--------------------------------+- --------------------------+------------------------ ------+--------------------------+-------------------- --------+--------------------------------+-------- ----------------------------+--------------------------+- ----------------------+-------------+| partitions_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 | använd_sida_antal | reserved_page_count | rad_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 |+--------------------+-------------+------------+ --------------------+----------------------------------+-- ------------------------+------------------------- -----+------------------------------+--------------------- -------+--------------------------------+--------- --------------------------+-------------------+-- --------------------+-------------+

Den här vyn returnerar många kolumner, så låt oss begränsa kolumnerna till bara ett par.

SELECT 
    partition_number,
    row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies'); 

Resultat:

+---------------------+-------------+| partitionsnummer | rad_antal ||------------------------+--------|| 1 | 1 || 2 | 99 || 3 | 900 || 4 | 3079 |+---------------------+-------------+

Vi kan se hur raderna är fördelade över partitionerna. De tilldelas exakt som vi specificerade i partitionsfunktionen. Raderna totalt 4 079, vilket är exakt hur många rader vi infogade.

Det är dock värt att notera att Microsofts dokumentation faktiskt anger att den här kolumnen bara är en ungefärlig antal rader i varje partition.

Bästa tillvägagångssätt

Microsoft rekommenderar att vi alltid håller tomma partitioner i båda ändarna av partitionsintervallet.

Detta är i fall du behöver antingen dela eller slå samman partitionerna i framtiden.

Anledningen till denna rekommendation är att garantera att partitionsuppdelningen och partitionssammanslagningen inte medför några oväntade dataförflyttningar.

Därför, med tanke på data i mitt exempel, skulle jag kunna ändra partitionsfunktionen så att den ser ut ungefär så här:

CREATE PARTITION FUNCTION MoviesPartitionFunction (int)  
    AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO 

Eller om jag räknar med fler än 10 000 rader kan jag använda ett större antal (eller skapa fler partitioner).

Om jag skulle återskapa alla steg igen, för att skapa min partitionerade tabell, skulle min partitionsstatistik se ut så här:

SELECT 
    partition_number,
    row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies'); 

Resultat:

+---------------------+-------------+| partitionsnummer | rad_antal ||------------------------+--------|| 1 | 0 || 2 | 100 || 3 | 3979 || 4 | 0 |+--------------------+-------------+

Nu är min data koncentrerad till de två mittersta partitionerna, och partitionerna i båda ändarna är tomma.


  1. T-SQL Hur skapar man tabeller dynamiskt i lagrade procedurer?

  2. Hur får man skript av SQL Server-data?

  3. Hur NTILE() fungerar i SQL Server

  4. Android SQLite-uppdateringsraden fungerar inte