PostgreSQL là gì? Hệ quản trị cơ sở dữ liệu quan hệ mạnh nhất thế giới
Database

PostgreSQL là gì? Hệ quản trị cơ sở dữ liệu quan hệ mạnh nhất thế giới

PostgreSQL là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở hàng đầu, hỗ trợ ACID, MVCC, JSON/JSONB và hàng trăm extension. Tìm hiểu cách kết nối và truy vấn PostgreSQL bằng Python và Node.js.

✦ Tóm tắt nhanh
PostgreSQL là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở hàng đầu, hỗ trợ ACID, MVCC, JSON/JSONB và hàng trăm extension. Tìm hiểu cách kết nối và truy vấn PostgreSQL bằng Python và Node.js.
Bài này thế nào?

PostgreSQL là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở được mệnh danh là "most advanced open source database" — lựa chọn hàng đầu của Instagram, Shopify, Discord và hàng nghìn startup toàn cầu. Bài viết giải thích PostgreSQL là gì, kiến trúc hoạt động, và cách kết nối thực tế bằng Python và Node.js.

PostgreSQL là gì?

PostgreSQL (đọc là "post-gres-Q-L" hoặc "postgres") là hệ quản trị cơ sở dữ liệu quan hệ (RDBMS) mã nguồn mở, ra đời từ dự án POSTGRES tại Đại học UC Berkeley năm 1986 bởi giáo sư Michael Stonebraker. Đến năm 1996, dự án đổi tên thành PostgreSQL và trở thành cộng đồng phát triển độc lập.

Điều khiến PostgreSQL nổi bật là sự kết hợp hiếm có: tuân thủ chuẩn SQL chặt chẽ trong khi vẫn hỗ trợ JSON/JSONB, mảng, kiểu dữ liệu tùy chỉnh, và hơn 100 extension mạnh mẽ như PostGIS (dữ liệu địa lý) và pgvector (vector embedding cho AI).

Kiến trúc PostgreSQL

Khi một ứng dụng kết nối đến PostgreSQL, luồng xử lý như sau:

  1. Client gửi kết nối đến Postmaster (process quản lý chính)
  2. Postmaster tạo một Backend process riêng cho mỗi kết nối
  3. Backend đọc/ghi qua Shared Buffer (bộ nhớ đệm dùng chung)
  4. Dữ liệu được persist xuống Data Files trên disk

PostgreSQL dùng mô hình process-per-connection (một process OS cho mỗi client), khác với MySQL dùng thread. Đây là lý do connection pooler như PgBouncer quan trọng khi scale lên hàng nghìn kết nối.

ACID và MVCC

PostgreSQL đảm bảo ACID đầy đủ thông qua cơ chế MVCC (Multi-Version Concurrency Control): khi update một row, Postgres không ghi đè mà tạo phiên bản mới — reader thấy phiên bản cũ, writer tạo phiên bản mới. Kết quả: đọc không bao giờ block ghi, và ghi không bao giờ block đọc.

Kết nối PostgreSQL bằng Python và Node.js

Python với psycopg2:

Python
 1import psycopg2
 2
 3conn = psycopg2.connect(
 4    host="localhost",
 5    port=5432,
 6    dbname="mydb",
 7    user="postgres",
 8    password="secret"
 9)
10cur = conn.cursor()
11
12# Insert với parameterized query (tránh SQL injection)
13cur.execute(
14    "INSERT INTO users (name, email) VALUES (%s, %s)",
15    ("Alice", "alice@example.com")
16)
17conn.commit()
18
19# Select
20cur.execute("SELECT id, name FROM users WHERE active = %s", (True,))
21rows = cur.fetchall()
22for row in rows:
23    print(row)  # (1, 'Alice')
24
25cur.close()
26conn.close()

Node.js với pg:

JavaScript
 1const { Pool } = require('pg');
 2
 3const pool = new Pool({
 4  host: 'localhost',
 5  port: 5432,
 6  database: 'mydb',
 7  user: 'postgres',
 8  password: 'secret',
 9});
10
11async function getActiveUsers() {
12  const result = await pool.query(
13    'SELECT id, name FROM users WHERE active = $1',
14    [true]
15  );
16  return result.rows; // [{ id: 1, name: 'Alice' }]
17}

CLI psql cơ bản:

Bash
1psql -h localhost -U postgres -d mydb
2
3# Trong psql
4\dt              -- liệt kê các bảng
5\d users         -- xem cấu trúc bảng users
6\timing on       -- bật đo thời gian query

Indexing trong PostgreSQL

PostgreSQL hỗ trợ nhiều loại index. Phổ biến nhất:

Loại Dùng khi Ví dụ
B-tree Mặc định, cho =, <, >, BETWEEN CREATE INDEX ON users(email)
GIN Tìm kiếm trong JSONB, array, full-text CREATE INDEX ON posts USING GIN(tags)
Partial Index chỉ một tập con rows CREATE INDEX ON orders(created_at) WHERE status = 'pending'
SQL
1-- B-tree index trên email
2CREATE INDEX idx_users_email ON users(email);
3
4-- GIN index để query JSONB
5CREATE INDEX idx_products_meta ON products USING GIN(metadata);
6
7-- Partial index cho orders chưa xử lý
8CREATE INDEX idx_pending_orders ON orders(created_at)
9WHERE status = 'pending';

PostgreSQL vs MySQL — Khi nào chọn cái nào?

Tiêu chí PostgreSQL MySQL
JSON support JSONB với index JSON cơ bản
Full-text search Tích hợp sẵn Hạn chế
Kiểu dữ liệu Phong phú (array, hstore, range) Cơ bản
Replication Logical + streaming Binary log
License PostgreSQL (free, commercial ok) GPL

Chọn PostgreSQL khi cần query phức tạp, ACID chặt, hoặc JSON hybrid. Chọn MySQL khi stack WordPress/LAMP hoặc cần ecosystem PHP rộng hơn.

MongoDB là gì? Document database và khi nào chọn NoSQL

Use cases thực tế

  • Instagram: dùng PostgreSQL cho toàn bộ social graph và media metadata
  • Shopify: PostgreSQL làm primary store cho hàng triệu merchant
  • Stripe: PostgreSQL làm primary database cho toàn bộ hệ thống thanh toán xử lý hàng tỷ USD

API là gì? REST API và cách hoạt động

Redis là gì? Cache, Pub/Sub và hàng đợi với in-memory database

Câu hỏi thường gặpQ&A
PostgreSQL khác MySQL ở điểm gì quan trọng nhất?
PostgreSQL hỗ trợ MVCC (Multi-Version Concurrency Control) thuần túy hơn, có kiểu dữ liệu phong phú hơn (JSONB, array, hstore, custom type), và tuân thủ chuẩn SQL chặt chẽ hơn. MySQL/MariaDB nhanh hơn trong workload đọc nhiều đơn giản, nhưng PostgreSQL được chọn khi cần tính nhất quán dữ liệu cao và query phức tạp.
ACID trong PostgreSQL có nghĩa là gì?
ACID là bốn thuộc tính đảm bảo giao dịch đáng tin cậy: Atomicity (toàn bộ transaction thành công hoặc rollback hoàn toàn), Consistency (dữ liệu luôn ở trạng thái hợp lệ), Isolation (các transaction không ảnh hưởng lẫn nhau khi đang chạy đồng thời), Durability (dữ liệu đã commit được lưu vĩnh viễn dù hệ thống crash).
MVCC là gì và tại sao quan trọng?
MVCC (Multi-Version Concurrency Control) cho phép nhiều transaction đọc/ghi đồng thời mà không block lẫn nhau. Khi bạn update một row, PostgreSQL tạo phiên bản mới thay vì ghi đè — reader thấy phiên bản cũ trong khi writer tạo phiên bản mới. Kết quả: đọc không bao giờ block ghi, và ghi không block đọc.
PostgreSQL có thể lưu dữ liệu JSON không?
Có, PostgreSQL hỗ trợ hai kiểu: JSON (lưu nguyên văn bản JSON) và JSONB (lưu dạng binary đã phân tích, hỗ trợ index và query nhanh hơn). JSONB được khuyến nghị cho hầu hết trường hợp vì cho phép dùng toán tử @>, ?, và tạo GIN index để tìm kiếm trong document.
Khi nào nên dùng PostgreSQL thay vì MongoDB?
Chọn PostgreSQL khi dữ liệu có cấu trúc rõ ràng và quan hệ giữa các bảng (JOIN), cần ACID đầy đủ cho giao dịch tài chính hoặc thương mại điện tử, hoặc cần query phức tạp với GROUP BY và window function. Chọn MongoDB khi schema thay đổi thường xuyên, dữ liệu dạng document lồng nhau tự nhiên, hoặc cần scale horizontal nhanh chóng.
PostgreSQL có dùng được miễn phí không?
Có. PostgreSQL được phát hành theo PostgreSQL License — một giấy phép kiểu BSD/MIT cho phép sử dụng, sửa đổi và phân phối miễn phí kể cả trong sản phẩm thương mại. Không có phiên bản Enterprise trả phí — mọi tính năng đều có trong bản mã nguồn mở.

PostgreSQL is the open-source relational database management system dubbed "the world's most advanced open source database" — the top choice for Instagram, Shopify, Discord, and thousands of startups worldwide. This article explains what PostgreSQL is, how its architecture works, and how to connect to it in practice using Python and Node.js.

What is PostgreSQL?

PostgreSQL (pronounced "post-gres-Q-L" or simply "postgres") is an open-source relational database management system (RDBMS) that originated from the POSTGRES project at UC Berkeley in 1986, led by Professor Michael Stonebraker. In 1996 the project was renamed PostgreSQL and evolved into an independent open-source community.

What makes PostgreSQL stand out is a rare combination: strict adherence to the SQL standard while also supporting JSON/JSONB, arrays, custom data types, and over 100 powerful extensions such as PostGIS (geospatial data) and pgvector (vector embeddings for AI).

PostgreSQL Architecture

When an application connects to PostgreSQL, the processing flow is as follows:

  1. The Client sends a connection to the Postmaster (the main managing process)
  2. The Postmaster forks a dedicated Backend process for each connection
  3. The Backend reads and writes through the Shared Buffer (shared memory cache)
  4. Data is persisted to Data Files on disk

PostgreSQL uses a process-per-connection model (one OS process per client), unlike MySQL which uses threads. This is why a connection pooler such as PgBouncer becomes important when scaling to thousands of concurrent connections.

ACID and MVCC

PostgreSQL guarantees full ACID compliance through MVCC (Multi-Version Concurrency Control): when a row is updated, Postgres does not overwrite it but instead creates a new version — readers see the old version while the writer creates the new one. The result: reads never block writes, and writes never block reads.

Connecting to PostgreSQL with Python and Node.js

Python with psycopg2:

Python
 1import psycopg2
 2
 3conn = psycopg2.connect(
 4    host="localhost",
 5    port=5432,
 6    dbname="mydb",
 7    user="postgres",
 8    password="secret"
 9)
10cur = conn.cursor()
11
12# Insert with parameterized query (prevents SQL injection)
13cur.execute(
14    "INSERT INTO users (name, email) VALUES (%s, %s)",
15    ("Alice", "alice@example.com")
16)
17conn.commit()
18
19# Select
20cur.execute("SELECT id, name FROM users WHERE active = %s", (True,))
21rows = cur.fetchall()
22for row in rows:
23    print(row)  # (1, 'Alice')
24
25cur.close()
26conn.close()

Node.js with pg:

JavaScript
 1const { Pool } = require('pg');
 2
 3const pool = new Pool({
 4  host: 'localhost',
 5  port: 5432,
 6  database: 'mydb',
 7  user: 'postgres',
 8  password: 'secret',
 9});
10
11async function getActiveUsers() {
12  const result = await pool.query(
13    'SELECT id, name FROM users WHERE active = $1',
14    [true]
15  );
16  return result.rows; // [{ id: 1, name: 'Alice' }]
17}

Basic psql CLI commands:

Bash
1psql -h localhost -U postgres -d mydb
2
3# Inside psql
4\dt              -- list all tables
5\d users         -- show users table structure
6\timing on       -- enable query timing

Indexing in PostgreSQL

PostgreSQL supports multiple index types. The most common:

Type Use when Example
B-tree Default; for =, <, >, BETWEEN CREATE INDEX ON users(email)
GIN Searching inside JSONB, arrays, full-text CREATE INDEX ON posts USING GIN(tags)
Partial Index only a subset of rows CREATE INDEX ON orders(created_at) WHERE status = 'pending'
SQL
1-- B-tree index on email
2CREATE INDEX idx_users_email ON users(email);
3
4-- GIN index for querying JSONB
5CREATE INDEX idx_products_meta ON products USING GIN(metadata);
6
7-- Partial index for unprocessed orders
8CREATE INDEX idx_pending_orders ON orders(created_at)
9WHERE status = 'pending';

PostgreSQL vs MySQL — When to Choose Which?

Criterion PostgreSQL MySQL
JSON support JSONB with indexes Basic JSON
Full-text search Built-in Limited
Data types Rich (arrays, hstore, ranges) Basic
Replication Logical + streaming Binary log
License PostgreSQL (free, commercial ok) GPL

Choose PostgreSQL when you need complex queries, strict ACID compliance, or a JSON hybrid approach. Choose MySQL when working with a WordPress/LAMP stack or when you need the broader PHP ecosystem.

Real-world Use Cases

  • Instagram: uses PostgreSQL for the entire social graph and media metadata
  • Shopify: PostgreSQL as the primary store for millions of merchants
  • Stripe: PostgreSQL as the primary database for a payment system processing billions of dollars

What is Redis? Cache, Pub/Sub and queues with in-memory database

What is MongoDB? Document database and when to choose NoSQL

What is an API? REST API and how it works

Frequently Asked QuestionsQ&A
What is the most important difference between PostgreSQL and MySQL?
PostgreSQL implements MVCC (Multi-Version Concurrency Control) more purely, offers richer data types (JSONB, arrays, hstore, custom types), and adheres more strictly to the SQL standard. MySQL/MariaDB is faster for simple read-heavy workloads, but PostgreSQL is the choice when you need high data consistency and complex queries.
What does ACID mean in PostgreSQL?
ACID is four properties that guarantee reliable transactions: Atomicity (the entire transaction either succeeds or rolls back completely), Consistency (data always remains in a valid state), Isolation (concurrent transactions do not interfere with each other), and Durability (committed data is permanently stored even if the system crashes).
What is MVCC and why does it matter?
MVCC (Multi-Version Concurrency Control) allows multiple transactions to read and write simultaneously without blocking each other. When you update a row, PostgreSQL creates a new version instead of overwriting — readers see the old version while the writer creates the new one. The result: reads never block writes, and writes never block reads.
Can PostgreSQL store JSON data?
Yes. PostgreSQL supports two types: JSON (stores raw JSON text) and JSONB (stores a parsed binary representation, supporting indexes and faster queries). JSONB is recommended for most use cases because it allows the @>, ? operators and GIN indexes for searching inside documents.
When should I use PostgreSQL instead of MongoDB?
Choose PostgreSQL when your data has a clear structure with relationships between tables (JOINs), you need full ACID compliance for financial or e-commerce transactions, or you need complex queries with GROUP BY and window functions. Choose MongoDB when the schema changes frequently, data is naturally nested documents, or you need rapid horizontal scaling.
Is PostgreSQL free to use?
Yes. PostgreSQL is released under the PostgreSQL License — a permissive BSD/MIT-style license that allows free use, modification, and distribution even in commercial products. There is no paid Enterprise edition — all features are available in the open-source release.