Cơ sở dữ liệu quan hệ và NoSQL: Làm thế nào để chọn nền tảng phù hợp cho hệ thống của bạn
The choice between a relational and a NoSQL database is one of the most consequential architectural decisions you'll make. Get it right and your system scales gracefully. Get it wrong and you'll be fighting your database for years. This is what you actually need to know.
Mọi cơ sở dữ liệu đều lưu trữ dữ liệu. Nhưng đó là điểm tương đồng duy nhất giữa chúng. Cơ sở dữ liệu quan hệ và cơ sở dữ liệu NoSQL thể hiện những triết lý hoàn toàn khác biệt về cách dữ liệu nên được cấu trúc, lưu trữ và truy vấn — và những khác biệt đó lan tỏa đến mọi tầng lớp của các hệ thống được xây dựng dựa trên chúng.
Đây không phải là vấn đề cũ so với mới, hay đơn giản so với phức tạp. Cả hai loại đều chứa các hệ thống hoàn thiện, đã được thử nghiệm thực tế và được sử dụng trên quy mô rất lớn. Vấn đề là sự phù hợp với mục đích: mô hình nào phù hợp với cấu trúc dữ liệu, các mẫu truy cập của ứng dụng và các đảm bảo về tính nhất quán mà người dùng của bạn yêu cầu.
Cơ sở dữ liệu quan hệ thực sự là gì
Cơ sở dữ liệu quan hệ tổ chức dữ liệu thành các bảng — các hàng và cột có mối quan hệ được định nghĩa rõ ràng giữa chúng. Từ "quan hệ" trong tên gọi không ám chỉ việc các bảng có liên quan đến nhau (mặc dù thực tế là vậy), mà ám chỉ khái niệm toán học về quan hệ: một tập hợp các bộ tuple có chung các thuộc tính. Nền tảng lý thuyết này, được phát triển bởi Edgar Codd tại IBM vào năm 1970, đã chứng tỏ tính bền vững đáng kinh ngạc.
Các đặc điểm cốt lõi của cơ sở dữ liệu quan hệ là:
Cấu trúc cố định. Trước khi chèn dữ liệu, bạn phải định nghĩa cấu trúc: các bảng nào tồn tại, mỗi bảng có những cột nào, loại dữ liệu mà mỗi cột chấp nhận, và các ràng buộc nào áp dụng (NOT NULL, UNIQUE, CHECK, v.v.). Cấu trúc này là thỏa thuận giữa ứng dụng của bạn và cơ sở dữ liệu.
Bình thường hóa. Dữ liệu được tổ chức để loại bỏ sự trùng lặp. Tên của một khách hàng chỉ xuất hiện một lần, trong bảng customers. Mỗi đơn hàng tham chiếu đến khách hàng đó bằng ID. Nếu tên thay đổi, nó chỉ thay đổi ở một nơi. Điều này không chỉ là sự gọn gàng — mà còn là sự đảm bảo về tính nhất quán.
Giao dịch ACID. Tính nguyên tử, Tính nhất quán, Tính cách ly và Tính bền vững. Một giao dịch hoặc hoàn tất hoàn toàn hoặc không hoàn tất. Nếu bạn chuyển tiền từ tài khoản này sang tài khoản khác, việc ghi nợ và ghi có sẽ diễn ra cùng lúc hoặc không diễn ra. Cơ sở dữ liệu áp dụng điều này ở cấp độ lõi.
SQL. Ngôn ngữ truy vấn có cấu trúc là giao diện phổ quát cho cơ sở dữ liệu quan hệ. Nó mang tính tuyên bố — bạn mô tả những gì bạn muốn, không phải cách để đạt được nó — và nó có khả năng diễn đạt cực kỳ phong phú. Kết hợp, tổng hợp, hàm cửa sổ, truy vấn con, CTE: toàn bộ phạm vi của SQL cung cấp cho bạn các công cụ để đặt ra những câu hỏi phức tạp về dữ liệu của mình mà không cần viết mã ứng dụng để thực hiện công việc đó.
Các cơ sở dữ liệu quan hệ chính — PostgreSQL, MySQL, SQL Server, Oracle — chia sẻ các đặc tính này nhưng khác nhau về bộ tính năng cụ thể, đặc điểm hiệu suất và mô hình cấp phép. Đặc biệt, PostgreSQL đã trở thành lựa chọn mặc định cho các dự án mới, kết hợp tuân thủ nghiêm ngặt các tiêu chuẩn với bộ tính năng vượt trội.
Cơ sở dữ liệu NoSQL thực sự là gì
"NoSQL" là một thuật ngữ chung bao quát một số loại cơ sở dữ liệu riêng biệt, chủ yếu được thống nhất bởi những gì chúng không phải là: chúng không phải là cơ sở dữ liệu quan hệ và không sử dụng SQL làm giao diện chính (mặc dù một số hỗ trợ các ngôn ngữ truy vấn giống SQL). Thuật ngữ này được hiểu rõ hơn là "không chỉ SQL" — một sự thừa nhận rằng mô hình quan hệ không phải là cách tiếp cận hợp lệ duy nhất.
Các loại NoSQL chính là:
Cơ sở dữ liệu tài liệu lưu trữ dữ liệu dưới dạng tài liệu — thường là JSON hoặc BSON — trong đó mỗi tài liệu có thể có cấu trúc khác nhau. MongoDB là cơ sở dữ liệu được sử dụng rộng rãi nhất; các cơ sở dữ liệu khác bao gồm CouchDB và Firestore. Không có bảng và không có lược đồ cố định; một "bộ sưu tập" tài liệu có thể chứa các bản ghi với các trường hoàn toàn khác nhau.
Cơ sở dữ liệu khóa-giá trị là mô hình đơn giản nhất: mỗi bản ghi là một giá trị có thể truy cập thông qua một khóa duy nhất. Redis là ví dụ tiêu biểu, được sử dụng rộng rãi cho bộ nhớ đệm, lưu trữ phiên và bảng xếp hạng thời gian thực. DynamoDB cũng hoạt động chủ yếu như một cơ sở dữ liệu khóa-giá trị, với các tính năng tài liệu được tích hợp thêm.
Cơ sở dữ liệu theo gia đình cột tổ chức dữ liệu theo cột thay vì theo hàng, cho phép đọc các cột cụ thể một cách cực kỳ hiệu quả trên hàng triệu hàng. Apache Cassandra và HBase là các ví dụ chính. Mô hình này được thiết kế cho các tác vụ có khối lượng ghi lớn, khối lượng dữ liệu cao, nơi các mẫu truy vấn được biết trước.
Cơ sở dữ liệu đồ thị mô hình hóa dữ liệu dưới dạng nút và cạnh — các thực thể và mối quan hệ giữa chúng. Neo4j là ví dụ tiêu biểu. Khi mối quan hệ giữa các thực thể là chủ đề chính của truy vấn — mạng xã hội, hệ thống đề xuất, phát hiện gian lận — cơ sở dữ liệu đồ thị có thể biểu diễn các truy vấn đó một cách tự nhiên, điều mà SQL truyền thống sẽ yêu cầu các câu lệnh lồng nhau phức tạp.
Cơ sở dữ liệu chuỗi thời gian được tối ưu hóa cho dữ liệu được lập chỉ mục theo thời gian: InfluxDB, TimescaleDB, Prometheus. Dữ liệu từ cảm biến, dữ liệu tài chính theo thời gian thực, chỉ số ứng dụng — những trường hợp mà dấu thời gian luôn là khóa chính và các truy vấn theo khoảng thời gian là mô hình truy cập chủ đạo.
Sự khác biệt về cấu trúc định hình mọi thứ
Sự khác biệt sâu sắc nhất giữa cơ sở dữ liệu quan hệ và NoSQL không phải là cú pháp hay quy mô — mà là mối quan hệ giữa cấu trúc dữ liệu và tính linh hoạt của truy vấn.
Cơ sở dữ liệu quan hệ mang lại cho bạn tính linh hoạt tối đa trong truy vấn đổi lại sự tuân thủ sơ đồ từ đầu. Vì dữ liệu được chuẩn hóa và định kiểu, bạn có thể đặt hầu hết mọi câu hỏi về nó tại thời điểm truy vấn. Bạn có thể kết hợp các bảng theo những cách mà bạn không bao giờ ngờ tới khi thiết kế lược đồ. Bạn có thể tổng hợp trên các chiều mà bạn đã thêm vào vài tháng sau thiết kế ban đầu. Lược đồ hạn chế dữ liệu, nhưng ngôn ngữ truy vấn mang lại cho bạn sự tự do.
Cơ sở dữ liệu NoSQL thực hiện sự đánh đổi ngược lại. Chúng mang lại sự linh hoạt trong cách bạn cấu trúc và ghi dữ liệu, đổi lại là các mẫu truy vấn bị hạn chế hơn. Một cơ sở dữ liệu tài liệu cho phép bạn lưu trữ dữ liệu ở bất kỳ định dạng nào mà không cần di chuyển. Nhưng việc truy vấn hiệu quả qua các tài liệu đòi hỏi phải biết trước các mẫu truy cập và thiết kế cấu trúc dữ liệu xung quanh chúng.
Đây là mâu thuẫn cốt lõi: tính linh hoạt của lược đồ so với tính linh hoạt của truy vấn. Bạn có thể có cả hai, nhưng chỉ ở một mức độ nhất định. Mô hình cơ sở dữ liệu bạn chọn phản ánh sự đánh đổi nào là chấp nhận được hơn cho trường hợp sử dụng của bạn.
Định lý CAP và tại sao nó quan trọng
Các hệ thống phân tán không thể đồng thời đảm bảo Tính nhất quán, Tính sẵn sàng và Khả năng chịu lỗi phân vùng — chúng chỉ có thể đạt được tối đa hai trong ba yếu tố này. Đây là định lý CAP, và nó là nền tảng lý thuyết để hiểu tại sao cơ sở dữ liệu quan hệ và NoSQL lại hành xử khác nhau trong các điều kiện lỗi.
Cơ sở dữ liệu quan hệ truyền thống ưu tiên Tính nhất quán và Khả năng chịu phân vùng. Mỗi lần đọc đều phản ánh lần ghi gần nhất. Nếu xảy ra sự cố phân vùng mạng và cơ sở dữ liệu không thể đảm bảo tính nhất quán, nó sẽ từ chối cung cấp dữ liệu cũ — cơ sở dữ liệu sẽ trở nên không khả dụng thay vì không chính xác.
Nhiều cơ sở dữ liệu NoSQL — đặc biệt là những cơ sở dữ liệu được thiết kế để phân tán theo chiều ngang như Cassandra và DynamoDB — ưu tiên tính sẵn sàng và khả năng chịu lỗi phân vùng. Chúng sẽ cung cấp dữ liệu ngay cả khi xảy ra sự cố phân vùng mạng, chấp nhận rằng một số thao tác đọc có thể trả về các giá trị cũ. Đây là "tính nhất quán cuối cùng": tất cả các nút sẽ hội tụ về cùng một giá trị cuối cùng, nhưng có một khoảng thời gian mà chúng có thể không đồng nhất.
Hậu quả thực tế: nếu ứng dụng của bạn không thể chấp nhận việc đọc dữ liệu lỗi thời — số dư tài khoản ngân hàng, số lượng hàng tồn kho, hồ sơ y tế — bạn cần tính nhất quán mạnh. Nếu ứng dụng của bạn có thể chấp nhận sự không nhất quán ngắn hạn để đổi lấy tính sẵn sàng liên tục — như nguồn cấp dữ liệu mạng xã hội, danh mục sản phẩm, hồ sơ người dùng — tính nhất quán cuối cùng là chấp nhận được và mang lại sự linh hoạt trong kiến trúc.
Ví dụ thực tế: khi lựa chọn đúng đắn tạo nên sự khác biệt
GitHub: PostgreSQL là trung tâm của một nền tảng toàn cầu
GitHub vận hành một trong những nền tảng hợp tác phần mềm lớn nhất thế giới trên PostgreSQL — hàng triệu kho lưu trữ, hàng tỷ sự kiện, các truy vấn quan hệ phức tạp liên quan đến người dùng, tổ chức, kho lưu trữ, yêu cầu kéo, vấn đề và bình luận. Mô hình quan hệ phù hợp với lĩnh vực này: mối quan hệ giữa các thực thể này chính là sản phẩm. Một yêu cầu pull thuộc về một kho lưu trữ, được tạo bởi một người dùng, được người dùng khác xem xét, đóng các vấn đề, kích hoạt các đường ống CI.
Trong nhiều năm, GitHub vận hành một phiên bản PostgreSQL chính duy nhất với các bản sao đọc. Khi quy mô mở rộng, họ đã giới thiệu Vitess (một lớp phân mảnh MySQL cho một số khối lượng công việc) và ProxySQL để quản lý kết nối — nhưng cốt lõi quan hệ vẫn được giữ nguyên. Bài học ở đây không phải là PostgreSQL có thể mở rộng vô hạn mà không cần nỗ lực. Mà là mô hình quan hệ phù hợp với một lĩnh vực được định nghĩa bởi các mối quan hệ, và nỗ lực đầu tư vào việc mở rộng nó là xứng đáng, chính xác là vì việc chuyển sang một mô hình dữ liệu khác sẽ tốn kém hơn.
Twitter: quá trình chuyển đổi đầy khó khăn từ MySQL sang kiến trúc hỗn hợp
Twitter bắt đầu với MySQL và phải đối mặt với một cuộc khủng hoảng mở rộng quy mô đã được ghi chép rõ ràng khi sự tăng trưởng người dùng vượt quá khả năng phục vụ của một cơ sở dữ liệu quan hệ duy nhất. Vấn đề cốt lõi là đồ thị xã hội — các mối quan hệ theo dõi/được theo dõi giữa hàng trăm triệu người dùng — và vấn đề phân tán dòng thời gian: khi một người dùng có 10 triệu người theo dõi đăng tweet, tweet đó cần xuất hiện trên 10 triệu dòng thời gian gần như tức thì.
Mô hình quan hệ, như Twitter đã triển khai, không thể xử lý việc phân tán ghi này với tốc độ yêu cầu. Twitter đã di chuyển đồ thị xã hội sang một kho lưu trữ trong bộ nhớ tùy chỉnh và cuối cùng áp dụng Manhattan (kho lưu trữ khóa-giá trị phân tán nội bộ của họ) cho dòng thời gian và Cassandra cho các tác vụ ghi cao khác.
Bài học ở đây khá tinh tế. Dữ liệu cốt lõi của Twitter — tweet, người dùng, mối quan hệ — về cơ bản là quan hệ. Vấn đề không phải là mô hình dữ liệu; mà là khối lượng ghi và fanout ở quy mô đòi hỏi phải phân tán. Việc chuyển đổi tốn kém, phức tạp về mặt kỹ thuật và đòi hỏi nhiều năm đầu tư về mặt kỹ thuật. Ở quy mô của Twitter, đó là quyết định đúng đắn. Ở quy mô của hầu hết các ứng dụng khác, điều đó sẽ là quá sớm.
MongoDB: bài học cảnh tỉnh về tính linh hoạt của lược đồ
Vào đầu thập niên 2010, khi MongoDB ngày càng phổ biến, nhiều đội ngũ đã áp dụng nó chủ yếu vì tính linh hoạt của lược đồ — khả năng bắt đầu lưu trữ dữ liệu mà không cần định nghĩa lược đồ trước. Đối với việc thử nghiệm và phát triển giai đoạn đầu, điều này thực sự đã đẩy nhanh quá trình lặp lại.
Vấn đề nảy sinh khi hệ thống trưởng thành. Không có sự ép buộc cấu trúc, sự không nhất quán trong dữ liệu tích tụ dần dần. Các trường dữ liệu đáng lẽ phải bắt buộc đôi khi lại thiếu. Các giá trị đáng lẽ phải là số nguyên đôi khi lại là chuỗi ký tự. Các truy vấn giả định cấu trúc nhất quán lại trả về kết quả bất ngờ. Các đội ngũ phát triển phải viết các quy tắc xác thực cấp ứng dụng phức tạp mà cơ sở dữ liệu lẽ ra đã tự động thực thi miễn phí.
Đây không phải là thất bại của MongoDB như một cơ sở dữ liệu — nó là công cụ phù hợp cho nhiều trường hợp sử dụng. Đây là thất bại của giả định rằng tính linh hoạt về cấu trúc dữ liệu là tốt một cách vô điều kiện. Tính linh hoạt chỉ trì hoãn chi phí suy nghĩ về cấu trúc dữ liệu; nó không loại bỏ chi phí đó. Các nhóm sử dụng MongoDB mà thiếu kỷ luật đã phải triển khai một phiên bản yếu của cấu trúc quan hệ trong mã ứng dụng, mà không có các đảm bảo mà cơ sở dữ liệu quan hệ sẽ cung cấp.
Amazon DynamoDB: một câu chuyện thành công cho trường hợp sử dụng phù hợp
Giỏ hàng của Amazon là một trong những ví dụ điển hình về việc triển khai NoSQL đúng cách. Các yêu cầu rất rõ ràng: giỏ hàng phải luôn sẵn sàng (khách hàng luôn có thể thêm mặt hàng, ngay cả khi xảy ra sự cố khu vực), phải xử lý khối lượng ghi khổng lồ (hàng trăm triệu người dùng thêm và xóa mặt hàng), và mẫu truy cập đơn giản và được biết trước (luôn truy cập qua ID khách hàng).
Đội ngũ kỹ sư của Amazon, trong bài báo năm 2007 đã truyền cảm hứng cho DynamoDB, đã mô tả việc cố ý chọn tính nhất quán cuối cùng cho giỏ hàng: nếu hai thiết bị thêm mặt hàng đồng thời trong thời gian phân chia mạng, cả hai lần thêm này sẽ được giữ lại khi sự phân chia được khắc phục, ngay cả khi điều đó có nghĩa là trạng thái sẽ tạm thời không nhất quán. Một giỏ hàng luôn có thể ghi — ngay cả khi phải chấp nhận sự không nhất quán tạm thời — có giá trị hơn một giỏ hàng đôi khi không khả dụng.
Thiết kế của DynamoDB xoay quanh trường hợp sử dụng này — truy cập khóa-giá trị đơn giản, các mẫu truy vấn đã biết, tính sẵn sàng hơn tính nhất quán — chính là điều làm nên sự xuất sắc của nó. Các ứng dụng cố gắng sử dụng DynamoDB như một cơ sở dữ liệu quan hệ đa năng, thực hiện các truy vấn phức tạp trên nhiều thực thể, thường gặp khó khăn.
Airbnb: Elasticsearch cho tìm kiếm, PostgreSQL cho dữ liệu chính xác
Tính năng tìm kiếm của Airbnb — lọc danh sách theo vị trí, ngày tháng, giá cả, tiện nghi và tình trạng sẵn có — là một truy vấn mà không cơ sở dữ liệu quan hệ nào có thể xử lý hiệu quả ở quy mô lớn. Sự kết hợp giữa tìm kiếm địa lý, khớp văn bản đầy đủ và lọc đa thuộc tính phức tạp trên hàng triệu danh sách chính xác là trường hợp sử dụng mà Elasticsearch được thiết kế để phục vụ.
Airbnb sử dụng Elasticsearch làm lớp tìm kiếm trong khi duy trì PostgreSQL làm hệ thống lưu trữ chính. Khi một danh sách được cập nhật, thay đổi sẽ được ghi vào PostgreSQL (nguồn dữ liệu chính xác, với các đảm bảo ACID đầy đủ) và sau đó được truyền tải không đồng bộ sang Elasticsearch (chỉ mục tìm kiếm, được tối ưu hóa cho các mẫu truy vấn cụ thể của trải nghiệm tìm kiếm).
Đây là một mô hình kiến trúc đã được chứng minh: sử dụng cơ sở dữ liệu phù hợp cho từng mục đích, duy trì một nguồn dữ liệu chính xác rõ ràng và chấp nhận sự phức tạp trong vận hành khi phải đồng bộ hóa nhiều kho dữ liệu. Mô hình này hoạt động hiệu quả vì ranh giới được xác định rõ ràng và các sự đánh đổi đã được hiểu rõ.

Khi nào nên chọn cơ sở dữ liệu quan hệ
Cơ sở dữ liệu quan hệ là lựa chọn mặc định phù hợp cho hầu hết các ứng dụng. Những trường hợp mà đây rõ ràng là lựa chọn đúng đắn:
Dữ liệu của bạn có các mối quan hệ có ý nghĩa. Nếu các thực thể trong hệ thống của bạn có mối quan hệ quan trọng với nhau — người dùng và bài đăng của họ, đơn hàng và các mặt hàng trong đơn hàng, dự án và các nhiệm vụ của dự án — thì mô hình quan hệ thể hiện trực tiếp các mối quan hệ đó và cho phép bạn truy vấn chúng một cách hiệu quả.
Bạn cần tính nhất quán mạnh mẽ. Giao dịch tài chính, quản lý kho, hệ thống đặt chỗ, hồ sơ y tế — bất kỳ lĩnh vực nào mà việc đọc sai có hậu quả thực tế đều yêu cầu các đảm bảo ACID. Cơ sở dữ liệu quan hệ cung cấp điều này ở cấp độ lõi.
Các mẫu truy vấn của bạn chưa được xác định đầy đủ. Nếu ứng dụng của bạn cần trả lời các câu hỏi về dữ liệu mà bạn không thể dự đoán đầy đủ tại thời điểm thiết kế, tính linh hoạt của SQL là vô cùng quý giá. Khả năng viết truy vấn ad-hoc trên một lược đồ được chuẩn hóa tốt là một tài sản vận hành quan trọng.
Đội ngũ của bạn thành thạo SQL. Điều này nghe có vẻ đơn giản nhưng không phải vậy. SQL là một trong những kỹ năng kỹ thuật được hiểu rộng rãi nhất trong lĩnh vực công nghệ phần mềm. Mọi nhà phát triển bạn tuyển dụng đều sẽ nắm vững nó ở một mức độ nào đó. Kiến thức vận hành — cách thêm chỉ mục, cách đọc kế hoạch truy vấn, cách quản lý sao lưu — đều có sẵn rộng rãi. Hệ sinh thái công cụ đã phát triển hoàn thiện.
Bạn không chắc chắn mình cần gì. Khi còn nghi ngờ, hãy bắt đầu với PostgreSQL. Sẽ dễ dàng hơn để giới thiệu một kho lưu trữ chuyên dụng sau này, một khi bạn hiểu rõ các mẫu truy cập thực tế của mình, hơn là phải di chuyển từ kho tài liệu trở lại mô hình quan hệ khi dữ liệu của bạn hóa ra có cấu trúc hơn bạn nghĩ.
Khi nào nên chọn NoSQL
NoSQL là lựa chọn đúng đắn khi một yêu cầu cụ thể không thể được đáp ứng bởi mô hình quan hệ mà không tốn quá nhiều công sức:
Lượng ghi vượt quá khả năng xử lý của một nút duy nhất. Nếu ứng dụng của bạn cần duy trì hàng trăm nghìn lượt ghi mỗi giây trên hệ thống phân tán địa lý, việc mở rộng theo chiều ngang trên nhiều nút trở nên cần thiết. Các cơ sở dữ liệu theo cột như Cassandra được thiết kế cho mục đích này; cơ sở dữ liệu quan hệ có thể được phân tán nhưng đó không phải là chế độ tự nhiên của chúng.
Dữ liệu của bạn thực sự không có cấu trúc (schema-less) hoặc thay đổi liên tục. Một danh mục sản phẩm nơi các loại sản phẩm có thuộc tính hoàn toàn khác nhau, một hệ thống quản lý nội dung (CMS) nơi các loại nội dung thay đổi nhanh chóng, một hệ thống ghi log nơi cấu trúc sự kiện được định nghĩa bởi các hệ thống bên ngoài — những trường hợp này sẽ được hưởng lợi từ cơ sở dữ liệu tài liệu, nơi cấu trúc không bị cơ sở dữ liệu ép buộc.
Mô hình truy cập chính của bạn là tra cứu khóa-giá trị ở quy mô cực lớn. Các kho lưu trữ phiên, bộ nhớ đệm, bảng xếp hạng thời gian thực, cờ tính năng — các tác vụ nơi bạn luôn truy cập dữ liệu bằng một khóa duy nhất và không bao giờ cần ghép nối hoặc tổng hợp sẽ hưởng lợi từ sự đơn giản và hiệu suất của cơ sở dữ liệu khóa-giá trị.
Bạn đang mô hình hóa một đồ thị. Nếu các truy vấn chính của bạn liên quan đến việc duyệt qua các mối quan hệ — tìm tất cả bạn bè của bạn bè, xác định đường đi ngắn nhất giữa hai nút, phát hiện các phụ thuộc tuần hoàn — một cơ sở dữ liệu đồ thị sẽ diễn đạt các truy vấn đó một cách tự nhiên hơn và thực thi chúng hiệu quả hơn so với SQL đệ quy.
Bạn cần tối ưu hóa chuỗi thời gian. Hàng triệu dữ liệu cảm biến, dữ liệu tài chính hoặc chỉ số ứng dụng mỗi giây, với các truy vấn chủ yếu trên các khoảng thời gian, sẽ được phục vụ tốt hơn bởi một cơ sở dữ liệu chuỗi thời gian chuyên dụng hơn là một cơ sở dữ liệu quan hệ có cột thời gian.
Thực tế đa cơ sở dữ liệu
Điều quan trọng nhất cần hiểu về câu hỏi "cơ sở dữ liệu quan hệ so với NoSQL" là trong hầu hết các hệ thống đã phát triển, đây không phải là sự lựa chọn "hoặc là... hoặc là". Các hệ thống quy mô lớn thường sử dụng nhiều cơ sở dữ liệu, mỗi loại được chọn cho khối lượng công việc cụ thể mà nó phục vụ.
PostgreSQL cho hệ thống lưu trữ chính. Redis cho bộ nhớ đệm phiên và giới hạn tốc độ. Elasticsearch cho tìm kiếm văn bản đầy đủ. InfluxDB cho chỉ số ứng dụng. Mỗi cơ sở dữ liệu trong hệ thống này đều thực hiện tốt nhất chức năng của mình, và lớp ứng dụng quản lý tính nhất quán giữa chúng.
Chi phí vận hành của sự phức tạp này là có thật. Mỗi cơ sở dữ liệu bổ sung là một hệ thống cần theo dõi, sao lưu, mở rộng quy mô và hiểu rõ. Kỷ luật kỹ thuật cần thiết để duy trì tính nhất quán giữa nhiều cơ sở dữ liệu — xử lý các tình huống lỗi như khi một lệnh ghi vào PostgreSQL thành công nhưng cập nhật Elasticsearch sau đó thất bại — là không hề đơn giản.
Điểm khởi đầu cho hầu hết mọi ứng dụng nên là một cơ sở dữ liệu quan hệ duy nhất. Chỉ nên thêm các cơ sở dữ liệu chuyên dụng khi một yêu cầu cụ thể, đã được hiểu rõ không thể đáp ứng được nếu thiếu chúng. Việc đa dạng hóa cơ sở dữ liệu quá sớm là một hình thức tối ưu hóa sớm: nó thêm sự phức tạp trước khi bạn hiểu liệu sự phức tạp đó có cần thiết hay không.

Quyết định lựa chọn
Các câu hỏi thực sự quan trọng khi chọn cơ sở dữ liệu:
Yêu cầu về tính nhất quán của bạn là gì? Nếu câu trả lời cho câu hỏi "điều gì sẽ xảy ra nếu người dùng đọc dữ liệu cũ" là "đó là một vấn đề nghiêm trọng", thì bạn cần ACID. Nếu câu trả lời là "điều đó hơi khó chịu nhưng có thể chấp nhận được", thì bạn có nhiều lựa chọn.
Mô hình truy vấn của bạn là gì? Nếu bạn biết chính xác cách dữ liệu của bạn sẽ được truy cập và mô hình truy cập đó đơn giản và có khối lượng lớn, bạn có thể tối ưu hóa cho nó. Nếu mô hình truy cập của bạn phức tạp hoặc chưa được biết đầy đủ, tính linh hoạt của SQL sẽ rất có giá trị.
Khối lượng ghi của bạn là bao nhiêu? Đối với đại đa số các ứng dụng, một phiên bản PostgreSQL được điều chỉnh tốt trên phần cứng hợp lý có thể xử lý hàng nghìn lần ghi mỗi giây mà không gặp khó khăn. Những trường hợp mà điều này thực sự không đủ là hiếm hơn so với những gì mà cơn sốt NoSQL của những năm 2010 đã gợi ý.
Dữ liệu của bạn có cấu trúc như thế nào? Dữ liệu đồng nhất cao, có mối quan hệ chặt chẽ phù hợp với mô hình quan hệ. Dữ liệu biến đổi cao, có mối quan hệ lỏng lẻo có thể phù hợp hơn với mô hình tài liệu.
Đội ngũ của bạn biết gì? Sự quen thuộc trong vận hành rất quan trọng. Một đội ngũ am hiểu sâu về PostgreSQL sẽ xây dựng được hệ thống đáng tin cậy hơn trên PostgreSQL so với trên cơ sở dữ liệu NoSQL mà họ đang học, ngay cả khi cơ sở dữ liệu NoSQL đó về mặt lý thuyết phù hợp hơn.
Cơ sở dữ liệu quan hệ đã tồn tại qua 50 năm thay đổi công nghệ không phải vì nó luôn là công cụ tốt nhất, mà vì nó là một lựa chọn mặc định xuất sắc — linh hoạt, đáng tin cậy, được hiểu rõ và được hỗ trợ bởi hàng thập kỷ kiến thức vận hành. Hãy rời xa nó một cách có chủ đích, với sự hiểu biết rõ ràng về những gì bạn đạt được và những gì bạn phải hy sinh.