SQL Server hỗ trợ các bảng và chỉ mục được phân vùng. Khi một bảng hoặc chỉ mục được phân vùng được phân vùng, dữ liệu của nó được chia thành các đơn vị có thể được trải rộng trên nhiều nhóm tệp.
Do đó, để tạo một bảng được phân vùng trong SQL Server, trước tiên bạn cần tạo / nhóm tệp sẽ chứa mỗi phân vùng. Bạn cũng cần tạo một hàm phân vùng và một lược đồ phân vùng.
Vì vậy, nó diễn ra như thế này:
- Tạo / s nhóm tệp
- Tạo một chức năng phân vùng
- Tạo một lược đồ phân vùng
- Tạo bảng được phân vùng
Dưới đây là ví dụ về cách sử dụng các bước này để tạo bảng có bốn phân vùng.
Tạo nhóm tệp
Đầu tiên, chúng tôi thêm bốn nhóm tệp vào cơ sở dữ liệu có tên Kiểm tra , và sau đó chỉ định tệp vật lý cho từng nhóm tệp đó.
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
Bạn sẽ cần thay đổi mã này, tùy thuộc vào yêu cầu của bạn. Bạn cũng sẽ cần thay đổi đường dẫn tệp cho phù hợp với môi trường của mình. Ví dụ:nếu bạn đang sử dụng Windows, đường dẫn của bạn có thể giống D:\mssql\data\MoviesFg4dat.ndf
.
Ngoài ra, nếu bạn cần nhiều phân vùng, hãy thêm nhiều nhóm tệp tại đây. Ngược lại, nếu bạn cần ít phân vùng hơn, hãy chỉ định ít nhóm tệp hơn tại đây.
Tạo hàm phân vùng
Tiếp theo, chúng tôi tạo một chức năng phân vùng có tên là MoviesPartitionFunction điều đó sẽ phân chia bảng thành bốn phân vùng.
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO
int phần chỉ định kiểu dữ liệu của cột được sử dụng để phân vùng.
Tất cả các loại dữ liệu đều hợp lệ để sử dụng làm cột phân vùng, ngoại trừ văn bản , ntext , hình ảnh , xml , dấu thời gian , varchar (tối đa) , nvarchar (tối đa) , varbinary (max) , kiểu dữ liệu bí danh hoặc kiểu dữ liệu CLR do người dùng xác định.
Ở đây, tôi sử dụng ba giá trị ranh giới (1, 100
và 1000
) để chỉ định bốn phân vùng. Các giá trị ranh giới này phải khớp hoặc có thể chuyển đổi hoàn toàn thành kiểu dữ liệu được chỉ định trong dấu ngoặc đơn sau tên của hàm phân vùng.
Đưa ra các giá trị ranh giới này và thực tế là tôi đã chỉ định RANGE LEFT
phân vùng, bốn phân vùng sẽ giữ các giá trị như được chỉ định trong bảng sau.
Phân vùng | Giá trị |
---|---|
1 | <=1 |
2 | > 1 VÀ <=100 |
3 | > 100 VÀ <=1000 |
4 | > 1000 |
Nếu tôi đã chỉ định một RANGE RIGHT
phân vùng, sự phân tích sẽ hơi khác một chút, như được nêu trong bảng sau.
Phân vùng | Giá trị |
---|---|
1 | <1 |
2 | > =1 VÀ <100 |
3 | > =100 VÀ <1000 |
4 | > =1000 |
Khái niệm tương tự cũng áp dụng nếu cột phân vùng sử dụng các kiểu dữ liệu khác, chẳng hạn như giá trị ngày / giờ.
Tạo sơ đồ phân vùng
Tiếp theo, chúng ta cần tạo một lược đồ phân vùng.
Lược đồ phân vùng ánh xạ các phân vùng của bảng hoặc chỉ mục được phân vùng tới các nhóm tệp mới.
Trong trường hợp của chúng tôi, mã sẽ giống như sau:
CREATE PARTITION SCHEME MoviesPartitionScheme
AS PARTITION MoviesPartitionFunction
TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);
GO
Lưu ý rằng chúng ta tham chiếu đến hàm phân vùng mà chúng ta đã tạo ở bước trước. Chúng tôi cũng tham chiếu đến các nhóm tệp mà chúng tôi đã tạo ở bước đầu tiên.
Tạo bảng được phân vùng
Cuối cùng, chúng ta có thể tạo bảng được phân vùng.
CREATE TABLE Movies (
MovieId int IDENTITY PRIMARY KEY,
MovieName varchar(60)
)
ON MoviesPartitionScheme (MovieId);
GO
Sự khác biệt duy nhất giữa việc này và tạo một bảng không được phân vùng là khi tạo một bảng được phân vùng, chúng tôi sử dụng ON
đối số để chỉ định một lược đồ phân vùng để sử dụng. Trong trường hợp của chúng tôi, chúng tôi chỉ định lược đồ phân vùng mà chúng tôi đã tạo ở bước trước và chỉ định MovieId làm cột phân vùng.
Bạn sẽ nhận thấy rằng MovieId cột có kiểu dữ liệu là int , khớp với các giá trị ranh giới mà chúng tôi đã chỉ định khi tạo hàm phân vùng.
Lưu ý rằng nếu bạn sử dụng một cột được tính toán trong một hàm phân vùng, nó phải được đánh dấu rõ ràng PERSISTED
.
Kiểm tra chức năng phân vùng
Bạn có thể sử dụng sys.partition_functions
xem để trả về tất cả các chức năng của phân vùng.
SELECT * FROM sys.partition_functions;
Kết quả (sử dụng đầu ra dọc):
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
Kiểm tra sơ đồ phân vùng
Bạn có thể sử dụng sys.partition_schemes
để kiểm tra sơ đồ phân vùng.
SELECT * FROM sys.partition_schemes;
Kết quả (sử dụng đầu ra dọc):
name | MoviesPartitionScheme data_space_id | 65601 type | PS type_desc | PARTITION_SCHEME is_default | 0 is_system | 0 function_id | 65536
Ngoài ra, bạn có thể sử dụng truy vấn sau để trả về các chi tiết khác, chẳng hạn như lược đồ, bảng, chỉ mục, v.v.
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;
Kết quả (sử dụng đầu ra dọc):
Lược đồSchema | dbo Object | Movies Index | PK__Movies__4BD2941A0ED85ACA Partition Scheme | MoviesPartitionScheme
Kiểm tra Bảng được phân vùng
Bạn có thể chạy sys.dm_db_partition_stats
xem để trả về trang và thông tin về số hàng cho mọi phân vùng trong cơ sở dữ liệu hiện tại.
Nhưng chạy điều đó trước khi chèn bất kỳ dữ liệu nào vào bảng sẽ dẫn đến hầu hết các số liệu thống kê bằng không.
Vì vậy, trước tiên tôi sẽ chèn dữ liệu.
INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;
Kết quả:
(4079 rows affected)
Chúng tôi có thể thấy rằng 4.079 hàng đã được chèn.
Bây giờ, hãy truy vấn sys.dm_db_partition_stats
xem.
SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Kết quả:
+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+ | 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 | +-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+
Chế độ xem này trả về rất nhiều cột, vì vậy hãy thu hẹp các cột xuống chỉ còn một vài cột.
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Kết quả:
+--------------------+-------------+ | partition_number | row_count | |--------------------+-------------| | 1 | 1 | | 2 | 99 | | 3 | 900 | | 4 | 3079 | +--------------------+-------------+
Chúng ta có thể thấy các hàng được phân bổ như thế nào trên các phân vùng. Chúng được phân bổ chính xác như chúng tôi đã chỉ định trong hàm phân vùng. Tổng số hàng là 4.079, chính xác là số hàng chúng tôi đã chèn.
Tuy nhiên, điều đáng chú ý là tài liệu của Microsoft thực sự chỉ ra rằng cột này chỉ là gần đúng số hàng trong mỗi phân vùng.
Phương pháp hay nhất
Microsoft khuyến nghị rằng chúng ta luôn giữ các phân vùng trống ở cả hai đầu của phạm vi phân vùng.
Đây là trường hợp bạn cần chia hoặc hợp nhất các phân vùng trong tương lai.
Lý do cho đề xuất này là để đảm bảo rằng việc phân chia phân vùng và hợp nhất phân vùng không phát sinh bất kỳ chuyển động dữ liệu không mong muốn nào.
Do đó, với dữ liệu trong ví dụ của tôi, tôi có thể thay đổi chức năng phân vùng để trông giống như sau:
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO
Hoặc nếu tôi dự đoán hơn 10.000 hàng, tôi có thể sử dụng số lượng lớn hơn (hoặc tạo nhiều phân vùng hơn).
Nếu tôi tạo lại tất cả các bước một lần nữa, để tạo bảng được phân vùng của mình, thống kê phân vùng của tôi sẽ giống như sau:
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Kết quả:
+--------------------+-------------+ | partition_number | row_count | |--------------------+-------------| | 1 | 0 | | 2 | 100 | | 3 | 3979 | | 4 | 0 | +--------------------+-------------+
Bây giờ dữ liệu của tôi được tập trung vào hai phân vùng ở giữa và các phân vùng ở cả hai đầu đều trống.