Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Създайте разделена таблица в SQL Server (T-SQL)

SQL Server поддържа разделени таблици и индекси. Когато една разделена таблица или индекс е разделена, нейните данни се разделят на единици, които могат да бъдат разпределени в повече от една файлова група.

Следователно, за да създадете разделена таблица в SQL Server, първо трябва да създадете файловата група/и, които ще съдържат всеки дял. Също така трябва да създадете функция за дялове и схема на дялове.

Така че става така:

  1. Създайте файлова група/и
  2. Създайте функция за разделяне
  3. Създайте схема на дялове
  4. Създайте разделената таблица

По-долу е даден пример за използване на тези стъпки за създаване на таблица с четири дяла.

Създаване на файлови групи

Първо добавяме четири файлови групи към базата данни, наречена Тест и след това посочете физическия файл за всяка от тези файлови групи.

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   

Ще трябва да промените този код в зависимост от вашите изисквания. Ще трябва също да промените пътеките на файловете, за да отговарят на вашата среда. Например, ако сте на Windows, пътят ви може да изглежда по-скоро като D:\mssql\data\MoviesFg4dat.ndf .

Освен това, ако имате нужда от повече дялове, добавете още файлови групи тук. Обратно, ако имате нужда от по-малко дялове, посочете тук по-малко файлови групи.

Създаване на функция за дял

След това създаваме функция за дял, наречена MoviesPartitionFunction което ще раздели таблицата на четири дяла.

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

Винт part определя типа данни на колоната, използвана за разделяне.

Всички типове данни са валидни за използване като колони за разделяне, с изключение на текст , ntext ,изображение , xml , клеймо за време , varchar(max) , nvarchar(max) ,варбинарна(макс.) , псевдоними типове данни или CLR потребителски дефинирани типове данни.

Тук използвам три гранични стойности (1, 100 и 1000 ), за да посочите четири дяла. Тези гранични стойности трябва или да съвпадат, или да бъдат имплицитно конвертируеми в типа данни, посочен в скоби след името на функцията за дял.

Предвид тези гранични стойности и факта, че посочих RANGE LEFT дял, четирите дяла ще задържат стойности, както е посочено в следващата таблица.

Дял Стойности
1 <= 1
2 1 И <= 100
3 100 И <=1000
4 1000

Ако бях посочил RANGE RIGHT дял, разбивката ще бъде малко по-различна, както е посочено в следващата таблица.

Дял Стойности
1 1
2 >= 1 И < 100
3 >= 100 И < 1000
4 >= 1000

Същата концепция се прилага, ако колоната за разделяне използва други типове данни, като стойности за дата/час.

Създайте схема на дялове

След това трябва да създадем схема на дялове.

Схемата на дяловете съпоставя дяловете на разделена таблица или индекс към новите файлови групи.

В нашия случай кодът ще изглежда така:

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

Забележете, че се позоваваме на функцията за дял, която създадохме в предишната стъпка. Също така препращаме към файловите групи, които създадохме в първата стъпка.

Създайте разделената таблица

Накрая можем да създадем разделената таблица.

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

Единствената разлика между това и създаването на неразделена таблица е, че когато създаваме разделена таблица, ние използваме ON аргумент за определяне на схема на дялове, която да се използва. В нашия случай указваме схемата на дялове, която създадохме в предишната стъпка, и задаваме MovieId колона като разделителна колона.

Ще забележите, че MovieId колоната има тип данни int , което съответства на граничните стойности, които сме посочили при създаването на функцията за дял.

Обърнете внимание, че ако използвате изчислена колона във функция на дял, тя трябва да бъде изрично маркирана PERSISTED .

Проверете функцията за разделяне

Можете да използвате sys.partition_functions преглед, за да върнете всички функции на дялове.

SELECT * FROM sys.partition_functions; 

Резултат (с помощта на вертикален изход):

<предварително име | MoviesPartitionFunctionfunction_id | 65536 тип | R type_desc | RANGEfanout | 4boundary_value_on_right | 0is_system | 0create_date | 2020-10-10 05:37:41.330modify_date | 2020-10-10 05:37:41,330

Проверете схемата на дяловете

Можете да използвате sys.partition_schemes за да проверите схемата на дяловете.

SELECT * FROM sys.partition_schemes; 

Резултат (с помощта на вертикален изход):

<предварително име | MoviesPartitionSchemedata_space_id | 65601 тип | PStype_desc | PARTITION_SCHEME е_по подразбиране | 0is_system | 0function_id | 65536

Като алтернатива можете да използвате следната заявка, за да върнете други подробности, като схема, таблица, индекс и др.

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; 

Резултат (с помощта на вертикален изход):

<предварителна>Схема | dboObject | Индекс на филми | PK__Movies__4BD2941A0ED85ACA Схема на дялове | Схема за разделяне на филми

Проверете разделената таблица

Можете да стартирате sys.dm_db_partition_stats преглед за връщане на информация за страница и брой редове за всеки дял в текущата база данни.

Но изпълнението на това преди вмъкване на каквито и да е данни в таблицата ще доведе до това, че повечето статистически данни са нулеви.

Така че първо ще вмъкна данни.

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

Резултат:

(засегнати 4079 реда)

Виждаме, че бяха вмъкнати 4079 реда.

Сега нека да запитаме sys.dm_db_partition_stats изглед.

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

Резултат:

+------------------+------------+------------ +-------------------+---------------------+- -------------------------+----------------------- ------+-----------------------+------------------- --------+--------------------------------+-------- ----------------------------+-------------------+- ---------------------+------------+| partition_id | обект_идентификатор | идентификатор_индекс | номер_на дял | 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 | използвани_брой_страници | запазени_брой_страници | брой_редове ||-------------------+------------+------------+ --------------------+--------------------------+-- ------------------------+-------------------------------- -----+-----------------------+-------------------- -------+--------------------------------+-------- ---------------------------+-------------------+-- ---------------------+------------|| 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 |+-------------------+------------+-----------+ --------------------+--------------------------+-- ------------------------+-------------------------------- -----+-----------------------+-------------------- -------+--------------------------------+-------- ---------------------------+-------------------+-- ---------------------+------------+

Този изглед връща много колони, така че нека стесним колоните само до няколко.

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

Резултат:

+--------------------+------------+| номер_на дял | брой_редове ||-------------------+------------|| 1 | 1 || 2 | 99 || 3 | 900 || 4 | 3079 |+-------------------+------------+

Можем да видим как редовете са разпределени в дяловете. Те са разпределени точно както сме посочили във функцията за дял. Общо редовете са 4079, което е точно колко реда вмъкнахме.

Въпреки това си струва да се отбележи, че документацията на Microsoft всъщност посочва, че тази колона е само приблизителна броят на редовете във всеки дял.

Най-добра практика

Microsoft препоръчва винаги да съхраняваме празни дялове в двата края на диапазона от дялове.

Това е в случай, че трябва или да разделите, или да обедините дяловете в бъдеще.

Причината за тази препоръка е да се гарантира, че разделянето на дяла и сливането на дяла няма да предизвикат неочаквано движение на данни.

Следователно, като се имат предвид данните в моя пример, бих могъл да променя функцията за дялове, за да изглежда така:

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

Или ако очаквам повече от 10 000 реда, бих могъл да използвам по-голям брой (или да създам повече дялове).

Ако трябваше да пресъздам всички стъпки отново, за да създам моята разделена таблица, статистиката на моя дял ще изглежда така:

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

Резултат:

+--------------------+------------+| номер_ на дял | брой_редове ||-------------------+------------|| 1 | 0 || 2 | 100 || 3 | 3979 || 4 | 0 |+-------------------+------------+

Сега данните ми са концентрирани в средните два дяла, а дяловете в двата края са празни.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изграждане на модел за машинно обучение със SQL Server, ML.NET и C#

  2. Синтаксис на for-loop в SQL Server

  3. Как да стартирате SQL Server 2017 и 2019 едновременно на Mac

  4. Как работи функцията STR() в SQL Server (T-SQL)

  5. Динамична въртяща се таблица в SQL Server