TopDev

PostgreSQL có hỗ trợ partition table không? Hướng dẫn từ A đến Z cho người mới

minhdev 📖 6 phút đọc ✎ đã sửa

Khi làm việc với các hệ thống cơ sở dữ liệu lớn, một trong những kỹ thuật phổ biến để tối ưu hiệu suất và quản lý dữ liệu hiệu quả là phân vùng bảng (partition table). Vậy câu hỏi đặt ra là: PostgreSQL có hỗ trợ partition table không? Câu trả lời là , và PostgreSQL còn cung cấp nhiều tùy chọn phân vùng linh hoạt, phù hợp cho nhiều trường hợp sử dụng thực tế.



Partition table trong PostgreSQL là gì?#

Partition table (bảng phân vùng) là một kỹ thuật cho phép chia một bảng lớn thành nhiều bảng con nhỏ hơn (gọi là partition) dựa trên một tiêu chí nhất định như thời gian, ID, khu vực địa lý… Mặc dù dữ liệu được chia nhỏ ở cấp độ vật lý, nhưng người dùng vẫn thao tác với nó như một bảng duy nhất ở cấp độ logic.

Điều này giúp:

  • Cải thiện hiệu suất truy vấn

  • Tăng tốc độ ghi và xóa dữ liệu

  • Dễ quản lý dữ liệu lịch sử hoặc dữ liệu theo từng nhóm



PostgreSQL bắt đầu hỗ trợ partition từ khi nào?#

PostgreSQL đã hỗ trợ partition từ rất lâu thông qua table inheritance, nhưng từ phiên bản PostgreSQL 10 trở đi, hệ thống đã hỗ trợ native partitioning – nghĩa là phân vùng được quản lý tự động và tối ưu tốt hơn ngay trong nhân hệ thống.

Từ PostgreSQL 11 trở đi, việc xử lý INSERT, UPDATE, SELECT, DELETE trên các bảng phân vùng đã trở nên ổn định và mạnh mẽ hơn nhiều.



PostgreSQL hỗ trợ những kiểu phân vùng nào?#

PostgreSQL hỗ trợ ba kiểu phân vùng chính:

  • Range Partitioning – phân vùng theo khoảng (ví dụ: theo ngày, theo ID)

  • List Partitioning – phân vùng theo giá trị cụ thể (ví dụ: theo quốc gia, khu vực)

  • Hash Partitioning – phân vùng bằng cách băm giá trị, giúp chia đều dữ liệu

Bạn có thể áp dụng riêng lẻ hoặc kết hợp các kiểu này trong các trường hợp phức tạp.



Ví dụ phân vùng bảng theo thời gian (Range Partitioning)#

Giả sử bạn có bảng don_hang lưu thông tin đơn hàng và bạn muốn phân vùng theo tháng:

Tạo bảng mẹ (partitioned table):#

CREATE TABLE don_hang ( id SERIAL PRIMARY KEY, ngay DATE NOT NULL, tong_tien NUMERIC ) PARTITION BY RANGE (ngay);

Tạo các bảng con (partition):#

` CREATE TABLE don_hang_2024_01 PARTITION OF don_hang FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');

CREATE TABLE don_hang_2024_02 PARTITION OF don_hang FOR VALUES FROM ('2024-02-01') TO ('2024-03-01'); `

Khi bạn thực hiện thao tác INSERT vào bảng don_hang, PostgreSQL sẽ tự động xác định partition phù hợp dựa trên giá trị cột ngay.



Lợi ích của việc dùng partition table#

  • Hiệu suất tốt hơn: Truy vấn chỉ quét dữ liệu trong partition phù hợp thay vì toàn bộ bảng

  • Quản lý dữ liệu dễ dàng: Có thể xóa dữ liệu cũ bằng cách DROP partition thay vì DELETE

  • Tăng tốc độ backup/restore: Chỉ cần sao lưu các partition cụ thể thay vì toàn bộ bảng

  • Hỗ trợ tạo chỉ mục riêng cho từng partition: Giúp tối ưu truy vấn theo nhu cầu



Những lưu ý khi dùng partition table trong PostgreSQL#

  • Không nên phân vùng nếu bảng quá nhỏ vì chi phí quản lý partition có thể cao hơn lợi ích.

  • Không nên dùng quá nhiều partition con (trăm ngàn bảng con) nếu không thực sự cần thiết.

  • Nên thiết kế phân vùng phù hợp với kiểu truy vấn phổ biến (ví dụ: theo thời gian, theo khu vực).



Kết luận#

PostgreSQL hoàn toàn có hỗ trợ partition table, và không chỉ hỗ trợ ở mức cơ bản mà còn cung cấp hệ thống phân vùng mạnh mẽ, hiệu quả, phù hợp với các hệ thống cần quản lý dữ liệu lớn. Nếu bạn đang xây dựng ứng dụng có dữ liệu phát sinh liên tục như log, giao dịch, đơn hàng… thì partitioning chính là công cụ không thể thiếu để tăng hiệu suất và giảm gánh nặng cho hệ thống.



Dưới đây là hướng dẫn chi tiết từng phần về:

  • Thiết lập partition tự động trong PostgreSQL

  • Tạo chỉ mục trên các partition

  • Sử dụng trigger để kiểm soát phân vùng đặc biệt (trong trường hợp không dùng native partition)



🧩 1. Thiết lập partition tự động trong PostgreSQL (native partition)#

Kể từ PostgreSQL 10, bạn có thể dùng partition tự động dựa vào cột và kiểu phân vùng (RANGE, LIST, HASH). Tuy nhiên, PostgreSQL không hỗ trợ tự tạo bảng partition con một cách tự động, bạn vẫn cần tạo thủ công hoặc viết script.

🔧 Ví dụ: Partition theo tháng – tự động tạo bằng hàm và trigger#

Bước 1: Tạo bảng mẹ

CREATE TABLE don_hang ( id SERIAL PRIMARY KEY, ngay DATE NOT NULL, tong_tien NUMERIC ) PARTITION BY RANGE (ngay);

Bước 2: Viết hàm tạo partition con nếu chưa tồn tại

` CREATE OR REPLACE FUNCTION tao_partition_don_hang() RETURNS TRIGGER AS $$ DECLARE partition_ten TEXT; start_date DATE; end_date DATE; BEGIN start_date := date_trunc('month', NEW.ngay); end_date := start_date + INTERVAL '1 month'; partition_ten := 'don_hang_' || to_char(start_date, 'YYYY_MM');

-- Tạo partition nếu chưa tồn tại EXECUTE format( 'CREATE TABLE IF NOT EXISTS %I PARTITION OF don_hang FOR VALUES FROM (%L) TO (%L)', partition_ten, start_date, end_date );

RETURN NEW; END; $$ LANGUAGE plpgsql; `

Bước 3: Tạo trigger gọi hàm mỗi khi chèn dữ liệu

CREATE TRIGGER don_hang_partition_trigger BEFORE INSERT ON don_hang FOR EACH ROW EXECUTE FUNCTION tao_partition_don_hang();

✅ Khi bạn INSERT vào don_hang, nếu chưa có partition con, hệ thống sẽ tạo và sau đó tự phân phối dữ liệu đúng phân vùng.



📌 2. Tạo chỉ mục trên từng partition#

Vì mỗi partition là một bảng con độc lập, nên bạn cần tạo chỉ mục riêng cho từng bảng con.

🔧 Ví dụ:#

CREATE INDEX idx_don_hang_ngay_2024_01 ON don_hang_2024_01(ngay); CREATE INDEX idx_don_hang_ngay_2024_02 ON don_hang_2024_02(ngay);

Bạn có thể viết một hàm tạo chỉ mục tự động sau khi tạo partition để tránh quên.



🧠 3. Sử dụng trigger để điều phối phân vùng thủ công (non-native partitioning – trước PostgreSQL 10)#

Trong các phiên bản cũ, bạn dùng table inheritance thay vì native partition. Khi đó, trigger được dùng để điều hướng dữ liệu đến đúng bảng con.

🔧 Bước 1: Tạo bảng mẹ#

CREATE TABLE don_hang ( id SERIAL PRIMARY KEY, ngay DATE, tong_tien NUMERIC );

🔧 Bước 2: Tạo bảng con bằng INHERITS#

CREATE TABLE don_hang_2024_01 ( CHECK (ngay >= DATE '2024-01-01' AND ngay < DATE '2024-02-01') ) INHERITS (don_hang);

🔧 Bước 3: Viết trigger điều phối dữ liệu#

` CREATE OR REPLACE FUNCTION chuyen_don_hang() RETURNS TRIGGER AS $$ BEGIN IF (NEW.ngay >= DATE '2024-01-01' AND NEW.ngay < DATE '2024-02-01') THEN INSERT INTO don_hang_2024_01 VALUES (NEW.*); RETURN NULL; END IF; RAISE EXCEPTION 'Dữ liệu không nằm trong bất kỳ phân vùng nào'; END; $$ LANGUAGE plpgsql;

CREATE TRIGGER don_hang_insert_trigger BEFORE INSERT ON don_hang FOR EACH ROW EXECUTE FUNCTION chuyen_don_hang(); `

✅ Trong mô hình này, bạn không lưu dữ liệu trong bảng cha, mà chỉ định tuyến vào bảng con thông qua trigger.

Bài liên quan trong #Database

✓ Đã sao chép link