PostgreSQL vs MySQL

PostgreSQL vs MySQL
Photo by Janine Bolon from Pixabay

Một mùa nhảy việc nữa lại đến, làm tôi nhớ đến mấy năm về trước bản thân tôi cũng đang đi phỏng vấn khắp nơi. Và trong một lần phỏng vấn rất hãm, tôi có được hỏi câu so sánh này. Câu trả lời của tôi bị đánh giá là chưa hiểu rõ bản chất 💔. Nên hôm nay trong lúc rảnh rỗi, tôi đã tìm hiểu và viết ra bài này, để xem tôi thiếu hiểu biết đến đâu (nhưng xong rồi vẫn chưa biết cần phải hiểu bản chất nào nữa 😆).

Trong số rất nhiều hệ quản trị cơ sở dữ liệu quan hệ (Relational Database Management Systems – RDBMS) hiện nay, PostgreSQL và MySQL là hai trong số những công cụ phổ biến nhất. Chúng có rất nhiều tính năng tốt và cạnh tranh lẫn nhau. Vì vậy, hỏi câu này cũng là bình thường thôi. Câu này để đánh giá kiến thức là chính 😂, những kiến thức này nếu dùng thì hữu dụng nhất là vào lúc bắt đầu dự án mới, khi mà cần phải đưa ra lựa chọn. (Chứ nếu chỉ quan tâm đến code tầng ứng dụng thì hầu như không khác nhau nhiều 😅.)

Nhắc lại những khái niệm cơ bản

Trong bài viết này tôi chỉ tập trung vào hai hệ quản trị cơ sở dữ liệu này. Những khái niệm khác (cơ sở dữ liệu, cơ sở dữ liệu quan hệ là gì, v.v…) xin được bỏ qua. Nếu muốn tìm hiểu những khái niệm cơ bản đó, các bạn hãy tìm đọc các bài viết khác (ở trang khác 😃, chứ tôi chưa viết bài nào như thế đâu 😅).

PostgreSQL là gì?

PostgreSQL được phát triển bởi đại học California (khoa Khoa học máy tính) và công bố lần đầu năm 1996 (tên ban đầu là POSTGRES). Hiện tại, nó tiếp tục được phát triển bởi PostgreSQL Global Development Group. PostgreSQL là một phần mềm mã nguồn mở.

PostgreSQL là một hệ quản trị cơ sở dữ liệu quan hệ (RDBMS) nhưng nó cũng có thể được coi là một hệ quản trị cơ sở dữ liệu hướng đối tượng (Object-Relational Database Management System – ORDBMS) bởi vì nó hỗ trợ nhiều tính năng hướng đối tượng như kế thừa bảng và chồng phương thức.

MySQL là gì?

MySQL là một hệ quản trị cơ sở dữ liệu quan hệ, lần đầu tiên được công bố vào năm 1995, trước PostgreSQL một thời gian ngắn. Nó cũng là một phần mềm mã nguồn mở (dùng giấy phép GNU GPL), được sở hữu và quản lý bởi Oracle. Trong suốt lịch sử của mình, MySQL nổi tiếng về sự ổn định, đáng tin cậy. Nó còn được cộng đồng đánh giá cao vì dễ sử dụng.

RDBMS vs ORDBMS

Trước khi đi vào so sánh chi tiết giữa PostgreSQL và MySQL, tôi muốn nói về sự khác nhau của RDBMS và ORDBMS trước. MySQL là một hệ quản trị cơ sở dữ liệu quan hệ (RDBMS) thuần túy. Bởi vì dữ liệu sẽ được lưu trữ trong các dạng có cấu trúc (với các hàng và cột). Ngoài ra, dữ liệu trong mỗi bảng có quan hệ với nhau, dữ liệu giữa các bảng cũng có quan hệ với nhau (vì thế mới gọi là hệ quản trị cơ sở dữ liệu quan hệ).

PostgreSQL là một hệ quản trị cơ sở dữ liệu hướng đối tượng (ORDBMS). Đương nhiên, nó vẫn là một hệ quản trị cơ sở dữ liệu quan hệ, cho phép làm việc với dữ liệu như những hệ RDBMS khác, trong khi vẫn tuân theo những nguyên tắc của mô hình hướng đối tượng. Do đó, một hệ quản trị ORDBMS có những khái niệm về class, object và kế thừa.

Với một hệ quản trị cơ sở dữ liệu hướng đối tượng, chúng ta có thể thực hiện những thao tác sau (tự định nghĩa kiểu dữ liệu, kế thừa bảng):

CREATE TABLE People (
    Name    PersonName  NOT NULL,
    DOB     DATE        NOT NULL
);
CREATE TABLE Customers (
    Id      Cust_Id     NOT NULL  PRIMARY KEY,
) INHERITS(People);

Ngoài ra, mô hình hướng đối tượng cung cấp nhiều lợi ích về việc liên kết dữ liệu. Trong một hệ quản trị cơ sở dữ liệu, thông thường chúng ta sẽ cần đến JOIN để liên kết nhiều bảng, tuy nhiên, việc đó hoàn toàn được quản lý và thực hiện bởi một hệ quản trị cơ sở dữ liệu hướng đối tượng, nên chúng ta có thể viết những truy vấn rất ngắn gọn và dễ hiểu như sau:

SELECT Formal( C.Name )
FROM Customers C
WHERE C.address.city = "New York" -- Không cần join

Về mặt cấu trúc dữ liệu, MySQL và PostgreSQL rất giống nhau. Cả hai đều sử dụng bảng để lưu trữ dữ liệu, dữ liệu sẽ được tổ chức thành các hàng và cột. PostgreSQL cũng tích hợp sẵn những tính năng như procedure, view, constraint, trigger, role, đồng thời hỗ trợ luôn NoSQL. Về phần mình, MySQL cũng tích hợp những tính năng tương tự (nếu không muốn nói là giống hệt nhau) và kể từ phiên bản 5.7 (công bố năm 2015), MySQL cũng bắt đầu tích hợp thêm các tính năng của NoSQL.

PostgreSQL vs MySQL: công cụ nào phổ biến hơn?

Hai hệ quản trị cơ sở dữ liệu này đều rất phổ biến và được sử dụng rộng rãi hiện nay. Tuy nhiên, để so sánh cụ thể về mặt số liệu, thì theo thống kê của DB-Engines, MySQL hiện được dùng phổ biến hơn PostgreSQL. Ngoài ra, theo thống kê của TOPDB Top Database Index (thống kê dựa trên kết quả tìm kiếm của Google), thì MySQL cũng phổ biến hơn khi xếp thứ 2 còn PostgreSQL chỉ xếp thứ 6.

So sánh chi tiết: PostgreSQL vs MySQL

Cộng đồng phát triển

MySQL có một cộng đồng lớn có thể hỗ trợ mọi lập trình viên. Có thể dễ dàng tìm được các hướng dẫn, lời khuyên hay những điều tương tự trên trang chủ của MySQL hoặc Percona. Ngoài ra, Oracle cũng cung cấp một gói hỗ trợ 24/7 (có trả phí với giá từ $2000-$10000 tùy vào mức độ).

PostgreSQL cũng có một cộng đồng rất đông các nhà phát triển, có thể hỗ trợ mọi lập trình viên thông qua IRC hoặc mailing list. PostgreSQL không có một gói hỗ trợ chính chủ nào cả, thế nhưng vẫn có những gói hỗ trợ được bán bởi một bên thứ ba. Tuy nhiên, việc hỗ trợ của PostgreSQL không thực sự bằng MySQL khi mà người dùng cần có kiến thức nhất định mới có thể lĩnh hội được.

Kiểu dữ liệu

Hiện tại, cả hai hệ quản trị cơ sở dữ liệu này đều cho phép làm việc với dữ liệu kiểu JSON. Tuy nhiên, MySQL đã chậm hơn PostgreSQL khi mà đến tận phiên bản 5.7.8 mới hỗ trợ điều này.

Hỗ trợ dữ liệu JSON cũng là một trong những tính năng quan trọng mà MySQL thêm vào đễ hỗ trợ NoSQL. Ngược lại, PostgreSQL không chỉ hỗ trợ kiểu dữ liệu JSON mà hỗ trợ luôn cả những dạng dữ liệu khác như XML, array, hstore, và người dùng có thể tự định nghĩa kiểu dữ liệu của riêng mình. Điều đó cho phép lập trình viên có thể thao tác với nhiều kiểu dữ liệu hơn khi làm việc với PostgreSQL.

Kiểu dữ liệu phong phú giúp tính năng của PostgreSQL phong phú hơn. Lấy ví dụ đơn giản là kiểu dữ liệu array, đây là một kiểu dữ liệu rất cơ bản, được coi là kiểu dữ liệu nguyên thủy của rất nhiều ngôn ngữ lập trình khác nhau. Nhờ hỗ trợ kiểu dữ liệu này, lập trình viên làm việc với PostgreSQL dễ dàng hơn rất nhiều.

Coding

Khi code với PostgreSQL và MySQL, có nhiều sự khác biệt cần lưu ý.

Đầu tiên, đó là PostgreSQL phân biệt chữ hoa/chữ thường. Điều đó yêu cầu lập trình viên phải viết chính xác câu query của mình, nếu không sẽ không ra được kết quả mong muốn. Ngược lại, MySQL thì không phân biệt như thế, do đó lập trình viên có thể viết query toàn chữ thường (hoặc toàn chữ hoa) mà không vấn đề gì.

Lưu ý rằng, PostgreSQL chỉ phân biệt chữ hoa/thường khi sử dụng cấu quote (dấu nháy, "), còn không thì PostgreSQL sẽ chuyển đổi tất cả chữ hoa thành chữ thường. Điều này có thể là một sự phiền hà nhất định cho một số lập trình viên. Tuy nhiên, tạm thời tôi không đánh giá đây là ưu hay nhược điểm, vì mỗi thứ sẽ thích hợp cho những bài toán cụ thể.

Một điểm khác biệt lớn nữa, đó là một vài phiên bản của MySQL yêu cầu lập trình viên phải chuyển đổi charset và string thành utf-8. Trong khi PostgreSQL không yêu cầu điều đó( Hay nói đúng hơn, PostgreSQL không cho phép sử dụng cú pháp utf-8).

SQL

SQL (Structured Query Language), là ngôn ngữ tiêu chuẩn để truy vấn dữ liệu. Đây là ngôn ngữ đã được tiêu chuẩn hóa bởi ISO/IEC, tuy nhiên, các hệ quản trị cơ sở dữ liệu khác nhau lại có những cú pháp tương đối khác nhau.

Những lệnh cơ bản của SQL như SELECT, INSERT, DELETE, và UPDATE thì hệ quản trị cơ sở dữ liệu nào cũng có. Nhưng mỗi công cụ lại có thêm những tính năng nâng cao hoặc cú pháp khác biệt đôi chút.

MySQL chỉ tương thích một phần với tiêu chuẩn SQL, vì còn rất nhiều tính năng (ví dụ constraint) chưa được hỗ trợ. PostgreSQL thì tương thích hơn (nhưng cũng không phải 100%). Nói một cách chính xác thì PostgreSQL hỗ trợ ít nhất 160 trong tổng số 179 tính năng bắt buộc của SQL.

Index

Dữ liệu càng phức tạp thì index lại càng quan trọng. Khi làm việc với những bảng lớn, hàng triệu bản ghi, thì index có thể là một chìa khóa để tăng hiệu suất làm việc. Trước khi so sánh cụ thể hai hệ quản trị cơ sở dữ liệu, thì trước hết, chúng có nhiều điểm chung: Cả hai đều hỗ trợ index dạng hash và B-tree.

Tuy nhiên, từng hệ quản trị cơ sở dữ liệu lại có những yêu cầu bắt buộc với index khác nhau. Trong MySQL, phần lớn index (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) đều lưu dưới dạng B-tree, trừ một vài ngoại lệ sau:

  • Index của dữ liệu không gian được lưu dưới dạng R-tree
  • Các bảng MEMORY hỗ trợ index dạng hash
  • InnoDB cho phép danh sách đảo ngược với index FULLTEXT

Với PostgreSQL, thì index chỉ là index thứ cấp. Do đó, index sẽ được lưu trữ độc lập, tách biệt khỏi heap của bảng (là nơi lưu trữ dữ liệu của bảng). Một vấn đề của việc này là mỗi khi truy vấn qua index, dữ liệu từ cả index và heap đều phải được nạp thì mới truy vấn được.

Để giải quyết vấn đề này, PostgreSQL hỗ trợ dạng truy vấn chỉ tìm trong index, có nghĩa là lập trình viên chỉ cần tìm trong index là đủ dữ liệu, không cần phải lấy dữ liệu từ bảng. Tuy nhiên, để làm được việc này, thì lập trình viên phải đảm bảo 2 điều: kiểu index phải hỗ trợ truy vấn chỉ từ index, và truy vấn có thể lấy đầy đủ dữ liệu từ index.

Để đảm bảo 2 yêu cầu này, lập trình viên phải lập index cho bảng bằng cách index tất cả các cột cần thiết, gọi là covering index. Index này sẽ chứa tất cả các cột được truy vấn thường xuyên.

Tính năng này mới chỉ xuất hiện trên PostgreSQL từ phiên bản 9.2 (ra mắt năm 2012) trong khi MySQL đã dùng kỹ thuật này từ rất lâu rồi. Tuy nhiên, PostgreSQL lại hỗ trợ nhiều kiểu index mà MySQL không có như index một phần, index kèm tính toán và index bitmap.

ACID

ACID (viết tắt của Atomicity, Consistency, Isolation, và Durability), là một mô tả về những tính chất mà một hệ thống lưu trữ dữ liệu phải có để đảm bảo thống nhất và toàn vẹn dữ liệu.

Hiện nay, phần lớn các hệ quản trị cơ sở dữ liệu quan hệ đều tuân thủ ACID. MySQL vốn ban đầu không tuân thủ theo nguyên tắc này. Tuy nhiên, một số thành phần của MySQL (như InnoDB và NDB engine) đã cho phép lập trình viên tuân theo chuẩn ACID nếu họ muốn.

Ngược lại, PostgreSQL tuân thủ hoàn toàn ACID. Tuy nhiên, việc tuân thủ này dẫn đến hệ quả là hiệu suất của hệ thống sẽ kém hơn. Nguyên nhân là do những nguyên tắc này không hề dễ dàng để đạt được. Nhất là “Isolation”, nghĩa là cô lập.

Để đạt được sự cô lập đúng nghĩa, lập trình viên phải đảm bảo các transaction (giao dịch) phải được tuần tự hóa. Nghĩa là kết quả của một loạt các transaction phải tương đương với việc thực hiện tuần tự các transaction đó. Một hệ quản trị cơ sở dữ liệu cho phép tuần tự hóa các thao tác đọc/ghi có thể đảm bảo dữ liệu nhất quán.

Tuy nhiên, dù tuân thủ ACID sẽ giúp đảm bảo sự nhất quán và toàn vẹn của dữ liệu (một điểm cộng lớn của PostgreSQL), việc đảm bảo ACID tuyệt đối sẽ hạn chế khả năng chạy song song bị hạn chế, do đó sẽ làm giảm hiệu suất của hệ thống (điểm trừ của PostgreSQL).

Tuy nhiên, cũng cần phải nói rõ rằng, việc so sánh hiệu suất ở đây là so với chính nó (nếu PostgreSQL không tuân thủ ACID thì hiệu suất sẽ tốt hơn rất nhiều), còn việc so sánh hai hệ quản trị cơ sở dữ liệu thì rất khó, vì còn rất nhiều yếu tố khác ảnh hưởng đến hiệu suất chung của toàn bộ hệ thống.

MVCC

MVCC (multi-version concurrency control) là tính năng quản lý các truy cập song song vào cơ sở dữ liệu. PostgreSQL đã đưa ra tính năng này sớm hơn rất nhiều so với MySQL, và nó được coi là một trong những ưu điểm vượt trội của PostgreSQL.

MVCC cho phép lập trình viên xây dựng các ứng dụng truy cập song song vào cơ sở dữ liệu mà không cần phải khóa bảng. Mọi truy cập đến cơ sở dữ liệu sẽ đều nhận được một bản snapshot của dữ liệu khi truy vấn. Và trước khi một transaction hoàn tất, thì không truy vấn nào có thể nhìn thấy sự thay đổi đó.

Điều đó có nghĩa là các thao tác đọc/ghi không bị ảnh hưởng lẫn nhau và MVCC sẽ giúp các thao tác song song tương tác dễ dàng hơn. Tính năng này cũng giúp cô lập các transaction bởi các kết nối khác nhau đến cơ sở dữ liệu. Điều đó giúp các transaction không bị xung đột lẫn nhau mà vẫn đảm bảo tính nhất quán của dữ liệu.

Với MySQL, để sử dụng MVCC, bắt buộc phải dùng InnoDB engine. Đây là engine của MySQL tuân thủ theo nguyên tắc ACID và có tính năng MVCC. Tất nhiên lập trình viên có thể lựa chọn engine khác, nhưng sẽ mất đi hai tính năng quan trọng này.

Tốc độ

Có thể dễ dàng tìm được các bài test tốc độ của hai công cụ này trên Internet. Các bài test, tùy thuộc vào phần cứng, thiết lập, v.v.. mà cho ra kết quả rất khác nhau, lúc thì MySQL hơn, lúc thì PostgreSQL hơn.

Tuy nhiên, nhận xét về tổng thể, PostgreSQL tốt hơn khi làm việc với lượng dữ liệu lớn, truy vấn phức tạp và các thao tác đọc/ghi hỗn hợp. Ngược lại thì MySQL có tốc độ tốt hơn với những thao tác nặng về đọc dữ liệu.

Replication, Clustering

Replication (nghĩa là bản sao, sao chép) là một công việc cho phép sao chép dữ liệu từ cơ sở dữ liệu này sang một cơ sở dữ liệu khác (gọi là replica). Điều này cho phép tạo ra nhiều cơ sở dữ liệu có cùng thông tin như nhau. Thao tác này mang lại nhiều lợi ích như backup tự động, khả năng chịu lỗi, mở rộng và giảm tải cho các truy vấn phức tạp.

Cả PostgreSQL mà MySQL đều hỗ trợ replication. Trong MySQL, replication là thao tác một chiều và bất đồng bộ. Theo đó, MySQL hoạt động theo mô hình master/slave, một server sẽ đóng vai trò là master và sẽ được sao chép dữ liệu bất đồng bộ sang các server khác.

Ngược lại, PostgreSQL là sao chép đồng bộ, nghĩa là sẽ có nhiều máy chủ chạy song song, và cơ sở dữ liệu chính (primary) sẽ được đồng bộ với các máy chủ khác (replica).

Một tính năng khác nữa mà cả PostgreSQL và MySQL đều hỗ trợ là clustering. Clustering là cơ chế sử dụng bộ nhớ chung để chia sẻ dữ liệu giữa các node trong cùng một môi trường. Điều này cho phép cơ sở dữ liệu chịu được lỗi (hay nói cách khác là vẫn tiếp tục hoạt động nếu server có lỗi), do dữ liệu dự phòng đã được tạo ra bằng cách sao chép cho mọi node.

Mặc dù sử dụng cơ chế replication bất đồng bộ, MySQL cluster vẫn cho phép sao chép đồng bộ. Điều này khiến MySQL không bị tắc cổ chai tại một điểm nào của hệ thống, đồng thời đảm bảo được dữ liệu được ghi ra nhiều node khác nhau. Hơn nữa, lập trình viên có thể sử dụng tính năng clustering của MySQL để scale hệ thống theo chiều ngang.

Về tính năng clustering, PostgreSQL hỗ trợ streaming và replication đồng bộ, đồng thời nó cũng có Postgres-XL, là một môi trường cơ sở dữ liệu được clustering.

PostgreSQL vs MySQL: Nên chọn công cụ nào?

Sau tất cả những so sánh ở trên, thì mọi chuyện đều dẫn tới câu hỏi quan trọng nhất: Dùng công cụ nào thì tốt hơn? Cũng như mọi công cụ tồn tại song song khác, câu trả lời cho câu hỏi này cũng không hề đơn giản. Tuy nhiên, riêng với trường hợp hai hệ quản trị cơ sở dữ liệu này, việc lựa chọn một trong hai đều ổn.

Cả hai đều là những hệ quản trị cơ sở dữ liệu được sử dụng rộng rãi với uy tín rất cao. Trong một vài trường hợp cụ thể, có thể MySQL sẽ tốt hơn PostgreSQL và ngược lại. Tuy nhiên, sự chênh lệch không quá lớn tới mức chọn công cụ này là đúng còn công cụ kia là sai.

Như đã so sánh nhiều tiêu chí ở trên, MySQL là một hệ quản trị cơ sở dữ liệu quan hệ, còn PostgreSQL là hệ quản trị cơ sở dữ liệu hướng đối tượng (có nhiều tính năng hướng đối tượng như kế thừa bảng, chồng phương thức, v.v…). Sự khác biệt này có thể khiến nhiều người lựa chọn PostgreSQL bởi sự tiện lợi khi phải sử dụng các cấu trúc dữ liệu phức tạp.

Hơn nữa, PostgreSQL tuân thủ chuẩn SQL tốt hơn MySQL và cũng đảm bảo sự nhất quán của dữ liệu tốt hơn (do tuân thủ nguyên tắc ACID). Về phần mình, MySQL cũng có thể tuân thủ nguyên tắc ACID nếu sử dụng InnoDB engine và NDB cluster. Nhờ vào việc không bắt buộc tuân thủ ACID, MySQL có tốc độ tốt hơn khi đọc dữ liệu.

Ngoài ra, việc lựa chọn MySQL cũng mang lại nhiều lợi ích. Trước hết, nó có cộng đồng hỗ trợ tốt hơn PostgreSQL, đồng thời có rất nhiều công cụ được phát triển bởi bên thứ ba. Một ưu điểm nữa là, MySQL là một công cụ có quen thuộc với nhiều người, hiệu suất tốt, đáng tin cậy và không phức tạp, rất dễ hiểu và dễ làm việc. Những năm gần đây, MySQL cũng liên tục đưa thêm các tính năng quan trọng (ví dụ MVCC).

PostgreSQL là một hệ quản trị cơ sở dữ liệu có nhiều tính năng tích hợp sẵn hơn, và nó đã được chứng minh trên thực tế là có thể xử lý truy vấn phức tạp tốt hơn (sub-query, filter, join, v.v…) cũng như khi làm việc với một lượng lớn dữ liệu. Tuy nhiên, nếu bạn cần một hệ quản trị cơ sở dữ liệu nhanh, đáng tin và dễ sử dụng thì MySQL có vẻ là lựa chọn tốt hơn. Nhưng nếu bạn cần làm việc với dữ liệu có cấu trúc phức tạp thì PostgreSQL là lựa chọn tốt.

Cuối cùng, việc lựa chọn giữa PostgreSQL và MySQL luôn luôn phụ thuộc vào từng bài toán cụ thể, nhu cầu của người sử dụng và kỹ năng cá nhân (khi sự chênh lệch không quá lớn, công cụ mà bạn thành thạo nhất luôn là công cụ tốt nhất ☺️).

Kết luận

Việc so sánh hai hệ quản trị cơ sở dữ liệu để giúp chúng ta hiểu hơn về từng công cụ. Nó không thể trả lời câu hỏi cái nào tốt hơn cái nào. Nhưng hiểu hơn về sự khác biệt có thể giúp chúng ta lựa chọn công cụ phù hợp hơn với nhu cầu của mình. Hay nói đơn giản, đặc trưng của hệ quản trị cơ sở dữ liệu nên khớp với yêu cầu của hệ thống.

Tôi xin lỗi nếu bài viết có bất kỳ typo nào. Nếu bạn nhận thấy điều gì bất thường, xin hãy cho tôi biết.

Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.