7 điều cần biết về cơ sở dữ liệu
Cơ sở dữ liệu là một phạm trù rộng lớn với vô vàn khái niệm khác nhau mà đôi khi các ứng dụng của chúng ta cần đến các chuyên gia có chuyên môn về lĩnh vực này để có thể phát triển và duy trì. Tuy có vẻ phức tạp nhưng cơ sở dữ liệu không phải một loại hộp đen ma thuật. Hãy tìm hiểu và nắm được cách hoạt động của cơ sở dữ liệu, những kiến thức này sẽ giúp ích cho bạn rất nhiều bởi lẽ cơ sở dữ liệu là xương sống của một ứng dụng. Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về bảy điều nên biết về cơ sở dữ liệu.
Lưu ý: Trong bài viết phần lớn sẽ đề cập đến các cơ sở dữ liệu quan hệ như PostgreSQL hoặc MySQL chứ không phải cơ sở dữ liệu NoSQL.
1. Database Store Transaction
Cơ sở dữ liệu về bản chất kiến trúc của nó không được trực quan cho lắm. Người ta thường nghĩ rằng cơ sở dữ liệu chỉ đơn giản là một hoặc hai tệp dữ liệu và có thêm mấy dòng code để quản lý các kết nối và sửa đổi dữ liệu. Nhìn chung thì nó cũng đúng ở một khía cạnh nào đó. Nhưng thực sự, về cốt lõi, cơ sở dữ liệu chỉ là một tệp nhật ký (logfile) chứa các transaction đã được gửi đến cơ sở dữ liệu và được lưu giữ theo thứ tự mà chúng đã được gửi.
Mọi thứ (trạng thái của bảng, hàng, lược đồ, ...) đều xuất hiện từ những thay đổi tích lũy được ghi lại trên nhật ký này. Mỗi công cụ cơ sở dữ liệu (database Engine) lưu trữ nhật ký này theo một cách khác nhau, nhưng ta có thể giả định trông giống như sau:
Từ nhật ký này, cơ sở dữ liệu có thể xây dựng lại các bảng, cơ sở dữ liệu, lược đồ và mọi thứ khác nếu tệp dữ liệu bị hỏng. Một lưu ý rất quan trọng, sau khi transaction được commit hoặc rollback, nó sẽ bị xóa khỏi nhật ký. Bởi, mục đích của nhật ký là để phân tích sự thay đổi khi một transaction đã hoàn thành.
Trong PostgreSQL và một số cơ sở dữ liệu quan hệ khác, bản ghi này được gọi là Write-Ahead-Log (WAL). Quản lý WAL này cũng như các tính năng của nó là một phần quan trọng trong việc điều chỉnh hiệu suất các cơ sở dữ liệu và quản lý việc nhân rộng. Bất kỳ transaction nào được ghi vào WAL cũng được phát sóng tới các bản sao của nó để có thể thêm transaction vào WAL của mình. Hiểu được cơ chế này chính là chìa khóa để hiểu về cách cơ sở dữ liệu hoạt động và cách khắc phục các sự cố.
2. Làm thế nào để chọn được cơ sở dữ liệu phù hợp?
Mọi người thường nói và đưa ra nhận xét về cơ sở dữ liệu “tốt nhất” hay “tệ nhất”, nhưng điều chúng ta thực sự cần là cơ sở dữ liệu phù hợp và hoạt động tốt với ứng dụng của bạn. chẳng có cơ sở dữ liệu nào là phù hợp với tất cả, cũng giống như không có ngôn ngữ lập trình hoặc hệ điều hành nào là nhất, là phù hợp hơn mọi cái còn lại.
Khi bắt tay vào một dự án mới, việc chọn được cơ sở dữ liệu phù hợp là một trong những quyết định quan trọng nhất. Làm thế nào để chọn? Dưới đây là danh sách năm điều mà chúng ta cần xem xét:
Loại dữ liệu nào sẽ được lưu trữ trong cơ sở dữ liệu?
Bạn đang lưu trữ các tệp nhật ký hay là lưu tài khoản người dùng?
Dữ liệu được lưu trữ phức tạp như thế nào?
Dữ liệu có thể được chuẩn hóa dễ dàng không?
Dữ liệu có thống nhất không?
Dữ liệu của ứng dụng gần như tuân theo cùng một lược đồ hay nó khác biệt hoặc được lồng ghép nhiều?
Tần suất dọc ghi dữ liệu là bao lâu một lần?
Ứng dụng có tần suất đọc hay ghi nhiều, hay cả hai?
Có thêm những cân nhắc về môi trường hoặc kinh doanh không?
Có tồn tại các thỏa thuận gì với các nhà cung cấp không? Có cần hỗ trợ của nhà cung cấp không?
3. Khó khăn khi di chuyển cơ sở dữ liệu
Đôi khi, chúng ta tham gia vào dự án với cơ sở dữ liệu đã được chọn sẵn và việc sử dụng cơ sở dữ liệu không phù hợp này gây ra khó khăn cho công việc.
Cũng không kém cạnh gì so với việc chọn cơ sở dữ liệu phù hợp, việc chuyển cơ sở dữ liệu này sang một cơ sở dữ liệu khác phù hợp hơn cũng gây ra những khó khăn nhất định. Bởi, chúng ta không chỉ phải tìm ra cách sao chép dữ liệu của mình từ cơ sở dữ liệu này sang cơ sở dữ liệu khác mà còn cần tìm hiểu một hệ thống hoàn toàn mới. Tùy thuộc vào mức độ liên kết chặt chẽ của cơ sở dữ liệu với phần còn lại của ứng dụng, chúng ta cũng có thể xem xét một cách toàn diện và đưa ra quyết định viết lại các đoạn code.
4. NoSQL không thay thế SQL
Các tranh luận về sử dụng cơ sở dữ liệu SQL hay NoSQL lúc nào cũng diễn ra. NoSQL thực sự có rất nhiều ưu điểm mạnh mẽ, nhưng thực tế là cơ sở dữ liệu NoSQL chưa thể thay thế cơ sở dữ liệu SQL. Chúng bổ sung cho nhau!
Có một vài thứ cơ sở dữ liệu NoSQL làm rất tốt và cũng có những thứ mà cơ sở dữ liệu SQL là tốt hơn. Prometheus rất tốt trong việc lưu trữ dữ liệu chuỗi thời gian như số liệu, chúng ta chắc sẽ không muốn dùng MySQL cho việc đó. Về mặt kỹ thuật có khả thi không? Chắc chắn là có, nhưng MySQL không được thiết kế cho điều đó và chúng ta sẽ chẳng nhận được hiệu suất và trải nghiệm tốt. Mặt khác, bạn sẽ không muốn sử dụng Redis để lưu trữ dữ liệu có tính liên quan cao như tài khoản người dùng hoặc giao dịch tài chính vì những lý do tương tự. Chắc chắn, bạn có thể làm cho nó hoạt động, nhưng tại sao lại khiến nó trở nên phức tạp khi bạn chỉ thực sự cần thứ phù hợp cho công việc?
5. Mở rộng quy mô
Đây cũng là một thách thức khi sử dụng cơ sở dữ liệu - mở rộng quy mô(scaling). Bởi vì chúng lưu trữ trạng thái của ứng dụng, việc tìm cách sao chép trạng thái theo cách nhất quán, an toàn, đủ nhanh và minh bạch với bất kỳ ứng dụng nào là điều khó khăn. Đây là lý do tại sao cách phổ biến nhất để mở rộng cơ sở dữ liệu, đặc biệt đối với cơ sở dữ liệu quan hệ là mở rộng theo chiều dọc.
Hiểu đơn giản về hai loại mở rộng dọc và ngang chúng ta cũng tim fhieeur qua ví dụ sau. Giả sử, bạn có một bình nước một gallon, nhưng nó có một lỗ nhỏ trên đó, vì vậy bạn cần phải chuyển nước sang thùng chứa khác. Tuy nhiên, tất cả những gì bạn có là những thứ đựng được nhỏ hơn một gallon (đơn vị đo thể tích lớn hơn 1l). Bạn có thể sử dụng hai phương pháp:
Sử dụng nhiều đồ chứa nhỏ hơn (như ly uống nước) và phân phối nước trên nhiều đồ đựng đó.
Sử dụng số lượng ít các thùng chứa một lít và phân phối nước trên số thùng chứa lớn đó.
Sử dụng nhiều đồ chứa nhỏ hơn là mở rộng quy mô theo chiều ngang, trong đó khối lượng công việc (hoặc nước) được trải rộng trên nhiều thùng chứa nhỏ. Sử dụng một vài thùng chứa lớn là mở rộng quy mô theo chiều dọc, trong đó tải trọng được dàn trải trên một số lượng nhỏ các thùng chứa lớn. Với tính năng mở rộng theo chiều ngang, khi cần bổ sung thêm, chúng ta sẽ bổ sung thêm nhiều vùng chứa. Còn với tính năng mở rộng quy mô dọc, bạn tăng lượng lưu trữ trong vùng chứa mà bạn đã có.
Với cơ sở dữ liệu, phương pháp phổ biến là mở rộng cơ sở dữ liệu của bạn theo chiều dọc bằng cách thêm dung lượng CPU và RAM. Điều này tránh được vấn đề phải sao chép trạng thái trong nhiều trường hợp nhưng vẫn cho phép cơ sở dữ liệu của bạn chịu thêm tải.
6. Các chỉ mục thường rất là tuyệt diệu cho đến khi...
Chỉ mục được cho là một trong những khía cạnh quan trọng của cơ sở dữ liệu, nhưng cũng là thứ người ta thường hay bỏ qua nhiều nhất. Nói một cách đơn giản, chỉ mục giống như là một mục lục cho cơ sở dữ liệu khi tra cứu dữ liệu. Thay vì phải quét toàn bộ một cột để tìm kiếm một giá trị, chỉ mục có thể cho biết giá trị đó ở đâu để tìm được ngay lập tức.
Nếu bạn đang đọc nó và tự nhủ: “Cái này nghe có vẻ giống như bảng băm vậy”, thì bạn cũng không sai. Chỉ mục về cơ bản là một loại bảng băm cho một cột nhất định trong bảng. Hầu hết các cơ sở dữ liệu quan hệ đều tự động tạo chỉ mục trên khóa chính, nhưng bạn có thể thêm chỉ mục vào bao nhiêu cột tùy thích.
Nhưng hãy cẩn thận...
Mặc dù các chỉ mục có thể tăng tốc đáng kể thời gian đọc của bạn - đặc biệt là trong các tập dữ liệu lớn - nhưng chúng đi kèm với sự cân bằng khi ghi dữ liệu vào bảng. Mỗi khi bảng được cập nhật, các chỉ mục trên bảng đó cũng cần được cập nhật, điều này làm tăng thêm thời gian cho các thao tác ghi. Bởi vì, chỉ mục không giống như mục lục của một cuốn sách chỉ đơn giản là một danh sách số trỏ tới các trang, một chỉ mục thực sự chứa bản sao của các cột cần thiết vừa được lưu trữ theo một thứ tự khác. Điều này có nghĩa là các chỉ mục sử dụng một lượng không gian đĩa tương ứng và yêu cầu I/O khi được cập nhật. Khi chỉ xử lý một vài chỉ mục trên bảng, sự đánh đổi thường là không đáng kể, nhưng nhiều chỉ mục sẽ khiến cơ sở dữ liệu bắt đầu phải cập nhật tất cả các chỉ mục đó trên mọi transaction.
7. Transaction
Mỗi khi một thứ gì đó tương tác với cơ sở dữ liệu, nó sẽ sử dụng một cấu trúc được gọi là transaction. Trong thế giới cơ sở dữ liệu, transaction là một đơn vị công việc nguyên tử - một hành động độc lập, rời rạc để thực hiện và có một trong hai kết quả: commit hoặc rollback.
Nghe có vẻ không phải là vẫn đề gì quá lơn nhỉ? Nhưng nó thực sự rất ý nghĩa đối với hiệu suất và hoạt động của cơ sở dữ liệu của bạn - đặc biệt là đối với những cơ sở dữ liệu tuân thủ tính ACID. Thứ tự mà các transaction được gửi và lượng dữ liệu được xử lý trong các transaction đó có tác động rất lớn tùy thuộc vào mức cô lập giao dịch được cấu hình trong cơ sở dữ liệu. Một câu chuyện nhỏ về một kinh nghiệm với việc chặn transaction:
“Nhiều năm trước, một thành viên trong nhóm ở Costa Rica đã khó chịu vì 'cơ sở dữ liệu chậm và hết thời gian'. Họ đã thực hiện một truy vấn SELECT * từ một bảng được mọi người sử dụng, vì vậy mỗi khi chạy, cơ sở dữ liệu sẽ khóa toàn bộ bảng được SELECT trong khoảng thời gian cần thiết để gửi tất cả kết quả trở lại Costa Rica vì ngay cả SELECT cũng là một transaction. "
Điều này là do máy chủ cơ sở dữ liệu phải đảm bảo tính nhất quán của dữ liệu khi máy khách nhận lại dữ liệu từ máy chủ, vì vậy không có transaction nào khác có thể được xử lý trong thời gian chạy truy vấn và truyền dữ liệu trở lại máy khách. Với các kết nối chậm, nó có thể gây ra tắc nghẽn lớn cho bất kỳ ai khác sử dụng cơ sở dữ liệu.
Hạn chế này có thể được khắc phục bằng cách điều chỉnh yêu cầu - chỉ tìm nạp dữ liệu khi cần, sử dụng bản sao để đọc, điều chỉnh cài đặt transaction phù hợp với nhu cầu.