Ý nghĩa partitioned table trong PostgreSQL

   Partitioned table là gì?

Table giống như một khối dữ liệu, dữ liệu càng lớn thì table càng lớn, và việc tìm kiếm 1 dữ liệu cụ thể càng khó. Do đó, các hệ quản trị CSDL như Oracle, PostgreSQL, SQL Server, … đều có 1 khái niệm giống nhau gọi là Partitioned Table để giải quyết vấn đề truy vấn trong 1 bảng rất lớn.

Hiểu 1 cách đơn giản, partition là kỹ thuật chia nhỏ bảng ra thành nhiều khối nhỏ theo 1 tiêu chí đã được chọn, để việc tìm kiếm được dễ dàng hơn.

Lấy 1 ví dụ: Giả sử bạn có 1 bảng tên là khach_hang, lưu trữ dữ liệu của toàn bộ khách hàng từ lúc triển khai hệ thống đến hiện tại. Khi bạn muốn lấy 1 dữ liệu khách hàng có thoi_gian_mua_hang là năm 2017 chẳng hạn, PostgreSQL cũng phải quét dữ liệu toàn bộ bảng để lấy ra dữ liệu bạn cần.

Nếu ta dùng kỹ thuật partition để chia nhỏ bảng ra theo tiêu chí thoi_gian_mua_hang, thì lúc đó, mỗi khối dữ liệu nhỏ là dữ liệu cho 1 năm (VD: 2015, 2016, 2017,…) hay còn gọi là partition. Khi đó, bạn muốn tìm dữ liệu nào đó thuộc năm 2017, chỉ có partition của năm 2017 được quét thôi, chứ không phải toàn bộ bảng.

Như vậy, thời gian xử lý và phản hồi sẽ tăng lên nhiều lần.


   Các kiểu partition trong PostgreSQL

Trong PostgreSQL cũng có nhiều kiểu partition. Điểm khác nhau giữa chúng là tiêu chí lựa chọn để phân chia partition. Phần tiếp theo tôi sẽ giới thiệu cho các bạn từng loại một

   List partition

Kiểu đầu tiên là List Partition. Đặc điểm của nó là tiêu chí để phân chia partition dựa trên giá trị cụ thể. VD: Bảng khach_hang có cột gioi_tinh, chỉ có 3 giá trị là Nam, Nữ, “Không xác định”. Nếu ta lựa chọn cột gioi_tinh là tiêu chí partition, thì ta sẽ có 3 partition tương ứng với 3 giá trị nêu trên.

Đọc thêm  Tính thời gian chạy của function trong PostgreSQL

Ví dụ: Tôi tạo ra một bảng partition như sau:

CREATE TABLE khach_hang(
    id              int4 not null,
    ho_ten          text not null,
    gioi_tinh       text,
    thoi_gian_mua_hang       date
) PARTITION BY LIST(gioi_tinh);

Câu lệnh này tạo ra bảng khach_hang với các thuộc tính thông thường. Tuy nhiên có 1 điểm đáng chú ý để phân biệt bảng partition với bảng thông thường, đó là mệnh đề PARTITION BY LIST (gioi_tinh). Mệnh đề này chỉ ra đây là bảng đã được partition theo kiểu LIST. Ở đây tôi cũng lựa chọn ra tiêu chí để phân chia partition đó là cột gioi_tinh.

Tiếp theo tôi cần tạo ra các partition dựa trên các giá trị của cột gioi_tinh. Tiến hành như sau:

CREATE TABLE NAM PARTITION of khach_hang FOR VALUES IN ('Nam');
CREATE TABLE NU PARTITION of khach_hang FOR VALUES IN ('Nu');
CREATE TABLE KHONG_XAC_DINH PARTITION of khach_hang FOR VALUES IN ('Khong xac dinh');

Câu lệnh trên tạo ra 3 partition của bảng khach_hang tương ứng với 3 giá trị Nam, Nu và Khong xac dinh.

Các bạn kiểm tra kết quả như sau:

   Range Partition

Đối với các cột không có giới hạn các giá trị như gioi_tinh, ví dụ như cột thoi_gian_mua_hang. Khách hàng có thể mua hàng vào bất cứ thời điểm nào. Nếu ta muốn lựa chọn cột này là cột partition, chúng ta có thể dùng kiểu Range Partition.

Theo kinh nghiệm của tôi, đây là kiểu thường gặp nhất. Trên các database mà tôi hiện đang quản lý cũng chủ yếu dùng kiểu này.

Tiêu chí để phân chia partition trong Range Partition là 1 dải các giá trị. Đây là 1 ví dụ:

CREATE TABLE khach_hang ( 
     id int4 not null,
     ho_ten text not null, 
     gioi_tinh text, 
     thoi_gian_mua_hang date ) PARTITION BY RANGE(thoi_gian_mua_hang);

Các bạn chú ý đến mệnh đề PARTITION BY RANGE đã thay thế cho PARTITION BY LIST ở ví dụ bên trên. Đó là mệnh đề chỉ ra bảng khach_hang sẽ được partition theo kiểu RANGE dựa trên cột thoi_gian_mua hang.

Tiêp theo tôi sẽ tạo ra các partition cho bảng này

CREATE TABLE nam_2016 PARTITION OF khach_hang FOR VALUES FROM ('2016-01-01') TO ('2016-12-31');
CREATE TABLE nam_2017 PARTITION OF khach_hang FOR VALUES FROM ('2017-01-01') TO ('2017-12-31');
CREATE TABLE nam_2018 PARTITION OF khach_hang FOR VALUES FROM ('2018-01-01') TO ('2018-12-31');
CREATE TABLE nam_2019 PARTITION OF khach_hang FOR VALUES FROM ('2019-01-01') TO ('2019-12-31');
CREATE TABLE nam_2020 PARTITION OF khach_hang FOR VALUES FROM ('2020-01-01') TO ('2020-12-31');
CREATE TABLE nam_2021 PARTITION OF khach_hang FOR VALUES FROM ('2021-01-01') TO ('2021-12-31');

Như các bạn thấy, tôi đã tạo ra các partition cho các năm từ 2016 đến 2021. Khi bạn insert 1 bản ghi vào bảng khach_hang, giá trị trong thoi_gian_mua_hang sẽ được kiểm tra, để xác định xem bản ghi đó sẽ được ghi vào partition nào.

Đọc thêm  Review công cụ quản trị PostgreSQL - DBeaver

Sau khi bạn đã tạo xong partition, bạn có thể kiểm tra lại như sau:

   Hash Partition

Loại cuối cùng mà tôi muốn nói đến trong bài viết này, đó là kiểu Hash Partition.

Các bản ghi dữ liệu trước khi được insert vào bảng, giá trị của cột được lựa chọn làm tiêu chí Hash Partition sẽ được băm (hash) ra, và đưa vào partition tương ứng. Như vậy 2 bản ghi có cùng giá trị ở cột partition sẽ nằm trên cùng 1 partition. Do đó, Hash partition thường được áp dụng cho những cột mà giá trị trong cột gần như duy nhất, để nó có thể phát huy hiệu quả tối đa.

Đây là 1 ví dụ về Hash Partition

CREATE TABLE khach_hang ( 
          id int4 not null,
          ho_ten text not null,
          gioi_tinh text,
          thoi_gian_mua_hang date ) PARTITION BY HASH(id);

Và câu lệnh tạo ra các partition

CREATE TABLE HASH0 PARTITION OF khach_hang FOR VALUES WITH (MODULUS 5, REMAINDER 0);
CREATE TABLE HASH1 PARTITION OF khach_hang FOR VALUES WITH (MODULUS 5, REMAINDER 1);
CREATE TABLE HASH2 PARTITION OF khach_hang FOR VALUES WITH (MODULUS 5, REMAINDER 2);
CREATE TABLE HASH3 PARTITION OF khach_hang FOR VALUES WITH (MODULUS 5, REMAINDER 3);
CREATE TABLE HASH4 PARTITION OF khach_hang FOR VALUES WITH (MODULUS 5, REMAINDER 4);

Ở đây ta có 2 mệnh đề: MODULUSREMAINDER. MODULUS là số partition sẽ được tạo ra. PostgreSQL sẽ dựa vào MODULUS để đưa dữ liệu vào REMAINDER tương ứng.

Giả sử: Với ví dự bên trên, bạn thêm 1 dòng dữ liệu có giá trị hash của cột id là 104, PostgreSQL sẽ lấy số dư của 104 chia cho 5 (104 mod 5), kết quả là 4. Như vậy dòng dữ liệu sẽ được đưa vào Partition HASH4 do có REMAINDER là 4.

Đọc thêm  Cấu hình Streaming Replication trong PostgreSQL 13

Nguồn: https://dangxuanduy.com/

   Hãy tham gia group “Kho tài liệu kiến thức database” để cùng học hỏi và chia sẻ nhé.

Xin cho tôi được biết, bạn cảm thấy bài viết này như thế nào? Ý kiến của bạn sẽ giúp tôi nâng cao chất lượng bài viết của mình.

    Hãy chia sẻ bài viết này nếu bạn thấy có ích nhé

     

     

    0 0 votes
    Article Rating
    Subscribe
    Notify of
    guest
    0 Comments
    Inline Feedbacks
    View all comments