Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 26 — SQL Databases — Khi chọn và Cách chọn

Architecture Decision-Making Bài 26/60

Mở đầu — vì sao bài này quan trọng

Trong hành trình ra quyết định kiến trúc, chọn cơ sở dữ liệu (database) là một trong những quyết định có "sức nặng" lớn nhất mà bạn sẽ đối mặt. Lý do rất đơn giản: database là nơi chứa tài sản quý giá nhất của doanh nghiệp — dữ liệu. Bạn có thể viết lại một service, đổi ngôn ngữ lập trình, thay framework tương đối dễ dàng. Nhưng migrate dữ liệu từ database này sang database khác khi hệ thống đã chạy production với hàng chục triệu bản ghi thì là một cuộc phẫu thuật đau đớn, tốn kém và đầy rủi ro. Nhiều startup Việt Nam đã trả giá bằng những đêm không ngủ chỉ vì một quyết định database vội vàng ở giai đoạn đầu.

Bài này tập trung riêng vào SQL databases (cơ sở dữ liệu quan hệ) — nhóm database dùng ngôn ngữ SQL, tổ chức dữ liệu theo bảng (table), hàng (row), cột (column) và tuân thủ tính chất ACID. Chúng ta sẽ trả lời hai câu hỏi cốt lõi: Khi nào bạn nên chọn SQL (thay vì NoSQL — vốn là chủ đề của Bài 27), và cách chọn đúng loại SQL database trong số các ứng viên phổ biến như PostgreSQL, MySQL/MariaDB, SQL Server, Oracle. Đây không phải là bài về "SQL nào tốt nhất" một cách tuyệt đối, vì không tồn tại câu trả lời như vậy. Đây là bài về việc ra quyết định có căn cứ, có thể bảo vệ được trước hội đồng kiến trúc và trước chính bạn của 3 năm sau.

Với tư cách một người ra quyết định kiến trúc, bạn cần hiểu đủ sâu để không bị "bán hàng" bởi marketing của các nhà cung cấp, và đủ thực tế để không chọn công nghệ chỉ vì nó "hot".

Khái niệm cốt lõi

SQL database là gì và điểm mạnh bản chất

SQL database (relational database) tổ chức dữ liệu thành các bảng có schema (lược đồ) được định nghĩa trước: mỗi cột có kiểu dữ liệu rõ ràng, các ràng buộc (constraint) như NOT NULL, UNIQUE, FOREIGN KEY được cơ sở dữ liệu tự động thực thi. Sức mạnh cốt lõi của SQL nằm ở bốn điểm:

  • ACID transactions: Atomicity (toàn vẹn — hoặc tất cả thành công, hoặc rollback hết), Consistency (nhất quán — dữ liệu luôn thoả các ràng buộc), Isolation (cô lập — các giao dịch song song không giẫm chân nhau), Durability (bền vững — đã commit thì không mất). Đây là lý do bạn tin tưởng SQL cho tiền bạc, đơn hàng, tồn kho.
  • Quan hệ và JOIN: Bạn có thể liên kết dữ liệu giữa nhiều bảng và truy vấn linh hoạt mà không cần biết trước câu hỏi. Đây là ưu thế lớn khi domain có nhiều thực thể liên quan chặt chẽ.
  • Schema mạnh (strong schema): Cấu trúc dữ liệu được kiểm soát ở tầng database, giảm rủi ro dữ liệu rác lọt vào từ tầng ứng dụng.
  • SQL — ngôn ngữ truy vấn khai báo trưởng thành: Chuẩn hoá, phổ biến, có hàng chục năm tối ưu hoá query planner phía sau.

Khi nào SQL là lựa chọn đúng

SQL nên là lựa chọn mặc định (default choice) cho đại đa số ứng dụng nghiệp vụ, và bạn chỉ nên rời khỏi nó khi có lý do cụ thể. Cụ thể, chọn SQL khi:

  • Dữ liệu có cấu trúc rõ ràng và nhiều quan hệ (users, orders, products, payments...).
  • Bạn cần transaction đa bảng đảm bảo tính nhất quán mạnh (strong consistency) — ví dụ trừ tiền tài khoản A, cộng vào B, ghi log, tất cả phải nguyên tử.
  • Tính toàn vẹn dữ liệu quan trọng hơn tốc độ ghi cực đại — tài chính, kế toán, quản lý tồn kho.
  • Bạn cần truy vấn ad-hoc linh hoạt cho báo cáo, phân tích nghiệp vụ.
  • Quy mô dữ liệu nằm trong tầm một node mạnh hoặc một cụm vừa phải — điều đúng với 90% doanh nghiệp Việt Nam (đến hàng terabyte vẫn hoàn toàn khả thi trên một PostgreSQL được cấu hình tốt).

Cách chọn giữa các SQL database phổ biến

Khi đã quyết định dùng SQL, bạn phải chọn "hương vị" cụ thể. Dưới đây là bức tranh thực tế, đặc biệt trong bối cảnh Việt Nam:

PostgreSQL — Lựa chọn mặc định của thời hiện đại. Mã nguồn mở, giấy phép cực kỳ thoáng, giàu tính năng và tuân thủ chuẩn SQL nghiêm ngặt. PostgreSQL nổi bật với: kiểu dữ liệu JSONB (lưu JSON có index, cho phép "lai" SQL và NoSQL trong cùng một hệ), full-text search tích hợp, extension mạnh (PostGIS cho dữ liệu địa lý, pgvector cho AI/embedding, TimescaleDB cho time-series), hỗ trợ giao dịch và concurrency (MVCC) rất tốt. Nếu bạn không có ràng buộc đặc biệt, PostgreSQL nên là điểm khởi đầu của mọi cuộc thảo luận.

MySQL / MariaDB — Mã nguồn mở, phổ biến khủng khiếp, hệ sinh thái khổng lồ (WordPress, Magento, phần lớn shared hosting ở VN đều mặc định MySQL). Đọc nhanh, cấu hình đơn giản, cộng đồng vận hành đông đảo nên dễ tuyển người. MariaDB là bản fork mã nguồn mở hoàn toàn của MySQL, tương thích gần như tuyệt đối và thường được ưa chuộng để tránh phụ thuộc Oracle (chủ sở hữu MySQL). MySQL/MariaDB là lựa chọn tốt khi workload thiên về đọc, khi bạn cần tương thích với các ứng dụng PHP phổ biến, hoặc khi đội ngũ đã quen thuộc.

SQL Server (Microsoft) — Mạnh, công cụ quản trị và BI xuất sắc, tích hợp tốt với hệ sinh thái .NET và Azure. Nhược điểm là chi phí license đáng kể. Phù hợp với doanh nghiệp lớn, ngân hàng, hoặc tổ chức đã "cắm rễ" trong thế giới Microsoft.

Oracle — Cực kỳ mạnh, đáng tin cậy cho hệ thống cực lớn (core banking, viễn thông), nhưng chi phí và độ phức tạp vận hành rất cao. Ở Việt Nam thường thấy trong ngân hàng, viễn thông, khu vực nhà nước — nơi đã đầu tư từ lâu và cần cam kết hỗ trợ doanh nghiệp.

Các managed/cloud-native SQL như Amazon RDS/Aurora, Google Cloud SQL, Azure SQL, hay các distributed SQL như CockroachDB, YugabyteDB, TiDB — đáng cân nhắc khi bạn cần khả năng mở rộng ngang mạnh, HA tự động, hoặc muốn giảm gánh nặng vận hành. Đổi lại là chi phí và mức độ lock-in nhà cung cấp cần cân nhắc kỹ.

Các tiêu chí quyết định cụ thể

Khi so sánh, hãy đánh giá theo các trục sau, không chỉ theo cảm tính:

  • Tính năng cần thiết: Bạn có cần JSONB, full-text search, GIS, time-series không? Nếu có, PostgreSQL thường thắng.
  • Mô hình license và chi phí: Open source (Postgres, MariaDB) hay thương mại (SQL Server, Oracle)? Tính cả chi phí license, hạ tầng, và nhân sự vận hành.
  • Hệ sinh thái và nhân lực địa phương: Ở VN, tuyển được DBA/dev quen công nghệ nào? Cộng đồng hỗ trợ ra sao?
  • Đặc tính workload: Nặng đọc, nặng ghi, hay hỗn hợp? Cần replication kiểu gì?
  • Khả năng mở rộng tương lai: Quy mô dữ liệu 3 năm tới ước tính bao nhiêu? Có cần sharding/distributed không?
  • Yêu cầu vận hành: Bạn tự vận hành (self-host) hay dùng managed service?

Tình huống thực tế

Tình huống 1: Sàn TMĐT tăng trưởng nóng chọn PostgreSQL thay MongoDB

Một startup thương mại điện tử ở TP.HCM (gọi là "ShopFast") khởi đầu năm 2021 với MongoDB vì đội kỹ thuật thấy "linh hoạt, không cần schema, dev nhanh". Sau 18 tháng, họ gặp cơn ác mộng: mỗi khi khách đặt đơn, hệ thống phải trừ tồn kho, tạo đơn, ghi nhận thanh toán và cập nhật ví khuyến mãi — bốn thao tác này cần nguyên tử. Với MongoDB thời điểm đó, họ phải tự "vá" transaction ở tầng ứng dụng, dẫn đến các lỗi tồn kho âm và đơn ma khi có 3.000 đơn/phút trong đợt sale 12/12.

Đội kiến trúc quyết định migrate phần dữ liệu giao dịch cốt lõi (orders, inventory, payments) sang PostgreSQL, giữ MongoDB cho catalog sản phẩm ít quan hệ. Nhờ ACID transaction đa bảng, lỗi tồn kho âm biến mất. Điểm thú vị: họ tận dụng cột JSONB của PostgreSQL để lưu thuộc tính sản phẩm biến động (màu, size, thông số) — vừa có sự linh hoạt của NoSQL, vừa có transaction mạnh.

Bài học: "Không cần schema" nghe hấp dẫn ở tuần đầu nhưng phản tác dụng khi domain của bạn thực chất đầy quan hệ và cần nhất quán mạnh. SQL nên là mặc định cho dữ liệu giao dịch, và PostgreSQL cho bạn "cửa thoát" JSONB khi cần linh hoạt cục bộ.

Tình huống 2: Doanh nghiệp trên nền .NET chọn SQL Server dù đắt hơn

Một công ty logistics tại Hà Nội xây hệ thống quản lý vận đơn hoàn toàn trên .NET, đội ngũ 12 dev đều thành thạo C# và Entity Framework. Khi ra quyết định database, một kiến trúc sư trẻ đề xuất PostgreSQL để "tiết kiệm license". Trên giấy tờ, tiết kiệm được khoảng vài nghìn USD/năm tiền license SQL Server Standard.

Tuy nhiên hội đồng kiến trúc quyết định giữ SQL Server vì: tích hợp gần như liền mạch với Entity Framework và toolchain Microsoft; SQL Server Management Studio giúp DBA làm việc hiệu quả; và họ đã có cam kết dùng Azure, nơi Azure SQL vận hành trơn tru. Chi phí license được bù lại bằng việc giảm thời gian phát triển và vận hành. Với họ, tổng chi phí sở hữu (TCO) khi tính cả năng suất đội ngũ lại thấp hơn.

Bài học: Quyết định database không tách rời khỏi hệ sinh thái và nhân lực hiện có. "Open source rẻ hơn" là đúng về license nhưng có thể sai về TCO nếu đội bạn phải học lại từ đầu. Hãy tính cả chi phí con người, không chỉ chi phí phần mềm.

Tình huống 3: Nền tảng fintech chọn distributed SQL khi vượt trần một node

Một ví điện tử Đông Nam Á (bối cảnh giả định hợp lý, kiểu Momo/ZaloPay) chạy PostgreSQL đơn khối và rất hài lòng trong 3 năm đầu. Nhưng khi lượng giao dịch chạm mốc 40.000 TPS giờ cao điểm và dữ liệu vượt 15 TB, việc scale dọc (mua server mạnh hơn) chạm trần vật lý và giá tăng phi tuyến. Họ cũng cần triển khai đa vùng (multi-region) để đáp ứng yêu cầu chủ quyền dữ liệu ở nhiều quốc gia.

Sau một giai đoạn PoC (proof of concept), họ chuyển các bảng "nóng" nhất sang distributed SQL (CockroachDB) — vẫn giữ giao diện SQL và ACID, nhưng phân tán qua nhiều node và vùng. Đây là quyết định đắt đỏ và phức tạp, chỉ hợp lý vì họ thực sự đã chạm giới hạn của SQL đơn khối, chứ không phải làm sớm vì "sợ scale".

Bài học: Đừng chọn distributed SQL khi bạn chưa cần. Một PostgreSQL đơn node được tune tốt phục vụ được phần lớn doanh nghiệp Việt Nam nhiều năm. Chỉ leo lên distributed SQL khi bạn có bằng chứng thực tế về việc vượt trần, kèm PoC đàng hoàng.

Hướng dẫn từng bước

Đây là quy trình bạn có thể áp dụng khi cần ra quyết định chọn SQL database cho một dự án mới:

  • Xác nhận SQL là đúng nhóm. Hỏi: dữ liệu có nhiều quan hệ không? Có cần transaction đa bản ghi nhất quán mạnh không? Nếu "có" cho cả hai — SQL là lựa chọn mặc định. (Nếu dữ liệu phi cấu trúc, ghi cực lớn, ưu tiên availability hơn consistency — hãy để dành cho quyết định NoSQL ở Bài 27.)
  • Liệt kê yêu cầu phi chức năng (NFR) liên quan. Ước tính khối lượng dữ liệu 1–3 năm tới, tỉ lệ đọc/ghi, TPS cao điểm, yêu cầu độ trễ, HA/RPO/RTO, ràng buộc chủ quyền dữ liệu. Con số cụ thể quan trọng hơn tính từ.
  • Lập danh sách ứng viên ngắn. Thông thường là PostgreSQL, MySQL/MariaDB, và (nếu ở thế giới Microsoft/Oracle) SQL Server hoặc Oracle. Đừng để danh sách quá dài.
  • Chấm điểm theo tiêu chí. Lập bảng so sánh theo các trục: tính năng cần thiết, chi phí license/hạ tầng, nhân lực địa phương, đặc tính workload, khả năng mở rộng, độ trưởng thành của managed service. Cho trọng số theo mức quan trọng với dự án.
  • Cân nhắc self-host vs managed. Đội bạn có đủ năng lực vận hành DBA không? Nếu không, một managed service (RDS, Cloud SQL, Azure Database) thường đáng giá dù đắt hơn về hạ tầng.
  • Chạy PoC nhỏ với dữ liệu thật. Nạp một tập dữ liệu đại diện, chạy các query nặng nhất, đo latency và throughput. Đừng tin benchmark của người khác — workload của bạn là độc nhất.
  • Viết ADR. Ghi lại bối cảnh, các phương án, tiêu chí, quyết định và hệ quả. (Template cụ thể cho việc chọn database sẽ được đề cập ở Bài 29 — Database Selection ADR.)

Lỗi thường gặp & mẹo

  • Chọn công nghệ vì "hot", không vì bài toán. Việc thấy một công ty lớn dùng X không có nghĩa X hợp với bạn — quy mô và bối cảnh của họ khác bạn hoàn toàn.
  • Đánh giá thấp chi phí migrate về sau. Người ta hay nói "cứ dùng tạm rồi đổi sau". Trên thực tế, đổi database production là dự án hàng tháng trời với rủi ro mất dữ liệu. Chọn cẩn thận từ đầu rẻ hơn nhiều.
  • Quên tính chi phí con người. License chỉ là một phần TCO. Chi phí tuyển, đào tạo, vận hành thường lớn hơn.
  • Nhầm "cần scale khủng" với "sẽ scale khủng". Rất nhiều đội over-engineer, chọn distributed SQL hay sharding từ ngày đầu trong khi một Postgres đơn node dư sức phục vụ vài năm.
  • Bỏ qua connection pooling. Với PostgreSQL, không dùng pooler (PgBouncer) là nguyên nhân số một gây sập dưới tải cao. Đây là mẹo vận hành cực kỳ đáng giá.
  • Mẹo — mặc định là PostgreSQL, và cần lý do để rời đi. Cách tư duy này giúp bạn tránh phân tích quá đà: nếu không có ràng buộc đặc biệt (hệ sinh thái Microsoft, shared hosting MySQL, yêu cầu distributed thật sự), PostgreSQL là điểm khởi đầu an toàn.
  • Mẹo — tận dụng JSONB của PostgreSQL cho các phần dữ liệu bán cấu trúc thay vì vội chạy sang một NoSQL riêng, giúp bạn giữ một hệ thống thay vì hai.

Bài tập thực hành

  • Phân tích tình huống. Bạn được giao thiết kế database cho một hệ thống đặt lịch khám bệnh online tại Việt Nam: có bệnh nhân, bác sĩ, lịch hẹn, thanh toán, và hồ sơ khám (có phần dữ liệu tự do dạng ghi chú). Hãy quyết định: SQL hay NoSQL? Nếu SQL thì chọn cụ thể loại nào? Viết ra 5 tiêu chí bạn dùng và cho điểm từng ứng viên.
  • Lập bảng so sánh. Tạo một bảng so sánh PostgreSQL vs MySQL/MariaDB vs SQL Server theo 6 trục: license/chi phí, tính năng JSON/full-text, hệ sinh thái tại VN, hiệu năng đọc/ghi, managed service, độ dễ tuyển nhân sự. Điền nhận định của bạn vào từng ô.
  • Viết đoạn quyết định. Giả sử bạn là kiến trúc sư của "ShopFast" trong tình huống 1. Viết một đoạn 200 từ giải thích cho CTO vì sao chọn PostgreSQL cho dữ liệu giao dịch, chuẩn bị sẵn để trả lời câu hỏi "Sao không dùng MongoDB cho nhanh?".
  • Ước lượng TCO. Với một startup dự kiến 500 GB dữ liệu và 2.000 TPS cao điểm sau 2 năm, hãy phác thảo chi phí ước tính cho hai phương án: PostgreSQL self-host trên VPS vs Amazon RDS PostgreSQL managed. Liệt kê các hạng mục chi phí bạn cần tính.

Tóm tắt

SQL database nên là lựa chọn mặc định cho phần lớn ứng dụng nghiệp vụ, đặc biệt khi dữ liệu có nhiều quan hệ và cần transaction ACID với nhất quán mạnh. Bạn chỉ nên rời SQL khi có lý do cụ thể, có bằng chứng — chứ không phải vì công nghệ khác đang thời thượng. Trong nhóm SQL, PostgreSQL là điểm khởi đầu hợp lý nhất cho các dự án hiện đại nhờ tính năng phong phú (JSONB, full-text, extension), giấy phép thoáng và độ trưởng thành cao. MySQL/MariaDB tỏa sáng trong hệ sinh thái web phổ biến và khi cần nhân lực dễ tuyển. SQL ServerOracle hợp lý khi bạn đã cắm rễ trong hệ sinh thái tương ứng và giá trị năng suất bù lại chi phí license. Distributed SQL chỉ nên xuất hiện khi bạn thật sự chạm trần của một node.

Quyết định đúng đến từ việc: xác nhận SQL là đúng nhóm, liệt kê NFR bằng con số cụ thể, chấm điểm ứng viên theo tiêu chí có trọng số, cân nhắc self-host vs managed, chạy PoC với dữ liệu thật, và ghi lại tất cả trong một ADR. Nhớ rằng chi phí thật của một quyết định database không nằm ở license, mà ở con người và ở cái giá phải trả nếu bạn phải migrate về sau.