LỰA CHỌN CƠ SỞ DỮ LIỆU PHÙ HỢP TRONG THIẾT KẾ HỆ THỐNG LỚN
Bài viết rất dài, hãy pha một tách trà hoặc cafe nhâm nhi để có sự tập trung cao độ nhé.
1. Mở đầu
Xin chào anh em! Hôm nay chúng ta sẽ nói về cơ sở dữ liệu. Trong quá trình thiết kế hệ thống, mức độ tốt của thiết kế và khả năng mở rộng của hệ thống phụ thuộc rất nhiều vào sự lựa chọn cơ sở dữ liệu mà bạn sử dụng. Thông thường, cơ sở dữ liệu không ảnh hưởng đến các yêu cầu chức năng của bạn, nghĩa là bạn có thể đáp ứng các yêu cầu chức năng bằng bất kỳ cơ sở dữ liệu nào. Nhưng các yêu cầu phi chức năng (NFRs) lại bị ảnh hưởng bởi sự lựa chọn cơ sở dữ liệu. Ví dụ, nếu bạn có các mô hình truy vấn nhất định, kiểu dữ liệu cụ thể hoặc cần xử lý một lượng lớn dữ liệu, thì sẽ có những loại cơ sở dữ liệu tối ưu hơn cho từng tình huống đó. Vì vậy, dựa trên lựa chọn cơ sở dữ liệu, nó sẽ ảnh hưởng đến khả năng thiết kế của bạn có thể mở rộng theo yêu cầu phi chức năng như thế nào. Trong bài viết này, chúng ta sẽ xem qua một số tình huống sử dụng phổ biến mà bạn có thể gặp phải trong quá trình thiết kế hệ thống, và xem xét các giải pháp tiềm năng hoặc tập hợp các cơ sở dữ liệu mà bạn có thể sử dụng để xử lý những tình huống đó. Thông thường, sự lựa chọn cơ sở dữ liệu phụ thuộc vào một số yếu tố.
- Yếu tố đầu tiên là cấu trúc dữ liệu của bạn, liệu nó có phải là dữ liệu rất có cấu trúc hay hoàn toàn không có cấu trúc.
- Yếu tố tiếp theo là mô hình truy vấn mà bạn có.
- Và một yếu tố khác nữa là lượng quy mô (scale) mà bạn cần xử lý. Tất cả ba yếu tố này sẽ ảnh hưởng đến lựa chọn cơ sở dữ liệu mà bạn muốn sử dụng.
2. Caching Database
Trong bài viết này, chúng ta sẽ xem xét một số trường hợp phổ biến ngay từ đầu, và sau đó chúng ta sẽ so sánh giữa SQL và NoSQL cũng như cách kết hợp các loại cơ sở dữ liệu để giải quyết vấn đề thực tế. Bây giờ, hãy nói về các giải pháp caching. Trong bất kỳ hệ thống nào mà bạn thiết kế, bạn sẽ chắc chắn cần phải sử dụng một số giải pháp caching. Có rất nhiều trường hợp cần caching. Giả sử bạn đang truy vấn một cơ sở dữ liệu và không muốn truy vấn nhiều lần, bạn có thể lưu giá trị vào một cache. Hoặc nếu bạn đang thực hiện một cuộc gọi từ xa đến một dịch vụ khác và dịch vụ đó có độ trễ cao, bạn có thể muốn lưu trữ tạm thời kết quả trả về của dịch vụ đó tại hệ thống của mình. Có rất nhiều trường hợp sử dụng caching. Thông thường, caching hoạt động theo cơ chế key-value, trong đó key thường là điều kiện where trong truy vấn hoặc các tham số của yêu cầu (request params) khi bạn thực hiện một cuộc gọi API, còn value là kết quả mà bạn mong đợi từ hệ thống khác. Các giá trị này thường được lưu trữ trong các kho key-value. Những giải pháp phổ biến là Redis, Memcached, hoặc etcd. "Hazelcast" cũng đang dần trở nên phổ biến hơn. Bạn có thể sử dụng bất kỳ giải pháp nào trong số đó. Trong các kiến trúc mà mình từng triển khai, mình thường sử dụng Redis vì đó là một giải pháp đã được kiểm chứng và được các công ty lớn trên toàn thế giới sử dụng, rất ổn định. Vì vậy, trong bất kỳ thiết kế hệ thống nào mà bạn cần sử dụng giải pháp caching, bạn có thể dùng Redis. Điều này không có nghĩa là bạn không thể sử dụng bất kỳ giải pháp nào khác; bạn có thể sử dụng bất kỳ giải pháp tương tự nào khác và nó cũng sẽ hoạt động tốt.
3. File Storage
Tiếp theo, chúng ta sẽ xem xét một số tùy chọn lưu trữ tệp. Giả sử bạn đang thiết kế một hệ thống như Amazon, nơi bạn bán nhiều sản phẩm khác nhau. Các người bán có thể sẽ tải lên hình ảnh sản phẩm, có thể cả video sản phẩm nữa, đúng không? Bạn cần một kho dữ liệu để lưu trữ những hình ảnh và video đó. Tương tự, bạn cũng có thể đang xây dựng một hệ thống như Netflix với các video, và bạn cần một hệ thống lưu trữ để hỗ trợ video. Bất cứ khi nào bạn cần lưu trữ hình ảnh/video, chúng ta sẽ sử dụng cái gọi là Blob Storage. Đây không thực sự là cơ sở dữ liệu, vì cơ sở dữ liệu cơ bản là dành cho các đối tượng mà bạn có thể truy vấn. Một tệp (file) thì không phải là thứ bạn thường xuyên truy vấn; bạn sẽ chỉ phục vụ nó như nó vốn có. Blob Storages được sử dụng trong các trường hợp này. Có rất nhiều nhà cung cấp Blob Storage, và một trong những lựa chọn phổ biến nhất, với chi phí khá hợp lý, là Amazon S3. Đây là một hệ thống rất tốt và được sử dụng bởi rất nhiều công ty. Bất cứ khi nào bạn cần lưu trữ hình ảnh/video hoặc bất kỳ nội dung tương tự nào, bạn có thể sử dụng Amazon S3 như một kho dữ liệu. Cùng với S3, bạn có thể muốn sử dụng cái gọi là Content Delivery Network (CDN). CDN thường được sử dụng để phân phối cùng một hình ảnh đến nhiều vị trí địa lý khác nhau. Lấy ví dụ đơn giản, bạn có một hình ảnh sản phẩm được lưu trữ trong Amazon S3 như nguồn dữ liệu chính, và có rất nhiều người từ khắp nơi trên thế giới truy cập vào sản phẩm đó. Bạn có thể muốn phân phối hình ảnh đó đến các máy chủ ở nhiều nơi khác nhau trên thế giới để mọi người có thể truy vấn nó nhanh hơn so với việc truy vấn trực tiếp từ S3, vốn có thể chỉ nằm ở một vài địa điểm. Vì vậy, đối với tất cả các nội dung dạng Blob (như hình ảnh, video), bạn sẽ sử dụng Amazon S3 kết hợp với một CDN và điều này sẽ phù hợp với hầu hết các bài toán của bạn.
4. Search Engine
Tiếp theo là một tình huống sử dụng rất phổ biến khác, chẳng hạn nếu bạn đang xây dựng một sản phẩm như Amazon và cần cung cấp khả năng tìm kiếm văn bản trên các sản phẩm khác nhau. Người bán có thể tải lên một sản phẩm với tiêu đề cụ thể, mô tả sản phẩm, và bạn muốn người dùng có thể tìm kiếm dựa trên các thông tin đó. Một số trường hợp sử dụng tương tự là nếu bạn đang xây dựng một sản phẩm như Netflix, nơi người dùng có thể tìm kiếm tên phim, thể loại, diễn viên và đoàn làm phim. Hoặc bạn có thể đang thiết kế một hệ thống như Uber hoặc Google Maps, nơi bạn muốn cung cấp khả năng tìm kiếm văn bản với hỗ trợ tìm kiếm mờ (fuzzy search). Đối với tất cả các trường hợp sử dụng này, bạn sẽ sử dụng cái gọi là Text Search Engine (Công cụ tìm kiếm văn bản). Một triển khai phổ biến của Text Search Engine được cung cấp bởi ElasticSearch và Solr, cả hai đều được xây dựng dựa trên Apache Lucene. Lucene cung cấp các khả năng tìm kiếm văn bản và được cả ElasticSearch và Solr sử dụng. Vậy, một trường hợp sử dụng tiếp theo chính là tìm kiếm văn bản, sử dụng ElasticSearch hoặc Solr. Ngoài ra, cả hai công cụ này đều hỗ trợ cái gọi là tìm kiếm mờ (Fuzzy Search). Fuzzy Search là gì? Hãy nhanh chóng xem qua. Giả sử bạn tìm kiếm từ "Airport" nhưng người dùng gõ sai chính tả thành "AIRPROT" (chữ O và R bị đảo vị trí). Nếu bạn không trả về kết quả nào, thì đó là một trải nghiệm người dùng không tốt, đúng không? Vậy nên bạn cần cơ sở dữ liệu của mình có khả năng xác định rằng người dùng không thực sự muốn nhập từ "AIRPROT", mà họ thực sự muốn nhập từ "AIRPORT", đúng không? Làm thế nào để cơ sở dữ liệu nhận ra điều này? Từ này có thể được chuyển đổi thành cách viết đúng của từ "airport" bằng cách thay đổi hai ký tự, đúng không? Chữ R cần được chuyển thành O và chữ O cần được chuyển thành R. Bạn có thể cung cấp mức độ "mờ" mà công cụ tìm kiếm của bạn cần hỗ trợ. Trường hợp này có mức độ mờ là 2, tức là Edit Distance. Thông thường, còn có nhiều yếu tố khác tham gia, nhưng đây là cách mà tìm kiếm mờ (fuzzy search) được triển khai trong hầu hết các giải pháp. Vì vậy, bất cứ khi nào bạn có các khả năng tìm kiếm, bạn sẽ sử dụng hoặc ElasticSearch hoặc Solr. Một điều rất quan trọng về cả hai công cụ này là chúng không phải là cơ sở dữ liệu. Chúng là các công cụ tìm kiếm. Sự khác biệt giữa một công cụ tìm kiếm và một cơ sở dữ liệu là bất cứ khi nào bạn ghi dữ liệu vào một cơ sở dữ liệu, cơ sở dữ liệu đảm bảo rằng dữ liệu đó sẽ không bị mất. Cả hai hệ thống này không đảm bảo điều đó. Chúng tuyên bố rằng chúng cung cấp khả năng sẵn sàng và tính dư thừa (redundancy) đủ tốt, nhưng về lý thuyết, dữ liệu có thể bị mất, vì vậy bạn không nên sử dụng chúng như nguồn dữ liệu chính của bạn. Nguồn dữ liệu chính của bạn nên được lưu trữ ở một nơi khác, và sau đó bạn có thể tải dữ liệu vào một trong hai hệ thống này để cung cấp khả năng tìm kiếm, và cả hai hệ thống này rất hiệu quả trong việc tìm kiếm.
5. Time Series
Tiếp theo, hãy xem bạn nên làm gì nếu bạn muốn lưu trữ một loại dữ liệu liên quan đến metrics. Ví dụ, nếu bạn đang xây dựng một hệ thống như Graphite, Grafana hoặc Prometheus, về cơ bản là một hệ thống theo dõi các metrics ứng dụng. Ví dụ, nếu bạn có tình huống sử dụng là nhiều ứng dụng đang đẩy các metrics liên quan đến thông lượng (throughput), mức sử dụng CPU, độ trễ, v.v., và bạn muốn xây dựng một hệ thống để hỗ trợ điều đó. Đó là khi một thứ gọi là Time Series Database xuất hiện. Hãy tưởng tượng Time Series Database là một mở rộng của cơ sở dữ liệu quan hệ, nhưng không có tất cả các chức năng và có một số chức năng bổ sung. Các cơ sở dữ liệu quan hệ thông thường cho phép bạn cập nhật nhiều bản ghi hoặc thực hiện các truy vấn ngẫu nhiên. Nhưng khi bạn đang xây dựng một hệ thống giám sát metrics, bạn sẽ không thực hiện cập nhật ngẫu nhiên. Bạn sẽ luôn thực hiện cập nhật tuần tự chỉ ở chế độ thêm (append-only mode). Nếu bạn đưa một mục vào tại thời điểm T1, mục tiếp theo sẽ là thời điểm T2, lớn hơn T1. Mục tiếp theo sẽ là thời điểm T3, lớn hơn cả T1 và T2. Vì vậy, đó là append-only mode. Ngoài ra, các truy vấn đọc của bạn sẽ là các truy vấn đọc hàng loạt với khoảng thời gian, ví dụ như bạn truy vấn dữ liệu của vài phút, vài giờ hoặc vài ngày gần đây. Bạn không thực hiện đọc ngẫu nhiên hay cập nhật ngẫu nhiên. Time Series Database được tối ưu hóa cho loại mô hình truy vấn và đầu vào này. Có rất nhiều cơ sở dữ liệu tương tự như InfluxDBhoặc OpenTSDB, vì vậy bạn có thể sử dụng một trong số chúng nếu có tình huống sử dụng đó. Đối với time series, bạn sử dụng cái gọi là OpenTSDB, viết tắt của Open Time Series Database. Tiếp theo là tình huống sử dụng khi bạn có rất nhiều thông tin và bạn muốn lưu trữ tất cả thông tin của công ty trong một loại kho dữ liệu nhất định để phục vụ cho các yêu cầu phân tích khác nhau. Hãy lấy ví dụ về một hệ thống như Amazon hoặc Uber, nơi bạn muốn cung cấp các phân tích về tất cả các giao dịch. Bạn có thể muốn cung cấp phân tích về số lượng đơn hàng, doanh thu ở từng khu vực địa lý, hoặc sản phẩm nào được ưa chuộng nhất, v.v. Trong trường hợp này, bạn cần một hệ thống như Data Warehouse (kho dữ liệu). Điều này về cơ bản là một cơ sở dữ liệu lớn trong đó bạn có thể đổ tất cả dữ liệu vào và cung cấp các khả năng truy vấn trên dữ liệu đó để phục vụ cho nhiều báo cáo khác nhau. Những hệ thống này thường không được sử dụng cho các hệ thống giao dịch, mà thường được dùng cho báo cáo ngoại tuyến. Vì vậy, nếu bạn có trường hợp sử dụng như vậy, bạn có thể sử dụng một hệ thống như Hadoop, rất phù hợp cho mục đích đó, nơi bạn đưa vào rất nhiều dữ liệu từ các hệ thống giao dịch khác nhau và sau đó xây dựng các hệ thống có thể cung cấp báo cáo dựa trên dữ liệu đó.
6. Case Study
Bây giờ, hãy xem các tình huống phức tạp hơn, nơi bạn có thể cần chọn giữa cơ sở dữ liệu quan hệ và cơ sở dữ liệu phi quan hệ. Điều đầu tiên giúp bạn quyết định sử dụng loại cơ sở dữ liệu nào là cấu trúc của dữ liệu. Nếu bạn có thông tin rất có cấu trúc thì có thể cơ sở dữ liệu quan hệ là lựa chọn hợp lý. Thế nào là thông tin có cấu trúc? Đó là loại thông tin mà bạn có thể dễ dàng mô hình hóa dưới dạng bảng, trong đó các bảng sẽ có các hàng và cột chứa thông tin. Ví dụ, nếu bạn muốn lưu trữ thông tin người dùng, chẳng hạn như hồ sơ người dùng trên mạng xã hội, nó sẽ bao gồm tên, địa chỉ email, thành phố, số điện thoại và một loạt các thông tin chuẩn mà mỗi người dùng sẽ có. Đó là thông tin có cấu trúc.
Vì vậy, nếu chúng ta cố gắng tạo ra một biểu đồ luồng (flowchart) về cách quyết định sử dụng cơ sở dữ liệu nào, thì đây là cách nó sẽ trông như thế nào. Lựa chọn đầu tiên chúng ta cần đưa ra là liệu chúng ta có dữ liệu có cấu trúc hay dữ liệu phi cấu trúc. Giả sử nếu chúng ta có dữ liệu có cấu trúc, câu hỏi tiếp theo mà chúng ta cần tự hỏi là liệu chúng ta có cần bất kỳ tính chất nguyên tử nào hoặc các đảm bảo giao dịch từ cơ sở dữ liệu hay không? Ví dụ, giả sử bạn đang xây dựng một hệ thống thanh toán hỗ trợ tính năng cho phép ai đó chuyển tiền từ tài khoản của họ sang tài khoản của người khác. Ở lõi của nó, hệ thống sẽ có hai truy vấn: một truy vấn sẽ giảm số tiền từ tài khoản của người gửi và truy vấn còn lại sẽ thêm số tiền vào tài khoản của người nhận. Về cơ bản là giảm từ tài khoản A và thêm vào tài khoản B. Bây giờ, cơ sở dữ liệu của bạn nên cung cấp cho bạn các đảm bảo rằng cả hai truy vấn này đều được gói trong một giao dịch, đảm bảo rằng hoặc cả hai truy vấn sẽ được thực hiện hoặc không truy vấn nào được thực hiện. Nhưng không bao giờ được xảy ra tình trạng số tiền đã bị trừ từ tài khoản A nhưng không được cộng vào tài khoản B, hoặc được cộng vào tài khoản A nhưng không bị trừ từ tài khoản B. Điều đó không nên xảy ra. Ngoài ra, nó cũng nên cung cấp cho bạn tính nhất quán, nghĩa là nếu bạn đã thực hiện giao dịch, lần truy vấn tiếp theo để lấy số dư tài khoản phải phản ánh số tiền đã thay đổi. Nó không nên xảy ra tình trạng đôi khi hiển thị số tiền đúng và đôi khi không hiển thị đúng.
Nếu bạn có loại yêu cầu như vậy, chẳng hạn như khi bạn đang xây dựng một hệ thống thanh toán hoặc một hệ thống quản lý kho hàng, nơi bạn cần theo dõi số lượng sản phẩm khi người dùng mua và số lượng cần phải giảm, thì những tình huống như vậy đòi hỏi tính nguyên tử, tính nhất quán, và tính giao dịch. Trong những trường hợp này, bạn cần sử dụng cơ sở dữ liệu quan hệ. Hiện có nhiều nhà cung cấp cơ sở dữ liệu quan hệ, bạn có thể sử dụng bất kỳ nhà cung cấp nào. Một số cơ sở dữ liệu phổ biến là MySQL, Oracle, SQL Server, Postgres, và còn nhiều loại khác nữa. Mình chỉ liệt kê những cái phổ biến, nhưng điều đó không có nghĩa là bạn không thể sử dụng bất kỳ cơ sở dữ liệu nào khác mà bạn thích. Hãy thoải mái sử dụng bất kỳ cơ sở dữ liệu nào cung cấp các đảm bảo ACID.
Giờ giả sử bạn có dữ liệu quan hệ nhưng không cần các đảm bảo ACID. Ví dụ, bạn chỉ đang lưu trữ thông tin người dùng mà không có bất kỳ yêu cầu nào về tính nguyên tử. Bạn vẫn có thể chọn sử dụng cơ sở dữ liệu quan hệ hoặc cơ sở dữ liệu phi quan hệ, và sẽ không có sự khác biệt lớn lắm, bởi vì thông thường, bạn có thể dễ dàng ánh xạ dữ liệu có cấu trúc vào một mô hình NoSQL, vì vậy bất kỳ kịch bản nào cũng đều ổn. Bây giờ, giả sử bạn không có dữ liệu có cấu trúc - vậy bạn sẽ làm gì? Có một loạt kịch bản mà trong đó trường hợp sử dụng của bạn có thể phù hợp. Có thể bạn đang cố gắng xây dựng một hệ thống danh mục cho một nền tảng thương mại điện tử như Amazon, nơi có thông tin về tất cả các mặt hàng có sẵn trên nền tảng đó. Giả sử bạn đang xây dựng danh mục cho Amazon và chúng ta lấy một số ví dụ, như áo sơ mi. Mỗi mặt hàng sẽ có các thuộc tính nhất định. Một chiếc áo sơ mi có thể có thuộc tính như kích cỡ: lớn, màu sắc: đỏ, v.v. Nếu bạn có một cái tủ lạnh, nó sẽ có dung tích như 200 lít/400 lít hoặc gì đó, cũng có chế độ tiết kiệm điện như 3 sao/5 sao, v.v. Đó là các thuộc tính của một chiếc tủ lạnh. Tương tự, một mặt hàng như sữa sẽ có thuộc tính số lượng và ngày hết hạn.
Thông thường khi bạn ở trên một nền tảng thương mại điện tử, bạn không chỉ cần xem các thuộc tính này. Nếu chỉ để xem chúng, bạn có thể lưu trữ dưới dạng JSON và lưu nó vào bất kỳ cơ sở dữ liệu nào. Nhưng thường bạn cũng muốn truy vấn các thuộc tính này. Việc truy vấn trên JSON hoặc các thuộc tính ngẫu nhiên hơi phức tạp trên các cơ sở dữ liệu quan hệ, nhưng có một số loại cơ sở dữ liệu được tối ưu hóa cho những loại truy vấn này. Đây là các cơ sở dữ liệu mà bạn có không chỉ nhiều dữ liệu về mặt số lượng mà còn về mặt cấu trúc. Nếu bạn có nhiều thuộc tính và nhiều loại truy vấn khác nhau, bạn sẽ rơi vào loại này, và nếu đó là trường hợp, bạn cần sử dụng cái gọi là Document DB. Có rất nhiều nhà cung cấp Document DB, như MongoDB, Couchbase. Trước đó, chúng ta đã nhắc tới Elastic Search và Solr để tìm kiếm văn bản, và chúng cũng là những trường hợp đặc biệt của Document Database.
Giả sử dữ liệu của bạn không phải là quan hệ và bạn không có các truy vấn phức tạp, chỉ có một vài truy vấn đơn giản, bạn vẫn có thể sử dụng Document DB nếu không rơi vào trường hợp thứ ba. Vậy trường hợp thứ ba là gì? Giả sử bạn có dữ liệu ngày càng gia tăng. Ý mình là gì khi nói về dữ liệu ngày càng gia tăng? Lấy ví dụ của Uber. Tất cả các tài xế của Uber liên tục gửi tọa độ vị trí của họ. Giả sử có một số lượng tài xế và họ gửi X tọa độ vị trí mỗi ngày. Vậy sẽ có X bản ghi được nhập vào mỗi ngày. Nhưng con số X này không phải là một hằng số, mà là một con số đang tăng lên, vì số lượng tài xế của Uber đang tăng theo từng ngày, đúng không? Vì vậy, dữ liệu này sẽ tăng, có thể là X vào ngày một, tăng thêm 1.1X vào ngày hai, 1.2X vào ngày ba, và cứ thế. Vì vậy, nó không tăng theo cách tuyến tính mà tăng theo một cách không tuyến tính. Đó là điều mình gọi là dữ liệu ngày càng gia tăng. Cộng với việc bạn chỉ có một số lượng loại truy vấn hạn chế. Giả sử nếu bạn muốn theo dõi tọa độ vị trí của tài xế, truy vấn quan trọng nhất mà bạn sẽ thực hiện là tìm tất cả các tọa độ của tài xế với mã tài xế là gì đó. Vì vậy, nếu bạn có số lượng truy vấn ít (có thể có khối lượng lớn) nhưng lượng dữ liệu lớn, thì loại cơ sở dữ liệu này sẽ là lựa chọn tốt nhất cho bạn. Đây được gọi là cơ sở dữ liệu dạng cột (Columnar DB) hoặc cơ sở dữ liệu định hướng cột, và Cassandra và HBase là những lựa chọn phổ biến và ổn định nhất cho các kịch bản này.
Bây giờ, nếu bạn không có bất kỳ yêu cầu nào trong số này - bạn không cần ACID, không có các loại dữ liệu và truy vấn đa dạng, và bạn cũng không có dữ liệu ngày càng gia tăng - thì bạn có thể sử dụng bất kỳ cơ sở dữ liệu nào mà bạn muốn. Điều này sẽ là một hệ thống có quy mô nhỏ, có một số lượng truy vấn rất nhỏ trên một số ít thuộc tính và trên một tập dữ liệu rất nhỏ. Bạn thường sẽ không gặp những yêu cầu như vậy trong một vài dự án, nhưng nếu bạn gặp, bạn có thể sử dụng bất kỳ cơ sở dữ liệu nào, trừ khi đó là một trong các trường hợp đặc biệt mà chúng ta đã nói đến. Vì vậy, nếu không có yêu cầu đặc biệt, bạn có thể sử dụng bất kỳ cơ sở dữ liệu nào trong số này và điều đó sẽ ổn. Nhưng thông thường, khi bạn đang thiết kế hệ thống, bạn sẽ không dễ dàng hài lòng với việc chỉ sử dụng một cơ sở dữ liệu duy nhất. Hãy xem xét các tình huống thực tế phức tạp hơn một chút.
Bây giờ, lấy ví dụ về việc chúng ta xây dựng một nền tảng thương mại điện tử, chẳng hạn như Amazon. Khi bạn đang quản lý hàng tồn kho, bạn muốn đảm bảo rằng mình không bán quá nhiều sản phẩm. Giả sử chỉ còn một sản phẩm của một mặt hàng cụ thể và có 10 người dùng muốn mua nó, bạn sẽ muốn áp dụng các tính chất ACID ở đây để đảm bảo rằng chỉ một trong số các người dùng có thể hoàn tất giao dịch, còn các người dùng khác thì không, đúng không? Bạn có thể đặt ra các ràng buộc và mọi thứ khác ở đó. Sẽ hợp lý nếu sử dụng cơ sở dữ liệu RDBMS cho hệ thống quản lý hàng tồn kho hoặc hệ thống quản lý đơn hàng của Amazon chẳng hạn.
Nhưng nếu bạn nhìn vào dữ liệu của Amazon, nó là dữ liệu ngày càng gia tăng. Tại sao? Vì số lượng đơn hàng tăng thêm mỗi ngày, các đơn hàng mới luôn xuất hiện và Amazon không thể xóa bỏ dữ liệu do nhiều lý do pháp lý. Đồng thời, số lượng đơn hàng cũng ngày càng tăng lên. Vì vậy, nó phù hợp với mô hình mà tôi đã đề xuất khi sử dụng Cassandra. Bạn có thể sử dụng kết hợp cả hai cơ sở dữ liệu này. Bạn có thể dùng MySQL hoặc bất kỳ RDBMS nào khác để lưu trữ dữ liệu về các đơn hàng vừa được đặt và chưa giao cho khách hàng. Sau khi mặt hàng được giao cho khách hàng, bạn có thể chuyển dữ liệu từ RDBMS sang Cassandra để lưu trữ lâu dài.
Bây giờ, hãy xem một ví dụ khác. Lấy lại ví dụ của Amazon, giả sử bạn muốn xây dựng một hệ thống báo cáo cho phép bạn truy vấn xem ai đã mua đường trong 5 ngày qua. Đường không chỉ là một sản phẩm, có rất nhiều người bán cung cấp các loại đường khác nhau của các công ty khác nhau với chất lượng khác nhau. Vì vậy, đường sẽ có rất nhiều ID sản phẩm khác nhau, và trên những ID sản phẩm đó sẽ có rất nhiều đơn hàng. Một lần nữa, mình đang nói rằng các đơn hàng sẽ nằm trong Cassandra hoặc RDBMS. Nhưng nếu bạn đang thực hiện các truy vấn ngẫu nhiên như ai đã mua đường, ai đã mua TV, ai đã mua TV với chất lượng nhất định, hoặc ai đã mua tủ lạnh với chất lượng cụ thể, thì điều này phù hợp với mô hình mà mình đề xuất sử dụng Document DB. Bạn có thể lưu trữ phần truy vấn trên Document DB. Bạn có thể lưu trữ một tập con của thông tin đơn hàng vào MongoDB, chẳng hạn như: người dùng có mã ID cụ thể, đã đặt một đơn hàng với mã ID nào đó vào một ngày cụ thể, với 10 mã sản phẩm khác nhau và số lượng tương ứng. Trên cơ sở dữ liệu này, bạn có thể thực hiện truy vấn để trả về danh sách người dùng và danh sách đơn hàng. Sau đó, bạn có thể lấy các mã đơn hàng đó và truy vấn trên cả hai hệ thống (RDBMS + Cassandra). Ở đây, chúng ta đang sử dụng cả ba hệ thống kết hợp với nhau để cung cấp các khả năng truy vấn đa dạng, ví dụ như ai đã mua cái gì. Vì vậy, trong bất kỳ tình huống thực tế nào, bạn sẽ cần sử dụng sự kết hợp của các cơ sở dữ liệu để đáp ứng các yêu cầu chức năng và phi chức năng mà bạn có.
7. Kết luận
Mình khuyến nghị bạn nên tìm hiểu thêm để chọn chính xác loại cơ sở dữ liệu nào phù hợp. Ngoài ra, có rất nhiều cơ sở dữ liệu khác mà mình chưa đề cập đến, chúng là các ví dụ về RDBMS hoặc cơ sở dữ liệu dạng cột. Điều này không có nghĩa đây là các lựa chọn duy nhất. Có rất nhiều lựa chọn khác mà bạn có thể khám phá và sử dụng. Vì vậy, mình nghĩ rằng điều này là đủ tốt cho việc lựa chọn cơ sở dữ liệu phù hợp với tình huống cụ thể.
8. Thông tin kết nối
Nếu anh em muốn trao đổi thêm về bài viết, hãy kết nối với mình qua LinkedIn và Facebook:
- LinkedIn: https://www.linkedin.com/in/nguyentrungnam/
- Facebook: https://www.facebook.com/trungnam.nguyen.395/
Rất mong được kết nối và cùng thảo luận!
All rights reserved