Bài viết tham khảo tại:http://www.sqlviet.com/blog/table-partitioning-cac-khai-niem-co-ban
Table Partitioning – Các Khái Niệm Cơ Bản
Vũ Huy Tâm
Bài Table Partitioning Trong SQL Server giới thiệu về kỹ thuật phân đoạn của SQL Server và cũng giới thiệu qua các khái niệm xung quanh kỹ thuật này, như partition function, partition schema, filegroup. Bài viết này đề cập chi tiết hơn các khái niệm trên để giúp bạn hiểu thêm về kiến trúc partitioning của SQL Server.
Partition Function
Bước đầu tiên bạn cần làm khi thực hiện phân đoạn là tạo partition function để định nghĩa giá trị biên của các đoạn. Partition function không giống với các hàm UDF thông thường (bạn không thể gọi trực tiếp), mà chỉ dùng vào mục đích phân đoạn. Nó đưa ra định nghĩa về mặt logic, rằng mỗi đoạn chứa dải giá trị từ đâu đến đâu chứ không qui định các đoạn được lưu trữ như thế nào, cũng như tên trường dùng để phân đoạn là gì.
Ví dụ 1: phân đoạn dựa vào dãy số
Bước đầu tiên bạn cần làm khi thực hiện phân đoạn là tạo partition function để định nghĩa giá trị biên của các đoạn. Partition function không giống với các hàm UDF thông thường (bạn không thể gọi trực tiếp), mà chỉ dùng vào mục đích phân đoạn. Nó đưa ra định nghĩa về mặt logic, rằng mỗi đoạn chứa dải giá trị từ đâu đến đâu chứ không qui định các đoạn được lưu trữ như thế nào, cũng như tên trường dùng để phân đoạn là gì.
Ví dụ 1: phân đoạn dựa vào dãy số
| Partition | Partition 1 | Partition 2 | Partition 3 | Partition 4 | |
| Dải giá trị | giá trị <= 1000 | 1000< giá trị <= 2000 | 2000 < giá trị <= 3000 | 3000 < giá trị |
Ví dụ 2: phân đoạn theo năm
| Partition | Partition 1 | Partition 2 | Partition 3 | |
| Dải giá trị | giá trị < 01/01/2010 | 01/01/2010<= giá trị < 01/01/2011 | 01/01/2011 <= giá trị |
Bạn có thể thấy ở ví dụ 1 chỉ có ba giá trị liệt kê trong hàm để tạo ra bốn đoạn. Tương tự ở ví dụ 2, chỉ có hai giá trị được dùng để tạo ra ba đoạn. Việc phân đoạn bảng giống như khi bạn cắt một sợi dây, trong đó partition function định nghĩa vị trí cho các nhát cắt, và để cắt sợi dây làm n đoạn bạn chỉ cần n-1 nhát cắt.
Trong hai ví dụ trên bạn có để ý đến từ khóa “LEFT” ở hàm MyPartFunc_1 và “RIGHT” ở hàm MyPartFunc_2? Mỗi partition function phải thuộc một trong hai kiểu, LEFT hoặc RIGHT. Như ở ví dụ trên, hàm MyPartFunc_1 có kiểu LEFT và hàm MyPartFunc_2 có kiểu RIGHT. Hai kiểu hàm này liên quan đến việc qui định giá trị biên thuộc về đoạn nào, đoạn bên trái hay bên phải. Với hàm kiểu LEFT, giá trị biên thuộc về đoạn phía trước nó (bên trái), như với hàm MyPartFunc_1 các giá trị biên 1000, 2000, và 3000 luôn thuộc về đoạn phía bên trái của chúng. Ngược lại với hàm kiểu RIGHT, các giá trị biên luôn thuộc về đoạn tiếp theo, tức là phía bên phải (hãy quan sát dải giá trị của các đoạn trong hàm MyPartFunc_2).
Việc phân chia làm hai loại hàm như vậy giúp bạn định nghĩa dải giá trị cho đúng với yêu cầu. Khi dải giá trị là các số rời rạc (discrete) như kiểu INT thì bạn chỉ cần một kiểu hàm và có thể chuyển đổi qua lại dễ dàng bằng cách tăng/giảm giá trị biên đi 1, do đó kiểu hàm không quá quan trọng. Như với ví dụ 1 ở trên, tôi có thể viết lại thành hàm kiểu RIGHT như sau:
Trong hai ví dụ trên bạn có để ý đến từ khóa “LEFT” ở hàm MyPartFunc_1 và “RIGHT” ở hàm MyPartFunc_2? Mỗi partition function phải thuộc một trong hai kiểu, LEFT hoặc RIGHT. Như ở ví dụ trên, hàm MyPartFunc_1 có kiểu LEFT và hàm MyPartFunc_2 có kiểu RIGHT. Hai kiểu hàm này liên quan đến việc qui định giá trị biên thuộc về đoạn nào, đoạn bên trái hay bên phải. Với hàm kiểu LEFT, giá trị biên thuộc về đoạn phía trước nó (bên trái), như với hàm MyPartFunc_1 các giá trị biên 1000, 2000, và 3000 luôn thuộc về đoạn phía bên trái của chúng. Ngược lại với hàm kiểu RIGHT, các giá trị biên luôn thuộc về đoạn tiếp theo, tức là phía bên phải (hãy quan sát dải giá trị của các đoạn trong hàm MyPartFunc_2).
Việc phân chia làm hai loại hàm như vậy giúp bạn định nghĩa dải giá trị cho đúng với yêu cầu. Khi dải giá trị là các số rời rạc (discrete) như kiểu INT thì bạn chỉ cần một kiểu hàm và có thể chuyển đổi qua lại dễ dàng bằng cách tăng/giảm giá trị biên đi 1, do đó kiểu hàm không quá quan trọng. Như với ví dụ 1 ở trên, tôi có thể viết lại thành hàm kiểu RIGHT như sau:
Tuy nhiên với kiểu dữ liệu có dải giá trị liền nhau, như DATETIME hay FLOAT, vấn đề trở nên phức tạp hơn và bạn cần chọn kiểu hàm cho đúng. Như ví dụ 2 ở trên, yêu cầu đặt ra là các giá trị thuộc về năm 2009 trở về trước vào một đoạn, và thời khắc đầu tiên của năm 2010 đã thuộc về đoạn sau, do đó dùng hàm RIGHT là thích hợp. Nếu dùng hàm LEFT bạn cần chuyển qua đại để thế này:
trong đó ’2009-12-31 23:59:59.999′ và ’2010-12-31 23:59:59.999′ tương ứng là thời điểm cuối cùng của năm 2009 và 2010 theo độ phân giải thời gian của hệ thống (các giá trị trên đây chỉ là ví dụ, tôi không rõ SQL Server chính xác đến bao nhiêu phần giây).
Partition Scheme
Sau khi định nghĩa dải giá trị cho các đoạn, việc tiếp theo là tạo partition scheme để định nghĩa không gian lưu trữ cho chúng. Partition scheme ánh xạ từng đoạn đã được định nghĩa trong partition function vào các filegroup (Các filegroup này cần được tạo trước khi tạo partition scheme):
Sau khi định nghĩa dải giá trị cho các đoạn, việc tiếp theo là tạo partition scheme để định nghĩa không gian lưu trữ cho chúng. Partition scheme ánh xạ từng đoạn đã được định nghĩa trong partition function vào các filegroup (Các filegroup này cần được tạo trước khi tạo partition scheme):
| Partition | Partition 1 | Partition 2 | Partition 3 | Partition 4 | |
| Dải giá trị | giá trị <= 1000 | 1000< giá trị <= 2000 | 2000 < giá trị <= 3000 | 3000 < giá trị | |
| Filegroup | FG1 | FG2 | FG3 | FG4 |
Về nguyên tắc bạn có thể gán tất cả các đoạn vào một filegroup, nhưng làm như vậy là vô hiệu hóa nhiều lợi điểm của việc phân đoạn. Trên thực tế bạn nên giành riêng mỗi filegroup cho một đoạn.
Filegroup
Filegroup được đưa vào SQL Server đã lâu, từ trước khi có partitioning. Khái niệm filegroup tương tự như folder trong windows, chỉ là một tên logic để nhóm các data file chứ không bản thân nó chứa dữ liệu. Filegroup chứa một hoặc nhiều data file và các data file này mới thực chứa dữ liệu. Khi mới tạo database, một filegroup có tên PRIMARY tự động được tạo và chứa data file chính (.mdf). Tuy nhiên bạn không nên dùng PRIMARY filegroup vào việc phân đoạn mà nên tạo filegroup mới.
Filegroup được đưa vào SQL Server đã lâu, từ trước khi có partitioning. Khái niệm filegroup tương tự như folder trong windows, chỉ là một tên logic để nhóm các data file chứ không bản thân nó chứa dữ liệu. Filegroup chứa một hoặc nhiều data file và các data file này mới thực chứa dữ liệu. Khi mới tạo database, một filegroup có tên PRIMARY tự động được tạo và chứa data file chính (.mdf). Tuy nhiên bạn không nên dùng PRIMARY filegroup vào việc phân đoạn mà nên tạo filegroup mới.
Phân đoạn bảng
Sau khi các bước trên hoàn tất, giờ bạn có thể tạo bảng và đồng thời phân đoạn nó:
Sau khi các bước trên hoàn tất, giờ bạn có thể tạo bảng và đồng thời phân đoạn nó:
Trong ví dụ trên, việc phân đoạn được gói gọn ở mệnh đề “ON MyPartScheme_1(MyID)”, và bảng được phân đoạn thông qua partition scheme MyPartScheme_1 dựa vào trường MyID. Khi đó trường MyID được gọi là partition key. Nếu bạn đã quen với việc dùng mệnh đề “ON some_filegroup_name” khi tạo bảng để chỉ định filegroup cho nó, bạn sẽ thấy việc phân đoạn chỉ đơn giản là thay tên filegroup bằng một partition scheme. Nói cách khác là thay vì chỉ định lưu dữ liệu vào một filegroup cụ thể, thì nay vào một partition scheme, và thông qua đó dữ liệu được phân đoạn.
Một vài lưu ý
- Ở đây bạn có thể thấy một sự phân cấp rất rõ ràng:
Trong một database bạn có thể tạo nhiều partition function.
Mỗi partition function có thể được dùng cho nhiều partition scheme
Đến lượt mỗi partition scheme lại được dùng cho nhiều bảng.
- Ở đây bạn có thể thấy một sự phân cấp rất rõ ràng:
Trong một database bạn có thể tạo nhiều partition function.
Mỗi partition function có thể được dùng cho nhiều partition scheme
Đến lượt mỗi partition scheme lại được dùng cho nhiều bảng.
- Một bạn hỏi qua email muốn phân đoạn dựa vào mã tỉnh thành, ví dụ Hà nội (HN) vào một đoạn, Sài gòn (SG) vào một đoạn, và các tỉnh thành khác vào một đoạn. Bạn không thể áp dụng trực tiếp partition function lên các giá trị này vì chúng không tạo ra một dải tăng tuần tự. Ví dụ Bình dương (BD) đứng trước Hà nội, còn Quảng ninh (QN) đứng sau Hà nội do đó không thể nằm chung trong một đoạn. Trong trường hợp này bạn cần tạo một ID cho mỗi tỉnh thành ở dạng số (ví dụ HN=1, SG=2, else=3,4,5…) và phân đoạn trên ID này.
- Việc phân đoạn chỉ có thể được thực hiện trên một dải giá trị duy nhất. Có những trường hợp bạn muốn phân đoạn dựa vào 2 hoặc nhiều trường, ví dụ phân đoạn hóa đơn bán hàng theo năm và trong mỗi năm tiếp tục phân chia các đơn hàng có trị giá hơn 1 triệu vào một đoạn và nhỏ hơn 1 triệu vào một đoạn. Khi đó bạn cần tạo một computed field đại diện cho hai trường kia và phân đoạn dựa vào computed field này.
- Việc phân đoạn chỉ có thể được thực hiện trên một dải giá trị duy nhất. Có những trường hợp bạn muốn phân đoạn dựa vào 2 hoặc nhiều trường, ví dụ phân đoạn hóa đơn bán hàng theo năm và trong mỗi năm tiếp tục phân chia các đơn hàng có trị giá hơn 1 triệu vào một đoạn và nhỏ hơn 1 triệu vào một đoạn. Khi đó bạn cần tạo một computed field đại diện cho hai trường kia và phân đoạn dựa vào computed field này.
Phiên bản áp dụng: SQL Server 2005 trở lên
No comments:
Post a Comment