sql >> Databáze >  >> RDS >> Sqlserver

Vytvoření dělené tabulky v SQL Server (T-SQL)

SQL Server podporuje dělené tabulky a indexy. Když je rozdělená tabulka nebo index rozdělena na oddíly, její data jsou rozdělena do jednotek, které lze rozložit do více než jedné skupiny souborů.

Chcete-li tedy vytvořit dělenou tabulku na serveru SQL Server, musíte nejprve vytvořit skupinu souborů, která bude obsahovat každý oddíl. Musíte také vytvořit funkci oddílu a schéma oddílů.

Takže to vypadá takto:

  1. Vytvořit skupinu/skupiny souborů
  2. Vytvořte funkci oddílu
  3. Vytvořte schéma oddílů
  4. Vytvořte rozdělenou tabulku

Níže je uveden příklad použití těchto kroků k vytvoření tabulky se čtyřmi oddíly.

Vytvořit skupiny souborů

Nejprve přidáme čtyři skupiny souborů do databáze s názvem Test a poté zadejte fyzický soubor pro každou z těchto skupin souborů.

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  

Tento kód budete muset změnit v závislosti na vašich požadavcích. Budete také muset změnit cesty k souborům, aby vyhovovaly vašemu prostředí. Pokud například používáte Windows, vaše cesta může vypadat spíše jako D:\mssql\data\MoviesFg4dat.ndf .

Pokud potřebujete více oddílů, přidejte sem další skupiny souborů. Naopak, pokud potřebujete méně oddílů, zadejte zde méně skupin souborů.

Vytvořte funkci oddílu

Dále vytvoříme funkci oddílu s názvem MoviesPartitionFunction který rozdělí tabulku na čtyři oddíly.

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

int část určuje datový typ sloupce použitého pro rozdělení.

Všechny datové typy jsou platné pro použití jako rozdělovací sloupce, kromě textu , ntext , obrázek , xml , časové razítko , varchar(max) , nvarchar(max) , varbinary(max) , alias datové typy nebo CLR uživatelem definované datové typy.

Zde používám tři hraniční hodnoty (1, 100 a 1000 ) k určení čtyř oddílů. Tyto hraniční hodnoty se musí buď shodovat, nebo být implicitně převoditelné na datový typ uvedený v závorkách za názvem funkce oddílu.

Vzhledem k těmto hraničním hodnotám a skutečnosti, že jsem zadal RANGE LEFT oddíl, čtyři oddíly budou obsahovat hodnoty uvedené v následující tabulce.

Oddíl Hodnoty
1 <= 1
2 1 AND <= 100
3  100 AND <=1000
4  1000

Kdybych zadal RANGE RIGHT oddíl, bude rozdělení mírně odlišné, jak je uvedeno v následující tabulce.

Oddíl Hodnoty
1 1
2 >= 1 AND < 100
3 >= 100 AND < 1000
4 >= 1000

Stejný koncept platí, pokud rozdělovací sloupec používá jiné datové typy, jako jsou hodnoty data/času.

Vytvořte schéma rozdělení

Dále musíme vytvořit schéma oddílů.

Schéma oddílů mapuje oddíly rozdělené tabulky nebo indexu na nové skupiny souborů.

V našem případě bude kód vypadat takto:

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

Všimněte si, že odkazujeme na funkci oddílu, kterou jsme vytvořili v předchozím kroku. Odkazujeme také na skupiny souborů, které jsme vytvořili v prvním kroku.

Vytvořte dělenou tabulku

Nakonec můžeme vytvořit rozdělenou tabulku.

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

Jediný rozdíl mezi tímto a vytvořením nedělené tabulky je ten, že při vytváření dělené tabulky použijeme ON argument k určení schématu rozdělení, které se má použít. V našem případě zadáme schéma oddílů, které jsme vytvořili v předchozím kroku, a zadáme MovieId jako dělicí sloupec.

Všimnete si, že MovieId sloupec má datový typ int , která odpovídá hraničním hodnotám, které jsme zadali při vytváření funkce oddílu.

Všimněte si, že pokud použijete vypočítaný sloupec ve funkci oddílu, musí být výslovně označen PERSISTED .

Zkontrolujte funkci rozdělení

Můžete použít sys.partition_functions view pro návrat všech funkcí oddílu.

SELECT * FROM sys.partition_functions;

Výsledek (při použití vertikálního výstupu):

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

Zkontrolujte schéma rozdělení

Můžete použít sys.partition_schemes zkontrolovat schéma oddílů.

SELECT * FROM sys.partition_schemes;

Výsledek (při použití vertikálního výstupu):

name          | MoviesPartitionScheme
data_space_id | 65601
type          | PS
type_desc     | PARTITION_SCHEME
is_default    | 0
is_system     | 0
function_id   | 65536

Případně můžete pomocí následujícího dotazu vrátit další podrobnosti, jako je schéma, tabulka, index atd.

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;

Výsledek (při použití vertikálního výstupu):

Schema           | dbo
Object           | Movies
Index            | PK__Movies__4BD2941A0ED85ACA
Partition Scheme | MoviesPartitionScheme

Zkontrolujte rozdělenou tabulku

Můžete spustit sys.dm_db_partition_stats view pro návrat informací o stránkách a počtu řádků pro každý oddíl v aktuální databázi.

Ale když to spustíte před vložením jakýchkoli dat do tabulky, bude většina statistik nulová.

Nejprve tedy vložím data.

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

Výsledek:

(4079 rows affected)

Vidíme, že bylo vloženo 4 079 řádků.

Nyní se zeptáme na sys.dm_db_partition_stats zobrazit.

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

Výsledek:

+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+
| 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        |
+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+

Toto zobrazení vrací mnoho sloupců, takže zužme sloupce pouze na pár.

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

Výsledek:

+--------------------+-------------+
| partition_number   | row_count   |
|--------------------+-------------|
| 1                  | 1           |
| 2                  | 99          |
| 3                  | 900         |
| 4                  | 3079        |
+--------------------+-------------+

Můžeme vidět, jak jsou řádky alokovány mezi oddíly. Jsou alokovány přesně tak, jak jsme zadali ve funkci oddílu. Celkový počet řádků je 4 079, což je přesně počet řádků, které jsme vložili.

Je však třeba poznamenat, že dokumentace společnosti Microsoft ve skutečnosti uvádí, že tento sloupec je pouze přibližný počet řádků v každém oddílu.

Doporučený postup

Společnost Microsoft doporučuje, abychom vždy ponechali prázdné oddíly na obou koncích rozsahu oddílů.

To pro případ, že budete v budoucnu muset oddíly buď rozdělit nebo sloučit.

Důvodem tohoto doporučení je zaručit, že rozdělení oddílu a sloučení oddílu nezpůsobí žádný neočekávaný přesun dat.

Proto s ohledem na data v mém příkladu bych mohl změnit funkci oddílu tak, aby vypadala nějak takto:

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

Nebo pokud předpokládám více než 10 000 řádků, mohl bych použít větší počet (nebo vytvořit více oddílů).

Pokud bych znovu vytvořil všechny kroky a vytvořil svou rozdělenou tabulku, moje statistiky oddílu by vypadaly takto:

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

Výsledek:

+--------------------+-------------+
| partition_number   | row_count   |
|--------------------+-------------|
| 1                  | 0           |
| 2                  | 100         |
| 3                  | 3979        |
| 4                  | 0           |
+--------------------+-------------+

Nyní jsou moje data soustředěna do prostředních dvou oddílů a oddíly na obou koncích jsou prázdné.


  1. Tabulky a indexy vs. HDD a SSD

  2. 3 způsoby, jak vypsat všechny uložené procedury v databázi PostgreSQL

  3. Správa dat pomocí Pythonu, SQLite a SQLAlchemy

  4. MariaDB Server 10.0.33 je nyní k dispozici