~/VibeHandbook
PDF miễn phí

Cơ sở dữ liệu

postgresql.org

PostgreSQL

Nó là gì

PostgreSQL là một cơ sở dữ liệu quan hệ mã nguồn mở, đã trưởng thành, lưu trữ dữ liệu trong các bảng có kiểu dữ liệu với khả năng hỗ trợ mạnh mẽ cho (Structured Query Language - Ngôn ngữ truy vấn có cấu trúc), giao dịch (transaction), và tính toàn vẹn dữ liệu. Nó nổi tiếng về độ chính xác, khả năng mở rộng, và các tính năng phong phú như JSONB (kiểu dữ liệu nhị phân của Postgres), tìm kiếm toàn văn (full-text search), và các hàm cửa sổ (window functions). Đây là lựa chọn mặc định cho hầu hết các ứng dụng cần dữ liệu có cấu trúc đáng tin cậy.

Điểm mạnh

  • Hãy hình dung một giao dịch chuyển khoản ngân hàng: nó phải hoàn tất toàn bộ, hoặc bị hủy toàn bộ — không bao giờ dừng ở trạng thái nửa vời. Sự đảm bảo tất-cả-hoặc-không-gì đó được gọi là giao dịch ACID (Atomicity, Consistency, Isolation, Durability - Tính nguyên tử, Tính nhất quán, Tính cô lập, Tính bền vững), và Postgres mang lại cho bạn tính nhất quán mạnh mẽ theo mặc định.
  • SQL mạnh mẽ: joins (kết nối bảng), CTE (Common Table Expressions - Biểu thức bảng chung), hàm cửa sổ, và các hàm tổng hợp.
  • Các kiểu dữ liệu linh hoạt bao gồm JSONB, mảng, khoảng giá trị (ranges), và các kiểu tùy chỉnh.
  • Các phần mở rộng như PostGIS (dữ liệu địa lý) và pgvector (embeddings).
  • Các ràng buộc mạnh mẽ, khóa ngoại (foreign key), và quy tắc kiểm tra (check) giúp đảm bảo chất lượng dữ liệu.

Đánh đổi

  • Mở rộng theo chiều dọc (vertical scaling) thì dễ; phân mảnh theo chiều ngang (horizontal sharding) đòi hỏi thêm công cụ hỗ trợ.
  • Cần thực hiện các migration (di trú) lược đồ (schema) khi mô hình dữ liệu của bạn thay đổi theo thời gian.
  • Nặng nề hơn khi vận hành so với một cơ sở dữ liệu dạng một-tệp-duy-nhất, đối với các dự án nhỏ.
  • Mô hình mỗi client một kết nối cần có một bộ gộp kết nối (connection pooler, ví dụ PgBouncer) khi hoạt động ở quy mô lớn.

Khi nào nên dùng

Hãy chọn PostgreSQL làm lựa chọn mặc định cho hầu hết mọi ứng dụng có dữ liệu quan hệ, giao dịch, hoặc nhu cầu báo cáo: các backend SaaS (Software as a Service - Phần mềm dạng dịch vụ), thương mại điện tử, phân tích dữ liệu, và bất cứ thứ gì hưởng lợi từ các ràng buộc và phép kết nối (joins).

Phù hợp với vibe coding

Khi chỉ đạo AI, hãy cung cấp cho nó các thực thể (entities) và mối quan hệ giữa chúng, sau đó yêu cầu nó tạo ra một lược đồ đã chuẩn hóa (normalized schema) với khóa chính (primary key), khóa ngoại (foreign key), ràng buộc NOT NULL, và các chỉ mục (index) hợp lý. Hãy kiên quyết yêu cầu sử dụng truy vấn tham số hóa (parameterized query — không bao giờ nối chuỗi SQL trực tiếp) để ngăn chặn tấn công chèn mã (injection), và yêu cầu AI bọc các thao tác ghi nhiều bước trong một giao dịch (transaction). Một mẹo hay: yêu cầu AI cũng tạo ra một tệp migration có thể đảo ngược (reversible). Hãy yêu cầu nó giải thích từng chỉ mục mà nó thêm vào. Bằng cách đó, bạn hiểu được sự đánh đổi giữa đọc và ghi trước khi áp dụng chúng.

CREATE TABLE users (
  id         BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  email      TEXT NOT NULL UNIQUE,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE orders (
  id       BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id  BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  total    NUMERIC(10,2) NOT NULL CHECK (total >= 0),
  status   TEXT NOT NULL DEFAULT 'pending'
);

CREATE INDEX idx_orders_user_id ON orders(user_id);

-- Parameterized query (placeholders, not concatenation)
SELECT o.id, o.total
FROM orders o
WHERE o.user_id = $1 AND o.status = $2;